OmniAICreator/Qiita-1.07M huggingface dataset:
Androidのビュー部品(2)Textパレット

# はじめに

Androidアプリの開発のために、パレットとビュー部品についての理解を整理します。
この記事で取り扱う環境は、Android Studio＋Windows10です。

:::note info
真新しい情報ではありません。体系立てて理解を整理するために、自分が理解しやすい枠組みでまとめるものです。
:::

## ひとつ前

https://qiita.com/w2mjra555/items/0e5bb3997bc1989a5ef5

## ひとつ先
https://qiita.com/w2mjra555/items/e87d10a64d2e32347aa2

## 1.レイアウトファイル(activity_main.xml)

デザインビューで見るとこんなかんじです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515319/60db1f75-f50e-6f5d-cd56-4ca234735668.png)

## 1.パレットとビュー部品

| No | パレット || No | パレット || No | パレット |
|-----------:|:-----------|:-----------|-----------:|:-----------|:-----------|-----------:|:-----------|
| 1 | Common || 4 | Widgets || 7 | Helper |
| 2 | Text || 5 | Layouts || 8 | Google |
| 3 | Buttons || 6 | Containers || 9 | Legacy |

### 1.2.Textパレット
テキスト入力系のビュー部品が定義されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515319/9be5e9ab-ef8f-c48c-b8b0-1c10b7bf2c2d.png)

| No | ビュー部品 | 説明 |
|-----------:|:-----------|:------------|
| 1 | TextView | テキストを表示 |
| 2 | Plain Text | プレーンテキスト入力 |
| 3 | Password | パスワード入力 |
| 4 | Password(Numeric) | パスワード(数値)入力 |
| 5 | E-mail | メールアドレス入力 |
| 6 | Phone | 電話番号入力 |
| 7 | Postal Address | 住所入力 |
| 8 | Multiline Text | 複数行テキストを入力 |
| 9 | Time | 時刻入力 |
| 10 | Date | 日付入力 |
| 11 | Number | 数字入力 |
| 12 | Number(Signed) | 符号付き数字入力 |
| 13 | Number(Decimal) | 小数入力 |
| 14 | AutoComplete TextView | 入力候補を提供する |
| 15 | MultiAutoComplete TextView | 入力候補を連続して提供する |
| 16 | CheckedTextView | チェックボックス付きテキスト |
| 17 | TextInputLayout | マテリアルデザイン |
Nuxt3 + Vuetify3の開発環境構築 (2022年5月時点の最新版)

Nuxt3がまだ不安定な状況で、執筆時点で公開されていた日本語記事通りに書いても正常に動作しなかったので、[公式のDiscussion](https://github.com/nuxt/framework/discussions/1183)に載っていた情報を元に構築しました。

## 動作環境
Node.js v14 or v16 (v14.16.0での動作を確認済)
Nuxt 3.0.0-rc.1
Vuetify 3.0.0-beta.1

## 手順

まずNuxt3のプロジェクトを作ります。

```
npx nuxi init nuxt-app
```

`nuxi` がインストールされていない場合はインストールするか尋ねられるので、インストールしてください。
プロジェクトのディレクトリに移動し、必要なパッケージをインストールします。

```
yarn install
```

Vuetifyにsassが必要になるので追加します

```
yarn add vuetify@next sass
```

`plugins` フォルダを作ってその中に `Vuetify.ts` を以下のように作成します

```plugins/vuetify.ts
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'

export default defineNuxtPlugin(nuxtApp => {
  const vuetify = createVuetify({
    components,
    directives,
  })

  nuxtApp.vueApp.use(vuetify)
})
```

`nuxt.config.ts` を以下のように修正します

```nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  css: ['vuetify/lib/styles/main.sass'],
  build: {
    transpile: ['vuetify'],
  },
  vite: {
    define: {
      'process.env.DEBUG': false,
    },
  },
})
```

動作確認のために `app.vue` を修正します

```app.vue
<template>
  <div>
    <v-btn>test</v-btn>
  </div>
</template>
```

アプリケーションを起動します

```
yarn dev
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265114/e2cdb7e0-5170-f3e5-a069-d7a74d836ee6.png)
このようにボタンが表示されていたら動作確認OKです。

## おまけ (マテリアルデザインアイコンを使いたい場合)

こちらも同じDiscussionに載っていたのでおまけで記載します。

まずパッケージを追加します。

```
yarn add mdi
```

`nuxt.config.ts` に追記します

```uxt.config.ts
import { defineNuxtConfig } from 'nuxt'

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  css: [
    'vuetify/lib/styles/main.sass',
    'mdi/css/materialdesignicons.min.css', // 追記
  ],
  build: {
    transpile: ['vuetify'],
  },
  vite: {
    define: {
      'process.env.DEBUG': false,
    },
  },
})
```

`app.vue` を修正します

```app.vue
<template>
  <div>
    <v-btn><v-icon>mdi-information</v-icon>button</v-btn>
  </div>
</template>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265114/4a430168-1a30-3283-ce66-4d30ad56e865.png)
アイコンが表示されていたらOKです。

## 参考

https://github.com/nuxt/framework/discussions/1183
FortigateVM を ESXi にインストールできない(サポートされていないハードウェア ファミリ「vmx-17」です。)

FortigateVMをESXiにOVFデプロイする際に、以下アラートで失敗した場合の対応です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/83eb61ad-1b7d-e9a3-c995-911df0faa807.png)

```
行 70:サポートされていないハードウェア ファミリ「vmx-17」です。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/56e924c4-0f5a-eb2d-3691-83c3f9d98fe8.png)

```
仮想マシンのデプロイに失敗しました:[missing message value]
```



環境：
vmware ESXi 6.7.0 Update 3 (Build 14320388)
FortiGate for VMware FGT_VM64-v7.0.5-build0304
→FortiGate-VM64.vapp.ovf




# 解決策
readme(FortigateVMダウンロードファイル内)にある通り、ESXi/vCenterに対し適切なFortiGate-VM64-<b>xxx</b>.ovfファイルを選択してください。

```
Compatibilities of different OVF templates:

|-----------------------------------------+-------------------------------------------|
|               Template                  |               Compatible with             |
|-----------------------------------------+-------------------------------------------|
| FortiGate-VM64.ovf                      | ESXI 7.0(Hardware Version 17) or later    |
|-----------------------------------------+-------------------------------------------|
| FortiGate-VM64.hw13.ovf                 | ESXI 6.5(Hardware Version 13) or later    |
|-----------------------------------------+-------------------------------------------|
| FortiGate-VM64.hw15.ovf                 | ESXI 6.7U2+(Hardware Version 15) or later |
|-----------------------------------------+-------------------------------------------|
| FortiGate-VM64.vapp.ovf                 | ESXI 7.0(Hardware Version 17) or later    |
|-----------------------------------------+-------------------------------------------|
| FortiGate-VM64.nsxt.ovf                 | ESXI 6.7U2+(Hardware Version 15) or later |
|-----------------------------------------+-------------------------------------------|
```




# 説明
ESXi/vCenterのバージョンごとに、サポートされる仮想マシンバージョンが異なります。
古いESXi/vCenterに、比較的新しいOVFファイル(仮想マシンファイルフォーマットファイル)を
適用しようとした際などに本エラーが出るものと推察されます。

今回はESXi6.7u3(仮想マシンバージョン<=15)に、仮想マシンバージョン17を適用したため
エラーとなり仮想マシンがデプロイされなかった、ということになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/6545a785-c761-35ab-9448-f65ca318d63a.png)


https://kb.vmware.com/s/article/1003746?lang=ja






# 参考
https://qiita.com/Higemal/items/44f3c419872a171ecc9b
チーム運営の苦手な私が、初心者でも簡単Glideアプリでタスク管理

## Glideでイベントタスクアプリを開発

https://twitter.com/satsuki_nozomii/status/1522181843059376129


## 開発の背景
私は業務上、**小中学生向けの学習型イベント**を企画運営するチームリーダーの役割も担っています。
昨年まではコロナ禍でイベントを催すことが難しかったのですが、本年から**本格的にイベントを開催していく**ことになりました。

運営メンバーは私を含め3名。
昨年までの活動はほとんど私一人で企画し運営していましたが他の業務も抱えながらの**一人イベント運営は実際大変な**ものがありました。
なので、今年からはチーム全体で運営をして~~自分が楽をしたい~~業務効率を上げたい！と強く感じ、タスク管理アプリを**初心者ながら作ってみることにしました。**

## 開発の参考にしたい動画を見つける
アプリ開発に使ったのは**ノーコード初心者におすすめ**と名高い[Glide](https://www.glideapps.com/)です。
初心者向け解説ブログや動画がたくさん出ていますが、私が参考にしたのはこちら。

https://www.youtube.com/watch?v=MHsW9Os-GrQ

「15分で」という触れ込みにときめきましたが、**超初心者の私は完成まで実際３時間程度**かかりました。

## スプレッドシートの作り方がキモ
Glideの良さは、**Googleスプレッドシートから自動で簡単にアプリが生成**される点です。

タスク管理で、業務担当者が一目でわかるようにしたかったので**Choiceというコンポーネント**を挿入しました。

業務の責任の所在をはっきりさせておかないと、昨年までのように**リーダーだけが業務を背負うことになってしいまいがち**なので、ここで**担当者をはっきりさせておきたかった**為、この機能を付けました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/928add33-0c65-f354-4709-97ad75ed5784.png)

Choiceコンポーネントの中身は、**スプレッドシートの別タブで入力**しておくと選択できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/7c764279-e0f9-5910-016a-4a86b9af2153.png)

## 欲しい機能を実装できる喜びと楽しさ
コンポーネント挿入の楽しさを覚えた私は、タブを追加し欲しい機能を追加しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/78ba4e3c-ca00-86df-8ff9-06a958623b17.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/837a8bdd-67d2-0a9d-d6de-88485c5dd98b.png)



**業務の完了・未完了もSwitch**というコンポーネントで表現。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/0e4956e8-04e2-07be-1bd2-b2de82272a56.png)

他にも**持ち物をメモ編集できる**ようにしたり、**保護者連絡先から電話がかけられる**ようにしたり、様々な機能を盛り込みました。

## 運営メンバーに実際触ってもらった感想
プロトタイプですが、メンバーにアプリを触ってもらい感想を頂きました。

「メンバー管理ができるのはありがたいです」
→これまで年間を通しての個人別参加表を紙ベースで管理していたので、**一目でいつでも確認**できるようになり良かったです。

「メンバーの連絡先に直接連絡できるのはいいですね」
→イベント中、ケガやとっさのことで**保護者様に連絡を取らなくてはならない際、非常に役に立つ**機能です。安心してイベント開催できます。

「Tシャツのサイズも地味に必要ですね」
→メンバー達の持っているチームTシャツは成長によりサイズ交換することがありますが、**サイズが管理できていなかったので在庫欠品しているサイズもありました**。Tシャツの発注が1年に一度しか行えないので、発注の際に非常に役立つ機能です。

「実際に導入しましょう！」
→作ってみて本当に良かったと思えた瞬間でした。

## こちらのアプリを利用するには
https://tall-trouble-3662.glideapp.io/

![アプリのQRコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2619726/54805215-8cac-3184-9c01-6336539b0351.png)

さつき
https://twitter.com/satsuki_nozomii
Wordpress管理画面が真っ白に…

WordpressでHPやLPを制作し、本番環境にアップロードしたけど、いざ管理画面に入ると画面が真っ白に...

なんで！？と思って原因を探ると、「functions.php」に諸悪の根源がありました。

最後の行が

```
?>


```

となっていたのを
```
?>
```
と直します。

なにが変わったん？

と思うかもしれませんが、実は、改行がなくなっているのです。

閉じタグ後の改行ひとつで管理画面が真っ白になる原因になるらしく、この点を修正したら、自分も見事に管理画面が表示されました。

そもそも、HTMLに埋め込むタイプのPHPファイル以外は閉じタグをつけないということがデフォルトらしく、自分自身新たな学びとなりました。

他にも、Wordpress関連のエラー要因はたくさんあると思いますが、同じ原因で動かないという人がもしいらっしゃれば、この点も確認してみてください。
Doma2でMergeを利用する

Doma2でMergeを利用することがあったので、メモとして残しておきます。

といってもそれほど難しいことはなく、まずはDaoインタフェースを用意します。

```java
@Dao
@ConfigAutowireable
public interface InventoryDao {
	/**
	 * 入荷予定をもとに在庫数を更新する。入荷予定に対する現在在庫が存在しない場合は、在庫データを作成する。
	 * @param dt 入荷予定日
	 * @return 挿入・更新件数
	 */
	@Update(sqlFile = true)
    int mergeInventoryUsingReceipt(LocalDate dt);
}

```

ここで注意するのは、`@Update`アノテーションを付与すること、戻り値を`int`にすることです。この戻り値は更新・挿入・削除した件数になります。

あとはこのDaoインターフェースに対応するMerge文を用意すればよいです。

```SQL
MERGE inventory AS I
USING (
  SELECT *
  FROM receipt
  WHERE dt = /* dt */'2022-04-23'
) R
ON I.item = R.item
WHEN MATCHED THEN UPDATE SET I.qty = I.qty + R.qty
WHEN NOT MATCHED THEN INSERT (item, qty) VALUES (R.item, R.qty);
```

**稼働確認環境(`pom.xml`抜粋)**

```xml
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.6.7</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
  <java.version>8</java.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
  </dependency>
  <dependency>
    <groupId>org.seasar.doma.boot</groupId>
    <artifactId>doma-spring-boot-starter</artifactId>
    <version>1.6.0</version>
  </dependency>
  <dependency>
    <groupId>org.seasar.doma</groupId>
    <artifactId>doma-processor</artifactId>
    <version>2.50.0</version>
    <optional>true</optional>
  </dependency>
  <dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <scope>runtime</scope>
  </dependency>
</dependencies>
```
[Python] pptx2md パワーポイントの資料をマークダウンに変換する。

# はじめに

ゴールデンウィークの勉強会で登壇する際に作成したパワーポイントを、Qiitaに投稿できるようにMarkdownに変換したくて調べてみました。

# pptx2md

使用したライブラリはこちらです。作者のGithubリポジトリはこちら。

https://github.com/ssine/pptx2md

# Google Colab

Google Colabで使ってみています。GoogleColabについてはたくさん記事があるので調べてみてください。

https://blog.kikagaku.co.jp/google-colab-howto

# pptx2mdの使い方

GoogleColabの初期環境には入っていないので、まずはライブラリのインストールから始めます。

```python
# ライブラリのインストール
!pip install pptx2md
```

Google Driveへマウントします。これは頻出記述なので覚えておくとよいですね。

```python
# GoogleDrive のマウント
from google.colab import drive
drive.mount('/content/drive/')
```

`PPTX`拡張子のパワーポイントファイルを任意のフォルダに入れ、そのフォルダに移動します。
今回は`Mydrive > PPTX`にいれておきました。`PPT`拡張子には非対応とのこと。

```python
# PPTXファイルを入れているフォルダに移動。一応リスト表示。
%cd  /content/drive/MyDrive/PPTX
%ls
```

正しくリスト表示がされたのを確認したら、あとはファイル名を指定して実行するだけです。

```python
# 実行
!pptx2md 2022GW夜のPowerBI勉強会第弐夜データモデル.pptx
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/b613f367-186f-9c14-fdfb-180ae58ef3e8.png)

`out.md`という名前でマークダウンファイルが出力されます。`img`フォルダに画像ファイルが格納されており、マークダウンファイルからは`img`タグを使用してリンクされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/88140cf6-8c35-63c4-6a49-01b11968e96d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/a6e2fe2f-df2f-1972-1121-4f2555fff69d.png)


# まとめ

最終的にこのツールを使用してMarkdownをつくることを意識してパワーポイントファイルを作成すれば、PPTX↔MDのいききはかなりスムーズになるのではと感じました。

MarkdownからPPTXやPDFを作成するツールもたくさんある（例:Marp）ので、どちらから作り始めるかは状況に応じて選択できる世界が生きやすいですよね。
CUDA開発環境まとめ (忘備録)

CUDA開発環境について試したものをまとめる。CUDA開発環境(CUDA Toolkit)はLinux, Windowsのマルチプラットフォームに対応しており、ユーザーが好きな環境を選ぶことができる。

## 1. ネイティブLinux
Linux専用マシンを用意できればの話ではあるが、物理マシンにLinuxを直接インストールしてある環境を整えるのが一番シンプルで楽である。(結論)
GPU実行、デバッグ、プロファイルやりたいこと全てができる。

## 2. VirtualBox + Linux
筆者はWindows PCしか持っていないかつ、Linux環境でCUDAプログラムを作成したいため、VirtualなLinuxを使えないか試みた。
VirtualBox + Linuxはできなくはないが、環境構築のハードルが高く断念した。
通常、仮想環境からだとホストPCのGPUを見ることができず、PCIパススルーという手段を講じなければならない。
PCIパススルーをするとホストはGPUを利用できなくなるため、グラボが複数ないとホストの画面出力等ができなくなってしまうらしい。。

サルでもできるGPUパススルー
https://zenn.dev/190ikp/articles/vagrant_libvirt_gpu

## 3. WSL
WindowsにGPUドライバー、WSLにCUDA ToolkitをインストールすればWSL内部でGPU実行ができる！
とぬか喜びしたが、デバッガーやプロファイラはサポート外のようで動作しない(2022/05/06現在)。
CUDA実行するだけで良いならWSLは簡単でおすすめ。

## 4. Windows
Windows環境での開発はあまり経験がないためこれから勉強予定。
Visual StudioやVScodeにCUDA用プラグインが用意されている。
GPU実行、デバッガー、プロファイラはすべて動くはず。

|       環境名       | 開発ベース環境 | GPU実行 | デバッガ | プロファイラ |        備考        |
| :----------------- | :------------: | :-----: | :------: | :----------: | :----------------- |
| ネイティブLinux    |     Linux      |    ○    |    ○     |      ○       |                    |
| VirtualBox + Linux |     Linux      |    ○    |    ○     |      ○       | 環境構築の難易度高 |
| WSL                |     Linux      |    ○    |    -     |      -       | Tool利用不可       |
| Windows            |    Windows     |    ○    |    ○     |      ○       |                    |

結局、物理マシンに直接乗ってるOSで開発するのが手っ取り早いのか(?)
Power Query workout - List.AllTrue / List.AnyTrue / List.Contains / List.ContainsAll / List.ContainsAny

先行評価(eager evaluation)と短絡評価(short-circuit evaluation)に使いたいので。短絡評価 であれば *if - then - else -* を代替できる。

# 確認方法
```text:Power&#x20;Query
// fxTrace
(message as text, value as function) as any =>
    Diagnostics.Trace(
        TraceLevel.Information, message, value, true
    )
```
```text:Power&#x20;Query
// SourceList
{
    fxTrace("#1 - false", ()=> 1 = 0),
    fxTrace("#2 - true",  ()=> 1 > 0),
    fxTrace("#3 - false", ()=> 0 = 1)
}
```
# 評価結果
## すべての *list* アイテムを評価する
List.AllTrue は妥当だが List.AnyTrue が意外に感じる。先行評価(eager evaluation)用途の関数なのだろう。
### List.AllTrue
https://docs.microsoft.com/en-us/powerquery-m/list-alltrue
```text:Power&#x20;Query
// AllTrue
List.AllTrue(SourceList)
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
|#3 - false|
### List.AnyTrue
https://docs.microsoft.com/en-us/powerquery-m/list-anytrue
```text:Power&#x20;Query
List.AnyTrue(SourceList)
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
|#3 - false|
## 可能な限りすべての *list* アイテムを評価しない
短絡評価(short-circuit evaluation)を期待する使用をしたい。
### List.Contains
https://docs.microsoft.com/en-us/powerquery-m/list-contains
```text:Power&#x20;Query
List.Contains(SourceList, true)
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
### List.ContainsAll
https://docs.microsoft.com/en-us/powerquery-m/list-containsall
```text:Power&#x20;Query
List.ContainsAll(SourceList, {true})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
```text:Power&#x20;Query
List.ContainsAll(SourceList, {true, 0})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
|#3 - false|
```text:Power&#x20;Query
List.ContainsAll(SourceList, {true, false})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|
### List.ContainsAny
https://docs.microsoft.com/en-us/powerquery-m/list-containsany
```text:Power&#x20;Query
List.ContainsAny(SourceList, {true})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|

```text:Power&#x20;Query
List.ContainsAny(SourceList, {true, false})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|

```text:Power&#x20;Query
List.ContainsAny(SourceList, {true, 0})
```
|Message|
|:--:|
|#1 - false|
|#2 - true|


# その他
https://powerbi.connpass.com/

- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
ガチャで使う乱数を考えてみる

前回の投稿「[Javaの乱数生成器について速度面から調査してみる](https://qiita.com/penguinsan/items/52a7b76e5570f7cf7e15)」でそれほど長周期が必要ないならThreadLocalRandom（SplitMix64）でいいかな、なんて書いたものの、そもそも「長周期が必要ない」もしくは「長周期が必要」ってどういうとき？ってなったのでガチャを例に考察してみます。

# 周期とは
ThreadLocalRandomに使われているSplitMix64などの疑似乱数には内部状態があり乱数を生成するごとに内部状態を更新していきます。
同じ内部状態から生成される乱数は同じになるので、内部状態が1周して同じ値に戻ってくるとそれ以降はまた同じ乱数の系列が出力されることになります。これが周期です。
ちなみにThreadLocalRandomの周期と内部状態は[Java17のAPIドキュメント](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/random/package-summary.html#algorithms)によると
周期(Period)：$ 2^{64} $
内部状態(StateBits)：64bit
であることがわかります。

# ガチャに必要な情報量
ガチャは抽選方法によっていろいろ作りが違うので、ここでは簡単に計算できるように最小確率のアイテムが0.1%だとして、出現確立を1000分率で設定することとします。（全排出アイテムの総和が1000となるように設定されている状態）
この状態は0から999の1000個の数字がそれぞれ出現アイテムに紐づいていると考えられます。
例えば0.1%のものなら一つの数字に紐づけ、10％のものなら100個の数字に紐づけます。（総和が1000なのですべてのアイテムは少なくとも1つ以上の数字と紐づいた状態になっています）

1連ガチャであれば1000個の数字がまんべんなく出てくれれば、想定通りの確率で排出されそうです。
1000をビット数であらわすと$ log_2{1000} \fallingdotseq 9.97 $なので内部状態が64ビットあるThreadLocalRandomでも大丈夫そうです。
では10連ガチャの場合どうでしょう。10連なので情報量は10倍で $ 9.97 \times 10 = 99.7 $ ほぼ100ビット必要ということになります。（ここでは最終的に排出されるアイテムの組み合わせではなく、すべてのパターンが出現する可能性があるかで考えています）
これではThreadLocalRandomでは1周してもすべてのパターンを網羅することはできません。（つまり結果が偏る可能性がある）

# まとめ
単発でしか利用されない抽選であれば通常の疑似乱数でも十分と言えそうですが、
簡略化したガチャのモデルでも10連となるとThreadLocalRandomの$2^{64}$周期では足りないことがわかりました。
実際のガチャでは小数点第5位ぐらいまで表記してあるものもあり、その場合前述のアルゴリズムだと1000万分率で設定することになるので情報量は増えます。（10連で約232bit）
結局運営によってどう設定されるかわからないガチャの設定に対して正しく輩出させるにはCSPRNG(暗号論的疑似乱数。JavaならばSecureRandom)を使っておくのが安心な気がしてきました。速度の面はガチャに限って言えば排出アイテムをデータベースに書き込む処理時間が支配的になることが多いので、速いに越したことはないにせよ問題になることは少ないと思います。

PRNGの話してたのに結局CSPRNGに行きついてしまって微妙ですが、ガチャ排出確立問題は非常にシビアなので・・・

# おまけ
この記事ではガチャでの話になっていますがランダム文字列の生成でも同じようなことが言えます。
大小英字＋数字の62種類の文字からなる30文字のランダム文字列を作ることを考えると
$log_2{62} \fallingdotseq 5.95(bit)$
$5.95 \times 30 = 178.5 (bit)$
となるのでそれなりに周期の長い乱数でないとまずそうです。
ただ、この手の文字列は一時キーに使ったりするシチュエーションが多いと思うので、セキュリティを考えるとそもそもCSPRNGで生成すべきと言えるでしょう。
モデルベース開発入門_モデルベース開発工程

# はじめに
[前回(そもそもモデルベース開発とは)](https://qiita.com/LetsMBD/items/a217444a89696c4bfc61)に引き続き
入門者(新入社員や転職者)向けモデルベース開発解説記事第二弾です。

第二弾は**モデルベース開発工程**についてです。
どのような手順で開発を進めていくのかを解説します。

モデルベース開発を中心に組み込み系の情報をまとめたホームページを作成中です。よければ覗いてみてください。
[モデルベース開発入門](http://lets-mbd.com/)

# 工程全体
下図は組み込みソフトウェア開発でよく用いられるV字プロセスといわれる開発工程です。
モデルベース開発でも従来開発でもこのプロセス自体は同じです。
**モデルをベース**にしながら**V字プロセスを効率よく進めていく**方法がモデルベース開発となります。
各工程について解説します。
![MBD工程図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2643741/a14bf0e5-7b82-56ed-687b-e615d138b424.jpeg)

## 要件定義
開発対象がどんなシステムなのか、どんな機能・性能を持たせるのかを定義する工程です。この工程で定義した全ての要件を満たすソフトが完成すると開発プロジェクトが完了となります。

注意点
後々言った言ってない問題に発展しないように要件定義結果は関連部署(委託元と委託先だったり、同じ会社でも自部署と他部署だったり)と合意を取り、証拠を残しましょう(議事録や打ち合わせ時の動画など)。

## 基本設計
要件定義で決定した各要件をどのように実現するかを設計します。
各ECUの受け持つ機能や入出力、通信仕様などを定義し、機能分割した後に側(がわ)だけの制御モデル(スケルトンモデル)を作成します。
後々「この機能はこのECU担当ではない」や「通信仕様はこれが正しい」など揉めることが無いように設計事項は仕様書としてドキュメント化し、関係者とのレビュー結果を書面として残しておきましょう。

## 詳細設計
基本設計で設計した各ECUが担当する機能のモデル化および検証を下記流れで行います。
1 各サブシステム内のロジックの作り込み
2 制御モデルの検証(モデリングガイドラインチェック、設計エラー検証、動的解析)
3 MILS(Model In the Loop Simulation)よるシステム検証

## コーディング
制御モデルからコードを生成し、その他コードと合わせてソフトを作成します。
従来開発では詳細設計で作成した仕様書をもとに人力でコーディング作業を行っていましたが、モデルベース開発では、自動コード生成機能により制御モデルから自動でコードを生成することができます。

## 単体評価
自動生成したコードを実際のECUに書き込んで机上環境で動作検証を行います。
この工程ではひとつのECUに対しての評価を行います。他ECUと連携して機能を実現する場合でも、まずは各ECUが仕様通り動作していることを確認するために本工程が存在します。(各ECUがそれぞれ正しく動いていることが確認できないまま結合してしまって不具合が出た場合、原因の切り分けに時間がかかる)

## 結合評価
複数のECUを結合して机上環境で動作検証を行います。
単体(ひとつのECU)ではなく、搭載予定のECUが全て接続された状態での評価を行います。
主にECU間の通信内容や、複数ECUが連動して機能する制御内容に関する確認を行います。
## 実機評価
全ECUを実機に搭載し、実環境で評価を行います。
要件定義内容を全て実現できていることを確認してプロジェクト完了となります。
# 終わりに
モデルベース開発工程について解説しました。モデルベース開発になったからといって工程自体が大きく変わるわけではなく、モデルをベースにしつつ効率的にV字プロセスを進めていくのがポイントです。


モデルベース開発を中心に組み込み系の情報をまとめたホームページも作成中ですのでよければ覗いてみてください。
[モデルベース開発入門](http://lets-mbd.com/)
AWS ECSの概念図をMermaidで書いてみた

ECSを勉強してみたので、主要概念をMermaidで書いてみた。


```mermaid
classDiagram
    Cluster "1" *--> "*" Service
    Service --> "1" TaskDef
    TaskDef --> "*" ContainerImage
    TaskDef ..> "*" Task : インスタンス化
    Task --> "*" Container
    ContainerImage ..> "*" Container : インスタンス化
    Service --> "0...1" LoadBalancer
    Service --> "*" Task

    class Service
    Service: +タスク数
    class TaskDef
    TaskDef: +ポートマッピング
```

### kubernetesとの関係

別のものなので、完全に対応付けできるわけではないですが、概ね似ている概念同士の関係

|ECS|Kubernetes|備考|
|-|-|-|
|Task|Pod|コンテナを複数含む|
|TaskDef|DeploymentのPod定義||
|Service|Service + DeploymentのPod定義以外||

### Mermaid感想

* 表示位置の調整はできるのか？
* 記述順を変えると、表示位置が変わったりする。
* クラス図だと、意味的な関係性を表すのに表示位置が結構大事なので、ちょっと使いづらいかも。
* シーケンス図なら行けるかな？
<備忘録>rails6でjQueryインストール

こんにちは
未経験から転職を目指すものです

今回はrailsアプリに
jQueryを入れて
画面に動きをつけていこうと
思います。


## 環境
* macOS      Monterey 12.３.1
* Ruby       3.1.2
* Bundler    2.3.10
* Rails      6.1.4.7

# jQueryインストール
まずはjQueryをインストールしていきます。
rails5以前はjquery-railsというGemをインストールするのが
主流のようですが
webpacker管理するには
yarnコマンドを使用しないといけないので、
yarnを使用してjQueryをインストールしていきます。

```
$yarn add jquery
yarn add v1.22.18
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ jquery@3.6.0
info All dependencies
└─ jquery@3.6.0
✨  Done in 1.72s.
```
インストールできました。

# webpackerの設定とjQueryの呼び出し
Webpackの設定ファイルでjQueryを管理下として認定します。
```js: app/config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// ここから
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
//ここまでを追加
module.exports = environment
```


続いて
application.jsでjQueryを呼び出します。

```js: app/javascript/packs/application.js
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()
require('jquery')  //追加
```

以上でjQueryを使える環境が整いました。



### 参考

https://qiita.com/tatsuhiko-nakayama/items/b2f0c77e794ca8c9bd74
RubyMine: 差分の表示にショートカットキーを割り当てる


RubyMineで、Git > 差分の表示(Show Diff) に、ショートカットキーを割り当てようとしたら、
設定項目にはメニューと同じ名称が見つかりませんでした。

そんな困った状態を回避出来たので、今回はその設定方法をご紹介したいと思います。


普段、RubyMineではプロジェクトタブを使ってファイルを選択しているのですが、
そこから、ファイルの変更内容を確認したいとなったとき、「マウス右クリック > Git > 差分の表示」という行程を行っていました。

たまに使う程度でしたら、マウスを使って操作とかでも良いかも知れませんが、複数のファイルを確認する時など何度も利用する場合は、マウスだとなかなか手間のかかる作業となってしまいます。

そこで、ショートカットキーの出番となるのですが、残念ながら標準では設定されていません。
じゃあ、自分で設定となるわけですが、冒頭に書いたようにここではまりました。

環境設定のキーマップ内を探しても、メニューに表示されている「差分の表示(Show Diff)」という項目は見つから無かったのです。設定出来ないのかな？と考えつつも、ぽちぽち探していると、、、見つかりました。

「**リポジトリの同じバージョンと比較**」 という名称でした。



試しに、キーマップの「リポジトリの同じバージョンと比較」に、ショートカットキーをセットしてみると、「Git > 差分の表示」にもしっかりキーが表示されました。

この設定で間違いなさそうです。


それでは設定していきましょう。


※ RubyMineには、Gitタブからファイル変更一覧を表示出来る機能があります。
プロジェクトタブにこだわらない場合は、Gitタブの方が簡単ですので、最後にそちらも少しご紹介しています。


 
## ショートカットキー設定方法
RubyMine メニュー > Preferences... を開きます。

![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251940/7cc2a1ef-a6cb-5991-4933-176cdc7b70dc.jpeg)


環境設定が開きますので、
キーマップ >  検索欄に「リポジトリの同じバージョンと比較」を入力します。

(英語表記)
Keymap > 「Compare with the Same Repository Version」

![image2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251940/c8bd3040-592e-246b-b356-f80704a6ecfd.jpeg)


検索にヒットした「リポジトリの同じバージョンと比較」を1つ選択します。
右クリックから「キーボードのショートカットを追加」を選択し、好きなショートカットキーを設定します。

(英語表記)
「Add Keyboard Shortcut」


私はショートカットキーに「SHIFT + CONTROL + COMMAND + D」を設定しました。

![image3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251940/2ca72435-f391-124c-b595-8fe5649f7d49.jpeg)


ここまでで、設定完了です。

プロジェクトタブから、変更を加えたファイルを選択して、ショートカットキーを叩いてみてください。
差分ウインドウがサッと開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251940/d7f74690-0ca6-0017-0952-0738ab95c322.png)





## Gitタブから差分を確認する

Gitタブ （COMMAND + 9）を使う場合は、すでにショートカットキーが準備されていますので、最初に書いたような登録の必要はありません。

使い方は簡単で、表示されている変更ファイル一覧から
ファイルを選択 > ショートカットキー「COMMAND + D」

これだけで、差分の確認が行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251940/295759f9-c8e4-3891-d8e2-0a549b89b024.png)

プロジェクトタブとの違いは、ファイル一覧の表示方法になります。
Gitタブは、変更されたファイルのみが一覧で表示され、プロジェクトタブは全ファイルが階層構造で表示されます。

どちらも、一長一短があると思いますので、自分のスタイルにあった差分機能を使って効率的な開発を進めていきたいですね。



## 補足

紹介しているのは、Mac版RubyMineの内容となります。
ReactアプリケーションをPreactへ、webpackのaliasを使って置き換える方法について


PreactはReactと比較してとても軽量です。
そこでReactからPreact置き換えるにはどうすればいいのかと思い、調べてみました。

もし間違い等あればコメント下さい。

## preact/compatを使う

最初に想像するのが、アプリケーション内のimportをすべてpreactに置き換える方法ですが、実はそれ以外に`preact/compat`を使うという方法があります。

https://preactjs.com/guide/v10/getting-started/#integrating-into-an-existing-pipeline

上記のページに書かれていますが、webpackを使っていれば、resolveのaliasに`preact/compat`を登録するだけのようです。

```js:webpack.config.js
const config = {
  ...
  "resolve": { 
    "alias": { 
      "react": "preact/compat",
      "react-dom/test-utils": "preact/test-utils",
      "react-dom": "preact/compat",
      "react/jsx-runtime": "preact/jsx-runtime"
    }
  }
  ...
}
```

アプリケーション内のコードは

```js
import React, { useState, useEffect } from 'react'
```

のように書かれたままですが、先程の設定だけで`react`ではなく`preact`が実行されています。

## webpackのaliasについて

webpackのaliasの使い方としては、他にどのように使われるのでしょうか。

例えば、以下のように記述をすると、`~`で`./src`のエイリアスを設定できます。

```js:webpack.config.js
resolve: {
  alias: {
    '~': path.resolve(__dirname, 'src')
  }
}
```

そして、アプリケーション内でそのエイリアスを使って他のモジュールの解決をすることができます。

```js:./src/components/hoge/fuga.js
import { bar } from '~/lib/foo/bar.js'
// import { bar } from '../../lib/foo/bar.js' と相対パスで書かなくても解決できる
```

ディレクトリが深くなったときや、ファイルの移動をする時などに、相対パスではなくエイリアスを使っていると便利なこともあるでしょう。

preactのalias設定も同様で、先程の例でいうと、

```js
import React, { useState, useEffect } from 'react'
```

これが、以下のようなエイリアスが登録されていることで`preact/compat`に定義されているuseStateなどを使うことができます。

```js
import React, { useState, useEffect } from 'preact/compat'
```

## preact/compatがやっていること

今回はReactからPreactへの置き換えでしたが、単純に1からPreactのアプリケーションを作る場合は、`preact/compat`は必須ではありません。

例えば、useStateも、

```js
import { useState } from 'preact/hooks'
```

のように`preact/hooks`から使用することができます。

`preact/compat`は、React, ReactDOMとの互換性を保つためのレイヤーで、互換性を保ちながらpreactの機能を使うことができます。

具体的には、[preact/compatのコード](https://github.com/preactjs/preact/blob/10.7.1/compat/src/index.js)を見てもらえれば分かるのですが、`preact`, `preact/hooks`などをimportして、互換性部分の実装を追加し、それらをexportしているようです。

```preact/compat/src/index.js
import {
	createElement,
	render as preactRender,
	cloneElement as preactCloneElement,
	createRef,
	Component,
	createContext,
	Fragment
} from 'preact';
import {
	useState,
	useReducer,
	useEffect,
	useLayoutEffect,
	useRef,
	useImperativeHandle,
	useMemo,
	useCallback,
	useContext,
	useDebugValue
} from 'preact/hooks';
import { PureComponent } from './PureComponent';
import { memo } from './memo';
import { forwardRef } from './forwardRef';
import { Children } from './Children';
import { Suspense, lazy } from './suspense';
import { SuspenseList } from './suspense-list';

...(略)

export default {
	useState,
	useReducer,
	useEffect,
    ...
}
```

PreactはReactとの互換性を維持する部分をcompatに切り出すことで、preactとしての機能はシンプルに、軽量なコードベースを維持しています。
PreactとReactの違いはドキュメントにまとまっていますので、ご覧ください。

https://preactjs.com/guide/v10/differences-to-react/

## 参考

- [Resolve | webpack](https://webpack.js.org/configuration/resolve/)
- [Differences to React | Preact: Fast 3kb React alternative with the same ES6 API. Components & Virtual DOM.](https://preactjs.com/guide/v10/differences-to-react/)
Ubuntu 22.04 btrfs subvolumeへのインストール

VPSで以下構成でインストールしたい。

```
# fstab
/dev/vg/swaplv none swap sw 0 0
/dev/vg/rootlv / btrfs subvol=@ 0 1
/dev/vg/bootlv /boot ext4 defaults 0 1
```

Ubuntu ubiquityインストーラのデフォルトでは`subvol=/`でインストールされてしまう。これではスナップショットが使いにくい。

自分の環境ではBIOS(KVM)なのでefiパーティションは作っていないが/boot/efiをマウントすれば同様。

### インストール前提

自動セットアップは使えないので通常のlive-server.isoを使う。
https://cdimage.ubuntu.com/ubuntu-server/daily-live/current/

VPSのWebコンソール(novnc)では日本語キーボードで@を入力できないことが多いのでSSH経由で実行する。


### インストール用SSHセットアップ

- iso boot後言語選択画面から F1キー -> Help > Exit to shellでシェルへ抜ける。
- root shellが自動で起動しているが、rootでのSSHログインは無効化されているようなのでデフォルトの`installer`ユーザを使う。
- パスワード設定されていないので `passwd installer`でパスワードを設定
- ipアドレスはDHCPで割り当てられているはず。`ip addr`、`ip route`で確認。
- リモートからinstallerユーザでログインすると自動でsubiquityが立ち上がる。

### インストール

通常のインストール手順を進める。
（LVM作成が若干UI変わっている。VGを消して再作成するとおかしくなるなど挙動が怪しかった20.04から改善されているようだ）

インストーラの中でネットワーク設定の自動検出中にSSHが切れる場合があるので注意。もし切れたらコンソール側で再設定が必要。

インストール完了後リブートせずにもう一度シェルへ抜ける。

### subvolume再配置

インストール完了後の`/`は`/target`にマウントされたままなのでsubvolを作って再マウントし、initramfs/grubに反映する。
(`/boot`デバイスを変えていなければgrub側の変更は必要無いはずだが念のため)

```
# スナップショットでrwコピーを作る
sync
btrfs subvolume snapshot /target /target/@
btrfs property set -ts /target/@ ro false

# 最終構成にあわせて再マウント
# umount /target/boot/efi
umount /target/boot
umount /target
mount -o subvol=@ /dev/vg/rootlv /target
mount /dev/vg/bootlv /target/boot
# mount /dev/vda1 /target/boot/efi

# update-initramfs/grub用にデバイスを持ち込む
mount --bind /proc /target/proc
mount --bind /dev /target/dev
mount --bind /sys /target/sys

# fstabのsubvol変更。ついでに/swap.imgのエントリが自動で入っているので消しておく。
vim /target/etc/fstab

# 最終構成のchrootに入ってfstabとgrubの反映
chroot /target
update-initramfs -u
grub-install --recheck /dev/vda
update-grub

# 再起動
exit
reboot
```


### 再起動後

- スナップショットもとが`subvol=/`に残っているので忘れず削除。 
- /tmpあたりはsubvolに切り分けておいたほうが良さそう

### 参考

- https://qiita.com/imokurity/items/dbc9bd9c193a6eb8f77d
Pythonの変数変更時の挙動

# Pythonの変数の参照について
変数の参照を調べると下記の記事を発見した。
https://qiita.com/ponnhide/items/cda0f3f7ac88262eb31e

結論は記事にある通りで自分の環境でも再現できたが、仕組みが理解できなかったので、調べてみた。
>長々と書いたけど、つまり、
変数に新たなオブジェクトそのものが代入されるときには、これまでの参照先から変わって新たなオブジェクトが作られた場所を参照するようになる。
で実務的には問題ないはず。


# ミュータブルとイミュータブル
Pythonのオブジェクトには、ミュータブルとイミュータブルの2種類あり、これを理解できれば変数変更時の挙動の仕組みを理解できる。
公式を見ると、[ミュータブル](https://docs.python.org/3/glossary.html#term-mutable)とは、
>Mutable objects can change their value but keep their id().

とある。ここで `id()` はオブジェクトのIDを返す。したがって、`id(A) == id(B)` でオブジェクトA, Bそれぞれの参照が同じかどうか判定できる。
このことを踏まえれば、 ミュータブルなオブジェクトを変更しても、`id()` を維持する、つまり、参照を維持するとわかる。

簡単に試してみた。ミュータブルなオブジェクトを変更しても参照が維持されてることがわかる。
```
>>> a = [1, 2, 3]
>>> b = a
>>> print(a, b)
[1, 2, 3] [1, 2, 3]
>>> id(a) == id(b)
True
>>>
>>>
>>> b[0] = 4
>>> print(a, b)
[4, 2, 3] [4, 2, 3]
>>> id(a) == id(b)
True
>>>
```

次に、[イミュータブル](https://docs.python.org/3/glossary.html#term-immutable)とは、
>An object with a fixed value. Immutable objects include numbers, strings and tuples. Such an object cannot be altered. A new object has to be created if a different value has to be stored.

とある。上記の通り値を変更しても、新しいオブジェクトが作成されるので、参照が維持されない。

こちらも簡単に試してみた。イミュータブルなオブジェクトを変更すると参照が維持されないことがわかる。
```
>>> c = 1
>>> d = c
>>> print(c, d)
1 1
>>> id(c) == id(d)
True
>>>
>>>
>>> d = 3
>>> print(c, d)
1 3
>>> id(c) == id(d)
False
```

# それでも分からなかったこと
下記の例を見てほしい。

```
>>> a = [1, 2, 3]
>>> b = a
>>> print(a, b)
[1, 2, 3] [1, 2, 3]
>>> id(a) == id(b)
True
>>>
>>>
>>> b = [4, 5, 6]
>>> print(a, b)
[1, 2, 3] [4, 5, 6]
>>> id(a) == id(b)
False
```

ミュータブルなオブジェクトであるリストに、別の値を代入すると参照が変わってしまった。
変更しても参照が変わらないのが、ミュータブルなオブジェクトじゃないのか？

上記の挙動の原因は公式で見つからなかった。
挙動からは、Pythonは変更と代入を区別すると考えられる。
さらに仮説として、代入時には新しいオブジェクトを作成し参照を変える、つまり、コピーオンライト的な挙動をしているのではないだろうか。

# むすび
代入時の挙動の仕組みは見つからず仮説になってしまったが、変数変更時の挙動の仕組みは理解できた。
代入時の挙動をもう少し調べたい。

# 追記(2022/05/06)
@shiracamus様より補足していただきました。（[補足のリンク](https://qiita.com/yt_kg/items/8a4d6171404a105002fb#comment-dfc8d162e3405c464fe5)）
ミュータブルなオブジェクトへの代入により参照が変わることについて、疑問が解消されました。

>Pythonの値はすべてオブジェクトで、変数はオブジェクトへの参照を保持するだけです。
変数は変数辞書に格納され、変数名は変数辞書を参照するための辞書キー文字列でしかありません。
リストはさらに要素オブジェクトへの参照を保持します。
変数に代入してオブジェクトの参照先を変更するのか、変数を参照してオブジェクト内の参照先を変更するるのか、その違いを理解する必要があります。
テストケースの書き方コツ

# はじめに
これを書いている今日は5月6日(金)です。
7連休明けで明日からまた土日になるので今日1日はあまり力を入れずに自己研鑽をして過ごそうと思いQiitaを読んでいました。
QA的な新しい記事があまり無いなーと思いつつ「じゃあ自分が書くか」くらいなノリで書いていこうと思います。
:warning: この執筆はサボリではなく「[スナバ](https://zenn.dev/matsukaz/articles/e75ea18506f7cd)」と呼ばれる業務時間内で認められている自由時間を使用しています。


## 文章としての体裁を整える
私も日本語は上手ではありませんが、まずテストケースをどう書くという話の前に日本語のドキュメントとしての質を意識しましょう。
設計者（設計と実装を区別している現場もありますが、本ページでは設計者を実装者、作成者の意味で記載します）以外の人が読むと
　**それらしいけど適切なのかよくワカラナイ**
　**読みにくい**
　**手順や期待値が変だな**
というものがしばしば爆誕します。

日本語のドキュメントとしての全体の構成やまとまりが適切でなく、さらに誤字脱字が含まれていると**全体の構成が把握できないうえに読みにくい**と感じる可能性が高いです。
全体の構成については正解があるものではありませんが、同じ会社やチームなどの組織内では、ある程度ルールを整えておいた方が良いでしょう。

ルールが全く整備されていないならソートをイメージすると良いかもしれません。
```
第1ソート：画面を基準に表示や機能を順次確認をしていく
第2ソート：OSを基準に順次確認をしていく
第3ソート：正常系、準正常系を順次確認していく
```
のようなイメージです。
テストケースをExcelやスプレッドシートで作っているなら第1ソートの画面名をシート名にしてシート内では第2、第3の順でまとまりを作っていく、ツールで作っているなら第1シートの画面名をテストスイート名にする・・・などが具体的な落としどころにすることが出来そうです。

他には**ですます調**や**能動態と受動態**も揃えておくとリズムが崩れなくて良いと思います。
手順の悪い例
```
1.ログインWebページを開き、新規登録ボタンを押下する
2.ユーザー名を入力する
3.パスワードを入力しろ
4.パスワード(確認)に入力
5.保存ボタンをクリックする
```
手順の良い例
```
1.ログインWebページを開き、新規登録ボタンを押下する
2.ユーザー名を入力する
3.パスワードを入力する
4.パスワード(確認)に入力する
5.保存ボタンを押下する
```
ボタンを押す操作は「押下」に揃えて、末尾は「する」で揃えてみました。
「クリック」に揃えても良いですし、「する」をすべて削除する形で揃えるのもOKです。
<br>

期待値の悪い例
```
・ユーザーを登録すること
・ユーザーが登録されないこと
・トップページが表示されること
```
期待値の良い例
```
・ユーザーを登録すること
・ユーザーを登録しないこと
・トップページを表示すること
```
期待値は能動態と受動態が混ざっているので能動態に揃えてみました。
期待値は受動態で書かれていることも多くありますが、一個人の意見としてはテスト対象は人ではなくシステムなのでシステムの振る舞いを期待値として書いています。つまり、能動態です。
```
・(システムが)ユーザーを登録すること
・(システムが)ユーザーを登録しないこと
・(システムが)トップページを表示すること
```
なお、所説あると思うのでこれは各組織で認識が揃っていればどちらでも良いと思います。
（噂では手順は能動態、期待値は受動態で書くように教わっている会社もあるとのこと。理由があってこれで教えているのであれば是非理由を教えて欲しいです！）

日本語の勉強ではないのでここでは**混在**さえしていなければOKとします。


## 誤字脱字
そもそもミスなので注意をしてもしてしまう人はしてしまうと思います。残念ながらうまく防ぐ術を心得ていません。
タイポ系を拾えるツール(Wordの校閲などでも可)の導入や、タイポは気が付いた人が直すというルールにするなどにしてしまったほうが良いかもしれません。
自分が書いた内容を読み直すことは最低限した方が良いと思いますが、**徹底します！** という気合の元で何度も読み返したり周りの人にお願いをしてみてもらうことによる対処は費用対効果が低いので個人的にはオススメしません。

## 手順には手順のみを書く
```
1.XXXボタンを押下する
2.画面右上の〇〇を確認する
3.YYYボタンを押下する
```
上記の例の手順1~3には仲間外れがあります。
答えは手順の2です。
理由は1と3は**操作手順**なので名実共に手順で間違いありませんが、2は**目視による確認**で手順ではありません。仮に2を飛ばしても3の実行が出来るのであれば手順として順序に組み込むことが不適切です。
不要な条件や手順の指定は正しいテストにならない可能性があるので必要な内容を必要なだけ記載するようにしましょう。
この場合の書き換えとしては
```
1.XXXボタンを押下する
2.YYYボタンを押下する
※手順1実行後の期待値として「画面右上の〇〇が△△であること」という期待値にする

（どうしても必要であれば）
1.XXXボタンを押下する
2.画面右上の〇〇の確認後、YYYボタンを押下する
```
という形にすると手順をすべて操作手順に落とし込めます。

## 大なり小なりは揃える
**< > ≦** のような記号や以上/以下、より大きい/より小さいの表現方法についてです。

これはQAよりもプログラムを書く方のほうが意識が強いかもしれません。
ちなみに私は新卒の頃に右側が大きくなるように書くよう教わりました。
`if(0 <= i)` がOKで`if(i >= 0)` がNGです。

テスト界隈では初歩的な教育で以下と未満の違いなどは教わる機会があるので区別はできていると思いますが、例えば年齢を19歳以下と20歳未満など同じ範囲を示す場合に書き方がずれることがあるので揃えるようにしましょう。


## 終わり
他にも書こうと思えば書けますが、夜になったので終了です。
生産性を重視していますが、すでにいろいろな事に取り組んでいて何かをやったりやめたりすることでグーーーンと生産性が上がるというようなものは残っていない気がしています。
なので、この記事に書いたような地味で微妙な事の積み重ねで気が付くと生産性が上がっている状態になったら良いなと思っています。


>自分が書いた内容を読み直すことは最低限した方が良いと思いますが

お腹がすいたので最低限のこともしないで投稿したいと思います！（こーゆーのがしくじる原因）
Pythonで画像をOCRしてテキスト変換する！

# はじめに
Pythonプログラムで即業務に役立つサンプルプログラムとして、画像の中の文字をOCR処理して文字起こしするプログラムを作成しましたので、共有します。
今回利用したOCRエンジンは、Tesseract-OCRです。

# 動作環境
Visual Studio Code
Python3.9.1
# 各種インストールライブラリー
pyocr 0.8.2
Pillow 8.4.0
pyperclip 1.8.2
# 処理概要:
クリップボードにある画像データをインプットにPythonプログラムでOCR処理して、テキストデータに変換して、再びクリップボードに保存するプログラムです。
![Pythonで超便利OCRツール作成_060.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1361368/a07e9d07-e534-683c-e740-3f3390a62c52.png)


# YouTubeでの解説：
プログラムの詳細やTesseractのインストール方法、Pythonプログラムをショートカットキーで実行する方法などはYoutubeでも解説していますので、ぜひ、ご覧ください。
<iframe width="560" height="400" src="https://www.youtube.com/embed/BqyJt1wCN_0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


# サンプルソース
YouTubeで紹介している処理のプログラムソースです。
```Python:OCR_pgm.py
import pyocr
from PIL import Image,ImageGrab
import pyperclip as pc

pyocr.tesseract.TESSERACT_CMD = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
#pyocrへ利用するOCRエンジンをTesseractに指定する。
tools = pyocr.get_available_tools()
tool = tools[0]

img = ImageGrab.grabclipboard()
# img = Image.open("./test.jpg")

#画像から文字を読み込む
builder = pyocr.builders.TextBuilder(tesseract_layout=6)
text = tool.image_to_string(img, lang="jpn", builder=builder)

print(text)
pc.copy(text)

```


# 最後に：
今後も、業務に役立ちそうなプログラムを作成して掲載していきたいと思います。
BlenderでPythonを実行する方法

## 概要

Blenderの機能のいくつかは、Pythonを使って実行できます。
ここでは、Pythonコードを実行する4つの方法を紹介します。

1. BlenderのPythonコンソール
1. Blenderのテキストエディター
1. シェルからBlenderのコマンド
1. アドオン

## BlenderのPythonコンソール

Pythonコンソールは、ちょっとしたコードを実行するのに向いています。
Pythonコンソールを表示するには、BlenderのエディタータイプからPythonコンソールを選びます。

![a1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/be2bb8cc-fb40-1ef8-c366-7fc9a745752c.png)

### Scriptingワークスペース

Pythonコンソールは、Scriptingワークスペースで予め表示されています。ワークスペースに切り替えはヘッダーで可能です。Scriptingは、ワークスペースの一番右にあります。ワークスペースが切れている場合は、スクロールする必要があります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/0cffdad9-65d8-db8c-337f-6826ae6f8bdd.png" width="500">

Pythonコンソールでは、`>>>`のプロンプトで、Pythonのコードを実行できます。
たとえば、下記のように`1 + 2`を入力して`Enter`を押すと`3`が返ります。

![スクリーンショット 2022-05-06 19.21.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/d3c4716f-a135-5b3c-0f7c-c1db34970ba9.jpeg)

## Blenderのテキストエディター

テキストエディターは、ある程度まとまったコードを実行するのに向いています。また、Blenderファイル（`.blend`）を保存すると、テキストも一緒に保存されるので、コードを残しておきたいときに便利です。
テキストエディターを表示するには、Blenderのエディタータイプからテキストエディターを選びます。

![a2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/bf12a029-c58a-abc5-0518-083e166cb79e.png)

なお、テキストエディターは、Scriptingワークスペースで予め表示されています。ワークスペースに切り替えはヘッダーで可能です。Scriptingは、ワークスペースの一番右にあります。ワークスペースが切れている場合は、スクロールする必要があります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/0cffdad9-65d8-db8c-337f-6826ae6f8bdd.png" width="500">

### 新規テキスト

ヘッダーの`新規`を押して、新規テキストを作成できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/5267b85f-bdd6-92de-b41d-0e52b3847a4f.png" width="500">

キャレット（テキストの挿入位置を表す縦棒）が表示されるので、テキストを入力できます。
作成したテキストは、テキストメニューからファイルとして保存できます。

### 既存ファイルのテキスト

ヘッダーの`開く`を押して、既存ファイルを開けます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/74fa733b-d67f-23ac-508a-6ac33f3a2635.png" width="500">

### テキストの実行（スクリプト実行）

新規テキストと既存ファイルのテキストは、どちらも、テキストメニューの`スクリプト実行`で実行できます。
また、ヘッダーの`▶`を押してもスクリプトを実行できます。

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/f8987d75-5be6-c178-2d23-f5afd5c7acba.png)

## シェルからBlenderのコマンド

BlenderのUIを使用せずにPythonコードだけ実行したい場合は、シェル（Windowsではコマンドプロンプト）からBlenderを実行する方法が便利です。Blenderをシェルから実行する場合、Pythonファイルを指定して実行できます。

詳しくは、記事「[Blenderのコマンドサンプル](https://qiita.com/SaitoTsutomu/items/6b70367455f843a979b1)」を参照してください。

## アドオン

特定の作法に従って、Pythonコードを記述することで、アドオンとして登録して実行することができます。
アドオンは、主にBlenderの機能を拡張したい場合に用います。

詳しくは、[ぬっち](https://qiita.com/nutti)さんの「[はじめてのBlenderアドオン開発](https://colorful-pico.net/introduction-to-addon-development-in-blender/2.8/)」が参考になります。
PyScript触ってみた

## 要約

ざっくり軽く調べた感じだと

* PyScriptとは
    * Pyodideでビルドされてる
    * 簡単にいうとHTML上でPythonが動かせる
* [Pyodide](https://pyodide.org/en/stable/)とは
    * CPythonのWebAssenblyへの移植版
    * ブラウザ上でPythonを動かす
    * micropipを使う
* WebAssenblyとは
    * バイナリコードをブラウザで扱うための技術

要するにPythonをバイナリ変換してWebAssenblyで動かしてるってこと？


* 何が嬉しいのか
    * JSではない選択肢が増える？
    * JSではできないことができる可能性がある？
    * JSより早くなる？

## とりあえず使ってみる

```shell
git clone https://github.com/pyscript/pyscript
cd pyscriptjs
npm install --global rollup
npm install
npm run dev
```

上記のコマンドを実行してhttp://localhost:8080/ にアクセスすれば次のような画面が表示されます。

![スクリーンショット 2022-05-06 19.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1654639/fa0c22eb-d82f-caf6-1322-96b8774147cd.png)

[Basic examples]のHello worldを開いてみるとPythonによって現在時刻が計算されていますという内容の文章が表示されます。

![スクリーンショット 2022-05-06 19.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1654639/e3269f6f-bab6-ac7a-2056-89ee87af1730.png)

画面を表示しているhtmlファイル`pyscriptjs/examples/hello_world.html`の中身を見てみるとPythonコードが`<py-script></py-script>`内で定義されています。

```html
~(省略)~
  <body>
    Hello world! <br>
    This is the current date and time, as computed by Python:
    <py-script>
from datetime import datetime
now = datetime.now()
now.strftime("%m/%d/%Y, %H:%M:%S")
    </py-script>
  </body>
~(省略)~
```

[Visualizations & Dashboards]のFractals with NumPy and canvasでは`<py-env></py-env>`でnumpy, sympy, 外部のpyファイルをimportしてフラクタルを描画しています。

```html
~(省略)~
<py-env>
- numpy
- sympy
- paths:
  - ./palettes.py
  - ./fractals.py
</py-env>
~(省略)~
```

![スクリーンショット 2022-05-06 19.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1654639/16b0a21e-c320-6ea5-0c91-878f0c084e32.png)



## 使用可能なライブラリ

現時点では[ここ](https://github.com/pyodide/pyodide/tree/main/packages)に記載されているものが使用可能なようです。例えば`opencv-python`や`scikit-learn`も使えるようです。もしかすると頑張ればここにないライブラリも使える？

## まとめ

今回はサンプルコードを軽く触ってみました。また興味がでたら触ってみようと思いますが今すぐに何かに活用できそうだなとは思いませんでした。


## 参考文献

https://towardsdatascience.com/pyscript-unleash-the-power-of-python-in-your-browser-6e0123c6dc3f
.gitignoreって何？

# .gitignoreとは
***Gitの管理下におきたくないファイルを指定するファイル***のことです。

# どこにあるのか
ざっくりとした説明になりますが、ファイルの下の方にあります。

![スクリーンショット 2022-05-06 10.04.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/34031b0a-6e0c-6854-e21b-6f004271dba1.png)

# 設定方法
今回は.envをGitの管理下から外そうと思います。
.gitignoreで設定している時は下のように特に何もありません。
![スクリーンショット 2022-05-06 10.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/b080d780-16fd-03df-7aea-8a7df3081e48.png)


.gitignoreで設定すると下のように.envの文字が薄くなります。

![スクリーンショット 2022-05-06 10.13.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/77355486-7ad9-83e0-3774-350d0786c4b7.png)

これでGitの管理下に置かれていない状態です。

# どういうふうに書くか

```.gitignore
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env    //今回はここを追記
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
/.idea
/.vscode
```
.gitignoreは人によって書いてある内容が変わります。

下の資料に細かい書き方などが載っています。

https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff
表計算の関数⇄Excelの関数のチートシート

基本情報技術者試験・表計算の関数名をExcelで言うと何？というのをまとめてみました。
イメージしやすいように簡単な機能説明をつけています。
ちなみに使用されている全てのExcel関数名はスプレッドシートでも同名の関数名でした。

| 基本情報 | Excel | 機能 |
|:-----------|------------|------------|
| 論理積 | AND | 複数の条件が、全てTRUEかどうか調べる。 |
| 論理和 | OR | 複数の条件が、一つでもTRUEかどうかを調べる。 |
| 否定 | NOT | 結果を反転させる。 |
| IF | IF | 条件を満たす場合と、満たしていない場合に、返す値を指定する。 |
| 最大 | MAX | 指定した範囲内の最大値を求める。 |
| 最小 | MIN | 指定した範囲内の最小値を求める。 |
| 平均 | AVERAGE | 指定した範囲内の平均を求める。 |
| 合計 | SUM | 数値の合計を求める。 |
| 個数 | COUNTA | 指定した範囲に含まれる、空白ではないセルの個数を求める。 |
| 順位 | RANK | 指定した数値の順位を求める。同順位の場合、最上位の順位になる。 |
| 標本標準偏差 | STDEV | セル範囲に含まれる数値を標本として計算した標準偏差を求める。 |
| 母標準偏差 | STDEVP | セル範囲に含まれる数値を母集団として計算した標準偏差を求める。 |
| 切上げ | ROUNDUP | 数値を指定した桁で切り上げる。 |
| 切捨て | ROUNDDOWN | 数値を指定した桁で切り捨てる。 |
| 四捨五入 | ROUND | 数値を指定した桁で四捨五入する。 |
| 整数部 | INT | 小数点を切り捨てて整数にする。 |
| 乱数 | RAND | 0以上で1を超えない数値をランダムで発生させる。 |
| 統合 | CONCATENATE | 複数の文字列を結合する。 |
| 剰余 | MOD | 割り算の余りを求める。 |
| 平方根 | SQRT | 平方根を求める。 |
| 表引き | INDEX | 指定した行番号・列番号にあるデータを取得する。 |
| 照合一致 | MATCH | 検索範囲内で指定した値で検索し、最初に見つかったセルの位置を数値で返す。 |
| 照合検索 | LOOKUP | 検索範囲の1行目または1列目で特定のデータを検索し、該当する行の指定列にあるデータを取得する。 |
| 垂直照合 | VLOOKUP | 検索範囲の1行目で特定のデータを検索し、該当する行の指定列にあるデータを取得する。 |
| 水平照合 | HLOOKUP | 検索範囲の1列目で特定のデータを検索し、該当する列の指定行にあるデータを取得する。 |
| 条件付合計 | SUMIF | 1つの条件に一致する数値の合計を求める。 |
| 条件付個数 | COUNTIF | 1つの条件に一致するセルの個数を求める。 |

:::note warn
引数の扱いは若干の違いがありました。
よく使用されている方の表計算ソフトで考えつつ、細かい部分は比較してみてください。
:::
Java17でGradleビルド時に「Unrecognized VM option 'MaxPermSize=2048M'」のエラーが発生した

備忘録です。

## 事象
Java17に上げてGradleでビルドをしようとしたら以下のエラーが発生した。

```bash
Unrecognized VM option 'MaxPermSize=2048M'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
```

## 原因
gradle.propertiesに設定していた`-XX:MaxPermSize`が[Java17でJava Optionから削除](https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html#removed-java-options)されたため。

```text:gradle.properties
org.gradle.jvmargs=-Xms2048M -Xmx5120M -XX:MaxPermSize=2048M
```

## 解決方法
gradle.propertiesから`-XX:MaxPermSize`のオプションを削除した。

```text:gradle.properties
org.gradle.jvmargs=-Xms2048M -Xmx5120M
```

## 参考文献
- [stack overflow](https://stackoverflow.com/questions/69402824)
全文検索【応用編】

「あの文言どこのファイルにあったっけな」
「検索して見つけたファイルをすぐに開きたいな」
そんなときに役立つコマンドをご紹介いたします（備忘録）
# 全文検索コマンド（コピペで使えるヨ）
```
$ find ./ -type f -print | xargs grep "hogehoge"
```
プロジェクトを行なっているディレクトリに移動して、検索したいワードをhogehoge部分に入れると対象のファイルをフルパスで表示してくれます。
それでは一つ一つ紹介していきます。
## findコマンド
場所を指定してファイルを検索するコマンドです。オプションを指定することで細かく、検索内容を指定することができます。
findの後にファイル名を指定することで特定のファイルを検索することができます。今回は「./」としています。このようにすることで現在いるディレクトリ以下にあるデータに対して検索をかけることができます。
### オプション
- -type f : 検索対象をファイルに限定します。ディレクトリは「d」
- -print : 見つけたファイルをフルパスで出力します。このオプションをつけておくことで対象のファイルを現在いるディレクトリから一発で開けます。
## xargsコマンド
標準入力やファイルからリストを読み込み、コマンドラインを作成して実行するコマンドです。先ほどのfindコマンドを「|（パイプ）」でつなぎます。
こうすることでfindコマンドで指定したすべてのファイルに対してxrags以降のコマンドを実行するよー的な意味合いです。
## grepコマンド
ファイル内の文字を検索するコマンドです。macでいうCommand + F的なやつです。
grep "foobar"とすることでfoobarを検索できます。

# まとめ
まとめに入ります。
「findコマンドにディレクトリ以下のデータを指定して（**./**）検索対象をファイルにして（**-type f**）フルパスで指定する（**-print**）
指定したディレクトリ以下のすべてのファイルに対して（**xargs**）「hogehoge」を検索する（**grep "hogehoge"**）」
得られた結果はフルパスで表示されるのでopen ./foo/bar/baz.txtみたいな感じで一発で開けます。
```
$ find ./ -type f -print | xargs grep "hogehoge"
```
特定のカスタム投稿タイプのみ投稿数を取得する

自分メモ。

> カスタム投稿タイプを複数使っていてカスタムタクソノミー等を共有している場合にカウントが、複数分のカスタム投稿タイプの合計が取得されてしまいますよね。
>例えば、事業所とスタッフというカスタム投稿タイプと、都道府県っていうタクソノミーがあってどっちの投稿タイプでも都道府県というタクソノミーを使っている場合、大阪のスタッフの数を取得したいのに事業所で登録している数も取得されてしまうようになるのです。

https://higezine.com/blog/front-end/wordpress/2020/01/16/615/
Advantages & Disadvantages of IGBT

利点

全体として、IGBTにはBJTとMOSFETの両方の利点があります。

それはより高い電圧と電流の処理能力を持っています。
入力インピーダンスが非常に高くなっています。
非常に低い電圧を使用して、非常に高い電流を切り替えることができます。
It is voltage-controlled i.e. it has no input current and low input losses.
ゲート駆動回路はシンプルで安価です。
正の電圧を印加することで簡単にオンに切り替え、ゼロまたはわずかに負の電圧を印加することでオフに切り替えることができます。
オン状態の抵抗が非常に低い
電流密度が高く、チップサイズを小さくすることができます。
BJTとMOSFETの両方よりも高いパワーゲインを持っています。
BJTよりもスイッチング速度が速い。


短所

MOSFETよりもスイッチング速度が遅くなります。
一方向であり、逆方向に伝導することはできません。
より高い逆電圧をブロックすることはできません。
BJTやMOSFETよりもコストがかかります。
サイリスタに似たPNPN構造のため、ラッチングの問題があります。


IGBTのアプリケーション
IGBTには、 ACおよびDC回路で使用される多くのアプリケーションがあります。ここにIGBTの重要なアプリケーションのいくつかがあります

SMPS（スイッチモード電源）で使用され、敏感な医療機器やコンピューターに電力を供給します。
It is used in UPS (Uninterruptible Power Supply) system.
速度制御を提供するACおよびDCモータードライブで使用されます。
チョッパーやインバーターに使用されています。
ソーラーインバーターに使用されています。
SQLのバルクインサート、バルクアップデート

SQLを使った一括更新を行なったので、その時の作業メモです。
この記事書くことで「バルク」という単語を知りました。

## 大前提として、トランザクションで区切る

SQLの最初に教えるべきこととして、トランザクション処理があります。
「テスト実行」とか「--dry-run」に近いSQLの **実行はするけど保存はしない** 操作ができます。

特にinsert, delete, updateなどのデータ変更の処理をする時はトランザクション処理をしましょう（必須）

```SQL
-- postgresqlの書き方
begin;
[一連の処理]
rollback;
-- コミットする時は「end;」
```

## Insertのバルクインサート

1行ずつのInsertはやめて、バルクインサートの方がいいことが多いです。
処理速度が早いことと、可読性が上がるので後からの処理が楽です。

```SQL
-- postgresqlの書き方
begin;
	select * from food order by cd limit 3;

	insert into
		food (cd, name) 
	values
		('000', 'パン')
		('001', 'ごはん')
		('002', '海苔')
		('003', '納豆')
		('004', '梅干し');

	select * from food order by cd limit 3;
rollback;
-- コミットする時は「end;」
```

## Updateのバルクアップデート

1行ずつのUpdateはやめてバルクアップデートの方がいいことが多いです。
case-whenを使った一括操作です。

update句をたくさん書く書き方もありますが、多分こっちの方が早い
（いい参考文献あれば共有いただけると嬉しいです）

条件分けがあるのに、where句を使わずにかけてるところがポイントです。

```SQL
-- postgresqlの書き方
begin;
	select * from food order by cd limit 3;

	update
		food
	set
		name =
			case
				when cd = '000' then 'パン'
				when cd = '001' then 'ごはん'
			    when cd = '002' then '海苔'
			    when cd = '003' then '納豆'
			    when cd = '004' then '梅干し'
			    else ''
			end;
	select * from food order by cd limit 3;

rollback;
-- コミットする時は「end;」
```


## あとがき

仕事で学んだことのメモとして記事を書いていますが、仕事で使っているシステムがEnterを押して帰ってくるまで裏でやってるDB処理が遅すぎたために複雑な機構を取ってる