OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP8.2】readonlyなクラスが作れるようになる

[PHP8.1でreadonlyプロパティが実装されました](https://qiita.com/rana_kualu/items/ae96400a0a6981eca64a)が、このreadonly修飾子がクラスにも使えるようになります。
プロパティごとにreadonlyを設定するのではなく、クラス自体を厳格に運用することができるようになります。

以下は該当のRFC、[Readonly classes](https://wiki.php.net/rfc/readonly_classes)の日本語訳です。


# PHP RFC: Readonly classes

## Introduction

PHP8.1で[readonlyプロパティがサポート](https://qiita.com/rana_kualu/items/ae96400a0a6981eca64a)されました。
しかしたとえば、多くのプロパティのある不変クラスの宣言は未だに面倒です。

そこで、このRFCではreadonlyなクラスのサポートを提案します。

## Proposal

PHP8.1で追加されたreadonlyを、クラスにも適用できるようにします。

```php:PHP8.2
readonly class Test {
    public string $prop;
}
```

これによって、クラス内の全てのプロパティがreadonlyになります。
また、動的プロパティの作成も禁止されます。

```php
readonly class Foo{
    public int $bar;

    public function __construct() {
        $this->bar = 1;
    }
}

$foo = new Foo();

$foo->bar = 2; // Fatal Error: Uncaught Error: Cannot modify readonly property Foo::$bar
$foo->baz = 1; // Fatal Error: Uncaught Error: Cannot create dynamic property Foo::$baz
```

また[Deprecate dynamic properties](https://qiita.com/rana_kualu/items/53012c8f84e0f92220c1)のRFCにおいては、`#[AllowDynamicProperties]`を指定することで動的プロパティを引き続き使えるようにサポートされましたが、readonlyクラスに対しての指定は禁止されます。

```php
#[AllowDynamicProperties]
readonly class Foo {
}

// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
```

### Restrictions

型のついていないプロパティ、静的プロパティを宣言することはできません。

```php
readonly class Foo{
    public $bar;            // Fatal error: Readonly property Foo::$bar must have type
    public static int $baz; // Fatal error: Readonly class Foo cannot declare static properties
}
```

### Inheritance

readonlyプロパティと同様、readonlyクラスをreadonlyクラスでextendsすることは可能です。

```php
readonly class A {}
readonly class B extends A {} // これはOK
```

readonlyクラスをreadonlyでないクラスでextendsしたり、その逆は禁止されます。

```php
readonly class A {}
class B extends A {}
// Fatal error: Non-readonly class B cannot extend readonly class A

class A {}
readonly class B extends A {}
// Fatal error: Readonly class B cannot extend non-readonly class A
```

### Reflection

`ReflectionClass::isReadOnly()`メソッドが追加され、クラスがreadonlyか否かを調べることができます。
また`ReflectionClass::getModifiers()`メソッドに`ReflectionClass::IS_READONLY`フラグが追加されます。

## Backward Incompatible Changes

互換性のない変更はありません。

## Vote

投票期間は2022/04/27から2022/05/11まで。

このRFCは、賛成28反対7の賛成多数で受理されました。


# 感想

一回だけ代入可能であり、代入したあとでの変更は不可能になります。
要するにimmutableオブジェクトです。

```php
readonly class Foo{
    public function __construct(
        public int $bar
    ) {}
}

$foo = new Foo(1); // OK
$foo->bar = 2; // NG
```


readonlyを指定したクラスは、静的プロパティは設定できず、動的プロパティも使用できず、型指定は必須であり、一度設定した値を書き替えることはできないと、できることが非常に限定されるようになります。
そのぶん何処かでうっかり値を書き替えられるなどの事故を防ぐことができ、堅固で安全性の高いインスタンスの運用が可能になります。

未定義プロパティへのアクセスは最終的に[PHP9.0で禁止される](https://qiita.com/rana_kualu/items/0defd290da5d1707f0d3)のですが、readonlyクラスはそれのほぼ上位互換みたいなものです。
【YOLO】Jetson で画像認識するまでのセットアップメモ


## 概要
Jetsonで画像認識する際にいくつか詰まるポイントやメモがあったので忘備録として残しておきます。


# JetsonをsshとVNCで遠隔操作する

jetsonを使用する際、いちいちキーボード等を接続していては机の上が汚くなり、作業効率が落ちるため、自分の💻から遠隔で操作できるようにする。

## VNC

### jetson側


![_2021-04-08_21.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/9a1e7d8a-f77d-3b27-1212-9fe6186c1d19.png)



L4T-READMEというフォルダがデスクトップに存在するため、クリックする。

/media/user(ここはユーザー名で置き換える)/L4T-README/README-vnc.txt

があるので、開くと中にvnc設定方法が書いてあるため、その指示に従う。つまづくことなくコピペで全部いけました。
![_2021-04-08_21.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/602477f3-2205-8eb8-236f-ed9b1ea5ee96.png)


ただ、ここの部分でpasswordがthepasswordに設定されていることは確認する。セキュリティ等に不安がある場合はここを書き換えて実行する。

上の処理を最後までやったら、ターミナルでifconfigを入力し、jetsonのipアドレスを確認して控えておく。

同じLAN内じゃないと接続できないよ

### 操作pc側

![_2021-04-08_21.20.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/8a558655-4f12-96b5-1e35-29a1d37ded66.png)


VNC Viewerというソフトをダウンロードする。


上のバーに先ほど控えたipアドレスを入力する。

![_2021-04-08_21.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/43f4dd4d-c732-b631-98f8-feaff5abfbd0.png)


先ほど設定したパスワードを入力することで、VNC接続が完了する。

めんどくさいのでremember passwordをオンにしておくと良い

VNC接続ができた場合、**ファイル転送も可能となるそうなのだが、自分の環境ではなぜか失敗するため**、次にsshの設定を行いscpでファイル送信する。
## ssh
https://kocoffy.com/jetson/post-201

こちらのサイト通りにしたらできました。

# Yolo使用までのめも
darknetでYOLOを使うのでdarknetをダウンロードする。

大体調べたとおりの手順にやると
なぜかmakeが成功しないので、cmakeでやる。
するとcmakeのバージョンが足りないので,``sudo apt update`` からの``upgrade``で　Cmakeをアップグレードしとく。

aptで持って来れるバージョンが最低要求より低いのでバイナリから入れる。(よくある)

``./configure``でやる

https://jskangaroo.hatenablog.com/entry/2020/02/11/213905

cmake作る際にopensslがないとか言われるから入れる。
```bash
$ ./configure
$ make
$ sudo make install
```

## 全体のフロー

- darknetをcloneする
- makeがなぜか失敗するからcmakeでやろうとするとcmakeのバージョンが違うからみす
- cmakeはaptで持って来れるバージョンが古すぎるから手動で入れる
- またopensslのバージョンが古すぎるからアプデする。

```bash
$ wget https://github.com/Kitware/CMake/releases/download/v3.18.1/cmake-3.18.1.tar.gz
$ tar zxvf cmake-3.18.1.tar.gz

$ sudo apt-get install libssl-dev ここで開発者ツール入れてる

$ cd cmake-3.18.1/
$ ./configure
$ make
$ sudo make install
$ echo 'export PATH=$HOME/cmake-3.18.1/bin/:$PATH' >> ~/.bashrc
$ source ~/.bashrc
```

ここまでやったらなぜかmake自体できる

するとvncc のpathが通ってない問題が発生する。

```bash
$ which vncc
```

で出てきたところをメモする。

しかしパスを通しても成功しない場合があったので直接設定を変える。
具体的にはdarknet/Makefileの七十四行目あたりにある

```bash
NVCC=nvcc
を
NVCC=/usr/local/cuda/bin/nvcc
```

これで成功しました！
react-native > firebase > While trying to resolve module `idb` 



Firebase`9.8.3`を入れたところ、
`While trying to resolve module idb` というエラーメッセージが表示される。




```
While trying to resolve module `idb` from file `/Users/xxxx/Github/Private/react-native-auth-google/node_modules/@firebase/app/dist/esm/index.esm2017.js`, the package `/Users/xxxx/Github/Private/react-native-auth-google/node_modules/idb/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/Users/xxxx/Github/Private/react-native-auth-google/node_modules/idb/build/index.cjs`. Indeed, none of these files exist:
```



## 解決方法

metro.config.jsをルートに追加する

```:metro.config.js
const { getDefaultConfig } = require('@expo/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

defaultConfig.resolver.assetExts.push('cjs');

module.exports = defaultConfig;
```


## 参考


https://stackoverflow.com/questions/72179070/react-native-bundling-failure-error-message-while-trying-to-resolve-module-i

https://docs.expo.dev/guides/customizing-metro/#adding-more-file-extensions-to--assetexts
基本情報（機械語のアドレス指摘方式パート2）

https://qiita.com/jupippii/items/043d1f4559023def1fe0

上記の続きを書きます。

## インデックス（指標）アドレス指定方式

インデックス（指標）アドレス指定方式では、オペランド部の値にインデックス（指標）レジスタの値を加算することで実効アドレスを求めます。

```
|命令部|2（インデックスレジスタ番号）|100(オペランド部）|

メモリ

0100 
0150 18
0154 25
0158 63

インデックスレジスタ
0
1
2 50

実効アドレスを求めます
```
インデックスレジスタとは連続したアドレスを扱うときに用いるレジスタです。
プログラミングの配列と同じですね。

今回はインデックスレジスタが2なので50の値を使用します。
インデックスレジスタの値とオペランド部の値を合わせることで、実効アドレスが決まります。

オペランド部が100のため150が実効アドレスです。
実効アドレスが150のためメモリは「１８」という値をデータとして用います。

## ベースアドレス指定方式
この方式では、オペランド部の値にベースレジスタの値を加算することで実効アドレスを求めます。

```
|命令部|50（オペランド部）|

メモリ

100
150
151
200 18
```
ベースレジスタってのはなによとなりましたが、プログラムがメモリ上にロードされた時の先頭アドレスを記憶しているレジスタのようです。
先頭アドレスを記憶することでメモリ上のどこにプログラムをロードされても命令を変えなくてすみます。

ベースアドレス指定方式はプログラム先頭アドレスからの差分をオペランド部で指定する方式です。

```
ベースレジスタ 150
オペランド     50
実効アドレス   200
```
200番地の「18」という値をデータとして用います。

## 相対アドレス指定方式
この方式では、オペランド部の値にプログラムカウンタの値を加算することで実効アドレスを求めます。

```
|命令部|50(オペランド部)|
150(プログラムカウンタ)

メモリ
0100
0150
0152
0200 18
0201

50(オペランド部) + 150(プログラムカウンタ)
実行アドレス 18
```
プログラムカウンタに入っているのは、次に実行される命令へのメモリアドレスです。
相対アドレス指定方式は、メモリ上にロードされたプログラムの中の命令位置を基準として
そこからの差分をオペランド部で指定する方式となります。

ベースアドレス方式と似ていてよくわからなくなってきたので一旦まとめてみます。

## 機械語のアドレス指定方式のまとめ
```
|命令部|オペランド|

メモリ
|メモリアドレス|実行アドレス|

```
**即値アドレス指定方式**
オペランド部に、対象となるデータそのものが入っている
**直接アドレス指定方式**
オペランド部に記載してあるアドレスが実行アドレスとして使える
**間接アドレス指定方式**
オペランド部に記載しているアドレスの中に、**対象となるデータが入っている箇所を示すメモリアドレス**がある
**インデックス（指標）アドレス指定方式**
オペランド部の値に、インデックスレジスタの値を加算することで実行アドレスを求める
**ベースアドレス指定方式**
オペランド部の値に、ベースレジスタの値を加算することで実行アドレスを求める
**相対アドレス指定方式**
オペランド部の値に、プログラムカウンタの値を加算することで実行アドレスを求める

## まとめ
早くCPUを頭に組み込みしたい
matlabでpng画像をbase64経由のエンコード・デコード

# やりかた
主に2つある，基本的には上で事足りるよね…？


## `matlab`純正関数を使う
`matlab.net.base64encode`と`matlab.net.base64decode`を直で叩く

https://jp.mathworks.com/help/matlab/ref/matlab.net.base64encode.html

https://jp.mathworks.com/help/matlab/ref/matlab.net.base64decode.html

そもそも画像データを読み込んで云々という動作させるには工夫が必要，データと型の扱いとか…


## `org.apache`を拝借する
`org.apache.commons.codec.binary.base64`をインスタンス化する

https://weblabo.oscasierra.net/java-apache-commons-codec-base64-1/

ただなんでJavaのライブラリが使えているのかよくわからん，R2022aで動いたけどこれはおま環かもしれないので要注意
あと`matlab`との食い合わせが悪いかもしれないので工夫が必要


# 使用例
やること

+ `html`で`Data URI Scheme`を出す
  + `Chrome`なら見れるはず
+ encode/decodeで元のファイルを復元する
+ **そのまま`slack`のwebhookにも送りつけてみる**
  + `type`には`mrkdwn`を指定する
  + 試したい人はapiを用意してね


```matlab:test1.mat
clear;


imgUrl = 'test.png';

fid = fopen(imgUrl);
fbt = fread(fid);
fclose(fid);


% With Apache
base64Coder = org.apache.commons.codec.binary.Base64;
fbtB64apa = uint8(base64Coder.encode(uint8(fbt)));
fbtB64apaChr = char(fbtB64apa.');
revfbtapa = double(typecast(base64Coder.decode(fbtB64apa),'uint8'));

newfid=fopen('test1Apache.png','w+');
fwrite(newfid,revfbtapa);
fclose(newfid);

% With Matlab
fbtB64matChr = matlab.net.base64encode(uint8(fbt));
revfbtmat = double(matlab.net.base64decode(fbtB64matChr).');

newfid=fopen('test1Matlab.png','w+');
fwrite(newfid,revfbtmat);
fclose(newfid);


% html base64 uri data scheme
html = '<head></head><body><img src="data:image/png;base64,'+string(fbtB64apaChr)+'"></body>'; % easy html style

newfid=fopen('test1.html','w+');
fwrite(newfid,html);
fclose(newfid);


% try to send Slack webhook
url = 'https://hooks.slack.com/services/xxx/yyy/zzz'; % your Webhook API url

content.type="html";
content.text = '<img src="data:image/png;base64,'+string(fbtB64apaChr)+'">'; % easy markdown style

payload = jsonencode(content);
options = weboptions('CharacterEncoding','UTF-8','UserAgent','matlab_simulink','Timeout',8);

webwrite(url,payload,options);
```


## どうなるか
こうなれば良い，`matlab`と`apache`で結果が一致するはず

![スクリーンショット 2022-06-20 18.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540440/0858346a-705a-0432-5caa-98d13a015b64.png)

`html`はブラウザで画像が見えていればOK
フォルダを見て画像が復元されていればOK

`slack`はクッソ長い文字列しか見えない，**そもそもData URI Schemeに非対応**か，もしくは**文字数制限でインタプリタが動作しない**か…
やはりどうしても画像投稿用のAPIを使う必要があるらしいな？


## `matlab`の問題点
自前で`uint8(binary)`しないとダメ，内部で変換してくれるらしいのだが恐らく`typecast(binary,'uint8')`をされている
画像データの読み込み時に`double`の`array`になるので，それを`cast`しながら`decode`してはいけない


## `apache`の問題点
恐らくちゃんとしたバイナリ列を返してくれるが，`matlab`側が`int8`で受け取るためオーバーフローみたいになる
ここでは`uint8`に`cast`する必要がある
SBOM とは

## 勉強前イメージ

セキュリティ周りっていうレベル感

## 調査

### SBOM とは

Software Bill Of Materials の略で、エスボムと読みます。
日本語ではソフトウェア部品表と言ってソフトウェアがどのような構成要素でできているのかを一覧で確認できるリストのことを指します。
製造業の部品表(BOM[Bill Of Materials])をソフトウェアに適応したものになります。

開発しているソフトウェアで独自のソースコードだけでなくライブラリやパッケージ等を組み合わせて構成されることがあります。
そのライブラリやパッケージ、また依存関係など一覧で簡単に参照できるようにするのがSBOMです。
これを行うことで使用していたライブラリやパッケージで脆弱性が発見されたりした際に
即座に判断できず調査から進めることをせずとも一覧を見るだけで影響あるのか・ないのかをすぐに確認できます。

また、SBOMにSPDX(Software Package Data Exchange)など様々なフォーマットがあります。
それによって管理することで効率的に管理することができます。

### SBOMがあるとき？

SBOMがあるとすると
2021/12に判明したLog4jの脆弱性ではSBOMを見て、Log4jを使用していればその部分の対処。
使用していなければ問題ありません。
しかし、何もなかったとするとapacheを使っているところからしらみつぶしに調査する必要があり
対応までに時間がかかってしまいます。

## 勉強後イメージ

部品表とかいうからIT関係ないんじゃないかって思ってたけど、
使ってるパッケージとかってことか。
これ管理するのめちゃくちゃ大変じゃない？

## 参考

- [SBOM 【Software Bill of Materials】 ソフトウェア部品表](https://e-words.jp/w/SBOM.html)
- [SBOM](https://www.newton-consulting.co.jp/itilnavi/glossary/sbom.html)
【JavaScript】使用してはまずい破壊的メソッドの話

## JavaScriptの２つの型
まず本題に入る前にJavaScriptには2つの型があります。

**プリミティブ型： 数値・文字列・論理値・null・undefined**
**オブジェクト型： その他オブジェクト**

そして、上記の2つではコピーする時の**JavaScript内のメカニズム**が多少異なります。

簡単な例を紹介します。

```JavaScript:プリミティブ型
let string = 'foo'
let newString = string
newString = 'bar'

console.log(string, newString);// foo bar
```
↑**プリミティブ型**では変数などはパソコンのメモリに保存され、コピーする際にも新しいメモリ空間を確保して保存します。
そのため元のstringにも影響ありません。

```JavaScript:オブジェクト型
let object = { name: 'foo' }
let newObject = object
newObject.name = 'bar'

console.log(object, newObject);// {name: 'bar'} {name: 'bar'}
```
↑**オブジェクト型**では新しいメモリに保存するのではなく、メモリアドレスを渡します。そのため元のobjectとnewObjectが同じメモリに保存されていて同じデータを共有しています。
だからnewObjectを変更すると元のobjectの値まで変わってしまいます。


次から本題に入っていきます。


## 破壊的メソッドとは

対象となるオブジェクト型の元の配列の値を変えてしまうメソッドを指します。

```JavaScript:破壊的メソッド一覧
sort()
splice()
push()
shift()
unshift()
reverse()
```

このメソッドの問題点は以下のミスが起きやすい点にあります。
```JavaScript
const numbers = [1, 2, 3, 4, 5];

// とても長い処理
numbers.push(6); <- 読み飛ばされてしまう可能性が高い
// とても長い処理

console.log(numbers); <- 読み手は[1, 2, 3, 4, 5]を期待している
// 実際は[1, 2, 3, 4, 5, 6]; 
```

ただし、非破壊的メソッドを使うと...
```JavaScript
const numbers = [1, 2, 3, 4, 5];

// とても長い処理
const newNumbers = numbers.concat(6);
// とても長い処理

console.log(numbers); // [1, 2, 3, 4, 5] 読み手の期待通りのまま
console.log(newNumbers); // [1, 2, 3, 4, 5, 6]
```

以上のことから**破壊的メソッドは**使用してはいけない風潮になっているらしいです。
jQueryの書き方

<html>
<title>jQueryが苦手すぎるため、備忘録として記録</title>

```
$(function () {
    // クラス名.on（イベント,function(){
    $(".status_code").on("change", function () {
        let disposal = $('option:selected').val();
        if(disposal == 3){
            $('#disposal_date').attr('readonly',false);
        } else {
            $('#disposal_date').attr('readonly',true);
        }
    });

    $("#asset_type_name").on("change",function(){
        let type_name = $("#asset_type_name").val();
        let type_id = $(`#${type_name}`).html();
    })
});
```
KVM とは

## 勉強前イメージ

仮想化のイメージあるけど、それ以外はわかってない

## 調査

### KVM とは

Kernel-based Virtual Machine の略で、linuxカーネル上で動く仮想化の技術です。
KVMを使ってホストを仮想化し、その上で仮想マシンを稼働させることができます。
仮想マシンはlinuxではなくてもwindowsでも稼働させることができ、複数の仮想マシンを稼働させることが可能です。

KVMはlinuxカーネル2.6.20以降で標準に搭載されています。
ちなみにlinuxカーネルのバージョン確認方法は `uname -r` コマンドで見ることができます。
以下が実行例ですが、こちらであれば3.10.0なのでKVMが標準搭載されています。

```
[root@localhost ~]# uname -r
3.10.0-1160.62.1.el7.x86_64
```

### そもそも仮想化のお話

仮想化を実現するには2種類のやり方があります。

- ホストOS型

ホストOSのミドルウェアとして、動作する。
気軽に構築できる。VirtualBoxなどこちらになる。
検証環境とかに使われている

- ハイパーバイザー型

ホストOSを使わず、仮想化のソフトが直接ハードウェアの入出力処置を実行する方法。
規模が大きい仮想マシンなどでよく使われている。

上記のような2つの種類があり
大きなサービスの本番環境などであればハイパーバイザー型が使われていることが多いのではないかと思います。
KVMはここでいうとカーネルに組み込まれているためどちらの型というのは言いづらいところではあります。

### QEMUについても・・・

KVMでlinuxカーネル上に仮想化の環境はできても入出力(I/O)の仮想化はできません。
これをするにはQEMU(キューエミュ)が必要です。
QEMUはエミュレータ型の仮想化ソフトの一つです。
KVMとQEMUをセットで入れることによって、様々なゲストOSを使用できます。

## 勉強後イメージ

virtualboxとかで検証環境を使ってるのはホスト型。
1台のサーバにいくつものサーバを置いて、webサーバだったりDBサーバだったり立てるのがハイパーバイザー型。
KVMはlinuxカーネル上で動く独自な存在。

## 参考

- [KVM とは](https://www.redhat.com/ja/topics/virtualization/what-is-KVM)
- [【連載コラム：仮想化技術をしっかり解説します（２）】仮想マシンの型には「ホストOS型」「ハイパーバイザー型」がありますが、その違いは？](https://linuc.org/study/column/3077/)
「スロークエリをkillしたら、MySQLが立ち上がらなくなりました...」

インフラ苦手人間がサーバーと格闘していた件の備忘録。
巻き込んでしまった皆さまには申し訳なさと感謝でいっぱいです。

## 環境
・OS:　RedHat Linux 8.2
・DB:　MySQL 5.7


## 事象
　①mysqlとSSH接続してデータ投入していたところ、以下のエラーが発生し接続が切れた
 ```
　　ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
```
　②その後mysqlの再起動を図るも、起動コマンド入力・認証後に下記エラーが発生し、再起動ができなかった
```
　 Job for mysqld.service failed because the control process exited with error code
```
## 結論
　サーバー内の容量を使いきっていた

## 詳しい経緯（戒めとして）
### 事象までの経緯
　・前日から、保守環境DBにてテスト用データ増幅作業を行っていた
　・当日もそれを続けており、ストアドプロシージャを1つ実行していた
　　⇒上記ストアドプロシージャが1時間たっても完了せず(statusはquery end)、やむなく対象プロセスをkill
　　⇒直後に事象①が発生
　・その後mysqlを再起動しようとservice mysqld startを実行
　　⇒事象②により再起動に失敗

### やってみたこと
　・ログチェック
　　⇒プロセスをkillした前後の処理はログに乗っているものの、以下の通り突然ログが切れた状態になっており、
　　　その後の起動試行についてはログ出力されていなかった
```
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
 [Warning] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
 [Warning] Can't create test file <サーバー内パスのため省略>lower-test
 [Note] <サーバー内パスのため省略>/mysqld (mysqld 5.7.37-log) starting as process 2498395 ...
<日時割愛>T10:49:15.333721+09:0 　//ここでログが途切れる
```
　　⇒「なんかクラッシュしたらしい...」ということしか読み取れず、先輩およびインフラエンジニアの方に泣きつく
　　⇒上記結論に至る

## 振り返ってみると
　冷静になって考えてみると、結構ヒントはありました。
 > 前日から、保守環境DBにてテスト用データ増幅作業を行っていた

　⇒ごりごりにINSERT SELECTを繰り返していたのだから、一番最初に容量を疑うべきだったのでは...?


> 上記ストアドプロシージャが1時間たっても完了せず(statusはquery end)

　⇒特にここ。
　　これまで何回も繰り返していたストアドプロシージャが、突然完了しなくなった理由を考えるべきだったのではないか。

> プロセスをkillした前後の処理はログに乗っているものの、以下の通り突然ログが切れた状態になっており、

　⇒その当時は「？？？」だったが、容量を使いきってログさえも書き込めなくなったということであれば納得がいく


## 教訓
　・データ投入をする場合、以下の2つをあらかじめ確認しておくこと
　　　①投入しようとしているデータ量
　　　②DBサーバーの残りのデータ量（ [df -h](https://www.itsenka.com/contents/development/unix-linux/df.html, "df -UNIX/Linuxコマンド -IT専科") などを使うと良い）

　・データ投入中もこまめにサーバー内の空き容量をチェックすること

　・普段からLinuxのコマンドは勉強しておくこと
　（知識があまりに浅いのでログの確認にすら四苦八苦した。その分だけ解決が遅くなったことは反省すべき）

## 最後に
　丸一日胃をきりきりさせながら調べてたんですが、インフラエンジニアの方が一瞬で解決してくださいました。
　やっぱり専門家は偉大。憧れますね。勉強します。
MacにRust環境を構築

# はじめに

２年ぶりにMac (Monterey)にRust開発環境を構築してみて、構築方法が変わっていました。構築方法を検索してみると古い情報が混じっていてわかりにくかったので、メモとして残しておきます。

:::note info
２０２２年６月での情報です。情報が古くなっている場合は、コメント欄で教えていただけると助かります。
:::

# インストール

以下の公式サイトに従ってインストールしていきます。

https://www.rust-lang.org/ja/learn/get-started

ターミナルから以下のコマンドを入力します。
```bash: ターミナル
% curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

Homebrewでインストールしたい場合は、以下を参照して下さい。

https://forge.rust-lang.org/infra/other-installation-methods.html

インストールできているか確認します。

```bash: ターミナル
% rustup --version        
rustup 1.24.3 (ce5817a94 2021-05-31)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.61.0 (fe5b13d68 2022-05-18)`
```
# VS Code 拡張

コマンドラインからテストプロジェクト（test_rust）を作成します。
プロジェクトを作成するのは必須ではないのですが、後でプロジェクをビルドしてデバッグするのでここで作成しておきます。

```bash: ターミナル
% cargo new test_rust
```

VS Codeでtest_rustフォルダを開きます。

次に、2つのVS Code拡張をインストールします。
* rust-analyzer　（コード補完、定義の表示等）
* CodeLLDB (デバッグに必要）

以前は、VS Code拡張のRustをインストールしていたのですが、非推奨になっているので、rust-analyzerをインストールしました。

# デバッグその1
main.rsを開くとmain関数の上に▶︎Run|Debugと表示されています。
Runをクリックすると実行、Debugをクリックするとデバッグ実行されます。
通常は、この方法でいいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613072/efb18a4d-6596-0332-d7b0-c96e32eb269a.png)
# デバッグその2
実行時の引数を指定したい場合は、こちらの方法になります。
create a launch.json fileをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613072/1f3106a5-1c39-af21-dea6-4e1c68f85cbb.png)
次に、LLDBを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613072/8465734f-43cf-bc95-5bc9-4a34cade855c.png)

rust-analyzerがCargo.tomlを認識すると以下のダイアログが表示されるので、Yesを押すとlaunch.jsonが作成されます。
デバッグ実行とUnitテスト実行用の設定が作成されます。
実行時の引数を追加したい場合は、launch.jsonを編集します。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613072/2099e869-5f5f-5d4f-4e02-e47baceafd76.png">

rust-analyzerをインストールした直後はCargo.tomlが認識されず、正しい設定ファイルが作成されなかったのですが、Macを再起動すると認識しました。

# まとめ
VS Codeを使ってrustのプログラムを開発する、最低限必要の環境を構築しました。
久しぶりに環境構築しましたが、いろいろ変わっていて戸惑いました。
環境も新しくなったのでRustのコーディングを楽しみたいと思います。
EC2用語要点まとめ（自分用メモ

・インスタンスタイプ
EC2インスタンス作成時に選択できるCPU、メモリ、ストレージ性能、ネットワークキャパシティーの組み合わせ

インスタンスタイプの名前は、インスタンスファミリー（M,T,Cなど）、インスタンスの世代（１、２、３・・・大きくなればなるほど最新）、インスタンスサイズ(nano,micro・・・大きくなればなるほどスペックが高い）で構成されている。


・ユーザーデータ
ユーザーがEC2インスタンス作成時に自動実行させたいコマンドやスクリプト（必須ではない）
設定したコマンドやスクリプトによってEC2インスタンス作成と同時にOSの設定やミドルウェアのインストールをすることで、インスタンスの作成完了後すぐに必要な環境を構築済みにできる。
EC2インスタンス作成時の「インスタンスの詳細の設定」画面で「高度な詳細」をクリックすると、ユーザーデータの設定画面が表示される。


・プレイスメントグループ
複数のEC2インスタンスをグループ化し、インスタンス間で低遅延な通信を可能にする機能。
EC2インスタンス作成時の「インスタンスの詳細の設定」内の「配置グループ」にて、プレイスメントグループの設定項目がある。


・インスタンスストア
EC2インスタンスから利用できる揮発性の（インスタンス稼働中にだけ利用可能な）ブロックストレージ。
だたし、EC2インスタンスの停止・終了時や障害発生時にはデータが失われる。一方、EBSよりも高いパフォーマンスを発揮できるという特徴がある。EBSで最も高性能なボリュームタイプでも64,000IOPS（※）だが、インスタンスストアは数百万IOPSを発揮できる。


・タグ
EC2インスタンスなどの各AWSリソースに「キー」と「値」を設定することにより、AWSリソースを分類できる任意の属性情報


・キーペア
EC2インスタンスに安全に接続するための暗号鍵。AWS上に保管されるパブリックキーと、ユーザーの環境上に保管するプライベートキーの2つの鍵で構成される。


・メタデータ
実行中のインスタンスに関するデータのこと。インスタンスIDやパブリックIPアドレス、DNSホスト名などが含まれます。
メタデータは実行中のインスタンスから「http://169.254.169.254/latest/meta-data/」にアクセスして取得できる。
S3互換のMinIOにてdocker-compose.yml上だけで初期バケットを作りたい

# この記事のターゲットとなる人
- Dockerを使用した開発をしており、S3互換ライブラリでMinIOを採用している(または検討中)
- 初期バケットを作りたいが、mcコンテナとか専用Dockerfileなどめんどくさいことはしたくない

# 結論
- `export` ディレクトリ配下にディレクトリを切れば良い
- docker-compose.yml 上で済ませるならこんな感じ

```yml
# "local" という初期バケットを作るサンプル
services:
  minio:
      image: minio/minio:latest
      container_name: minio
      environment:
          MINIO_ROOT_USER: localuser
          MINIO_ROOT_PASSWORD: password
      entrypoint: bash
      command: -c "mkdir -p /export/local && /opt/bin/minio server /export --address :9000 --console-address :9001"
      ports:
          - '19000:9000'
          - '19001:9001'
```

```yml
# docker-compose down 後も永続化を意識するならコマンドはいらない
services:
  minio:
      image: minio/minio:latest
      container_name: minio
      environment:
          MINIO_ROOT_USER: localuser
          MINIO_ROOT_PASSWORD: password
      entrypoint: bash
      volumes:
          - ./tmp:/export/local   # 永続化
      command: -c "/opt/bin/minio server /export --address :9000 --console-address :9001"
      ports:
          - '19000:9000'
          - '19001:9001'
```


## 雑な解説
- DockerのCMDは単一コマンドしか実行を受け付けないので `&&` で無理やり1行にまとめている
- `mkdir -p /export/local` にてバケットに相当するディレクトリを作成
- `/opt/bin/minio server /export --address :9000 --console-address :9001` にてminioのサーバーを立ち上げ
    - ポート番号はプロジェクトに合わせてお好みで


# あとがき
- 初期バケットを作るためだけにmcイメージや専用Dockerfileを用意するのが面倒だったので
- バケット数が増えてくると記述量が増えてくるので、その時は素直にshファイルに切り出した方が良いかもです
classで指定した複数の要素にstyleを設定したいけど、配列の要素を指定していくのは面倒だ

# 複数の要素にstyleを設定したい
## １．はじめに
JavaScriptで、HTMLをいじくりまわしていると、「class名が同じ要素すべてにstyleを設定したいな～」と思う時が訪れるでしょう。
でも、いちいち

    <script>
    function fontsize() {
        document.getElementsByClassName("name1")[0].style.fontSize = "70px";
        document.getElementsByClassName("name1")[1].style.fontSize = "70px";
        document.getElementsByClassName("name1")[2].style.fontSize = "70px";//以下繰り返し
        }
    </script>
のように書いて、あとは[]の中を要素の数分だけ指定して繰り返していくなんてめんどくさすぎる！
そう考えていた、そこのあなた(私)にこの記事を捧げます。

## ２．解決案
結論から言うと

    <script>
    function fontsize() {
        var className1 = document.getElementsByClassName("name1");
        for (var i = 0; i < className1.length; i++) {
            className1[i].style.fontSize = "70px";
        }
    }
    </script>
というようにfor文を駆使して書くとうまくいきます。
これでname1と名付けられた要素たちのフォントサイズを、(要素の数がたくさんあっても)すべて70pxにする処理が可能です。
## ３．この記事を書こうと思った背景
JavaScriptの勉強を始めた際に、

    document.getElementsByClassName("name1")[0].style.fontSize = "70px";
に関して愚かな私は
「いちいち[0]とか[1]で要素を指定せなあかんってなんやねん！

    document.getElementsByClassName("name1").style.fontSize = "70px";
で全部の要素のサイズを変えれないとclassってつけた意味ないやん！」
と憤慨していましたが、調べていくうちに、これはclassに罪があるわけではないことを知りました。
"They is ~"という文章を間違えてますと指摘されて、「なんやねんtheyって役立たずやな」と逆切れしているのに近かったのです。おバカでした。
（上のたとえに倣うなら

    document.getElementsByClassName("name1")[0].style.fontSize = "70px";
は"One of them is ~"みたいな感じですね）
## ４．おわりに
本当は、

     document.getElementsByClassName("name1").style.fontSize = "70px";
のように一行でまとめることができればいいんですが、調べた限り同様の条件では、できないようです。
…ただ、jQueryというライブラリのcss()を使うとかなりシンプルに書くことができます。

    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script>
            function fontsize() {
                $(".name1").css({'font-size':'70px'})
            }
    </script>
このように記述すると、前述のfor文で書いたコードと同じことができます。
というかこれが一番いいのかも？
【Slack】メッセージ送信用ベアラートークンの作成方法

# はじめに
社内のコミュニケーションツールでSlackを使用しています。
今回は自動で通知を送ってくれるbotに必要なベアラートークンの取得方法についてご紹介します。
# ベアラートークンを取得する
## bot用アカウント作成

ここにアクセスし、右上の**Create New App**をクリックします。
ワークスペースにログインしていない場合はします。

https://api.slack.com/apps

![記事用1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/0550494a-1d40-e039-5c71-6279f8b57924.png)

**From scratch**をクリックします。
![記事2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/a082f06f-14fb-96ff-cf6c-b2e347126d97.png)

任意のアプリ名,ワークスペースを選択し、**Create App**をクリックします。
![記事3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/aeb80fc1-5dde-3518-b7d1-ec8204754934.png)

**OAuth & Permissions**をクリックします。
画面遷移後、下にスクロールし**Scope**セクションを表示させます。
![記事4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/b00cafac-7888-a888-1e0f-9e96f6332975.png)
**Bot Token Scopes**内の赤枠で囲んだボタン**Add an OAuth Scope**をクリックします。
![記事5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/ca063d9b-bced-60e9-fb24-2b93bb898f47.png)
### スコープを設定する
必要なスコープを選択します。
今回はメッセージを送信するので、**chat:write**を選択し追加します。
![記事6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/c677754f-b4d5-ca51-831c-ec90d94f9445.png)

同様に**User Token Scope**にも**chat:write**を選択し追加します。
![記事7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/192b9a9d-6fcb-2bec-ce6f-60d45d415258.png)

### ワークスペースにインストールする
スコープを設定すると赤枠の**Install to Workspace**ボタンが有効になるのでクリックします。
![記事8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/0ad8ef7a-6427-a597-bfa4-844c1f0e5774.png)
権限をリクエストされるので、**許可する**をクリックします。
![記事9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/9aed9d22-c5d7-b43f-fc61-d21425531204.png)

### 生成されたトークンを取得する
アプリのインストールに成功すると、２つのトークンが生成されます。
これで完了です！
![記事22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/a3b65e5e-5a65-987f-74a5-052d76e46660.png)


# まとめ
今回はSlackでのベアラートークンの取得方法についてまとめてみました。
これがあればAPIを活用して通知を飛ばす事が可能になります。
取得したトークンを使って<a href="https://qiita.com/Aberyuu/private/40d1fb122fa865fdea13" target="_blank" rel="noopener noreferrer">Blue PrismからSlack通知を飛ばす方法</a>も記事にしていますので
そちらも見ていただければと思います！
【Blue Prism】【Slack】Slack通知をしてみよう

# はじめに
**Blue PrismからSlackに通知を送りたい！** っていう場面があるかもしれません。<br>
そこで今回は**Blue prism**から**Slack**への通知できるツールをご紹介したいと思います！<br>

# 今回使用した動作環境
* Blue Prism ver6.8.0

# 事前準備
まず、事前準備として以下を進めていきます。
* ベアラートークンの取得
* Slack Skillのインポート

## ベアラートークンを取得する
以下の記事で取得方法をまとめましたのでこちらを参照してください。
[【Slack】ベアラートークンの作成方法](https://qiita.com/Aberyuu/private/7121d7dfe54b65965dfb#bot%E7%94%A8%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E4%BD%9C%E6%88%90)

取得したら今回は赤枠の**Bot User OAuth Token**を使用します。
![記事27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/10312f77-a756-254f-2392-1cc3b5612daa.png)


### 認証情報にベアラートークンを設定する
Slackへ通知するには上記の**Bot User OAuth Token**を認証情報に設定する必要があります。
認証情報は［システムマネージャー］→［セキュリティ］→認証情報］で設定できます。
今回は新しい認証情報を作成するので、**新規**を選択します。
![記事25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/00d1f1fc-9f29-64c3-dcde-009d8410b99e.png)
３つの赤枠には以下の内容で設定します。
|  項目  |  入力形式  |  説明  |  値  |
| ---- | ---- | ---- | ---- |
|  名前  |  テキストボックス  | 任意の名称を設定 | Qiita_bot |
|  タイプ  |  プルダウン  | 認証情報のタイプを設定 | ベアラートークン |
|  トークン  |  テキストボックス  | トークンの値を設定 |  作成した**Bot User OAuth Token**の値を設定する  |

アクセス権の範囲も忘れずに設定します。
特に問題が無ければ**セキュリティの役割**,**プロセス（レガシー）**,**リソース（レガシー）** すべての項目にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/6c80d580-9874-e1f7-dc31-6890f3de1ffb.png)

## Slack SkillをBlue Prismにインポートする
Slack Skillは通常のVBOではないので、以下のリンクからダウンロードしてくる必要があります。
ダウンロードした.xmlファイルをBlue Prismにインポートします。
[Slack Skill](https://digitalexchange.blueprism.com/dx/entry/3439/solution/slack-messaging)

# インポートできたら、プロセスを実装してみよう
インポートが完了したら、プロセススタジオを開きます。
今回は以下のようにテスト用のプロセスを作成してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/bde44ac4-05db-9825-9a2f-773b1d8d7800.png)

## スキルからSlackアクションを配置する
赤枠の部分をクリックします。
![記事11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/b6524267-732e-0f1c-e131-f3ff539e4d2f.png)
クリックすると、赤枠のSlackアイコンが表示されるのでそれを左にドラッグ＆ドロップします。
メインページに配置できたらリンクを繋ぎます。
![記事12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/61f44076-de05-8de4-0b55-bf5eedbcc0f6.png)

## アクションのプロパティを設定する
配置しリンクを繋いだら、アクション**Post Message**を選択
入力プロパティを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/d361dd3c-598f-53cd-752a-5860f7208c5f.png)
今回は以下で設定します。
||  パラメータ  |  データ型  |  説明  |
| ---- | ---- | ---- | ---- |
|  入力  |  Slack Bearar Token  |  テキスト  |  設定した認証情報名  |
|  入力  |  Channel  |  テキスト  |  通知先のチャンネルID  |
|  入力  |  Text  |  テキスト  |  送信する通知の本文  |

これで設定完了しましたので実行してみます。
![記事26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/9e7862a5-dd29-e997-7283-8907c788a544.png)
# 実行する
では早速デバッグ実行してみましょう。
実行すると・・・
![記事28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/a805985a-473b-3e82-f11b-7d12c5c325f0.png)

メッセージが送信できました！
![記事29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/4bf82e6a-aefb-5486-8f24-4702cd2a3d61.png)
# まとめ
これを使えば、Blue Prismで稼働させているプロセスの処理結果などを
Slackで通知させる事ができます。
今回は、簡単なテキスト本文だけでしたがメンションを付けたり画像を添付して送る事も
できるのでそちらも記事にできればと思います！
NCMBのFlutter SDKを使って翻訳アプリを作る（その1：画面の仕様とSDKの初期化）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回はコミュニティSDKの一つ、Flutter SDKとDeepL APIを使って翻訳アプリを作ってみます。まず画面の仕様とSDKの初期化について解説します。

[ncmb | Dart Package](https://pub.dev/packages/ncmb)

## 完成版のコード

作成したデモアプリのコードは[NCMBMania/flutter_translation_app: Flutter SDKとDeepL APIを組み合わせた翻訳アプリです](https://github.com/NCMBMania/flutter_translation_app)にアップロードしてあります。

## ベースを作成する

`flutter create` コマンドでベースを生成します。

```
flutter create translate
```

## lib/main.dartについて

今回のコードはすべて main.dart に記述しています。クラスは次の6つです。

- MyApp
- MainPage
- TranslationPage
- _TranslationPageState
- HistoryPage
- _HistoryPageState

## MyApp

アプリ全体の準備をします。

```dart
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Translation App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: MainPage(),
    );
  }
}
```

## MainPage

タブを準備して、翻訳画面と履歴画面を読み込みます。

![Simulator Screen Shot - iPhone SE (3rd generation) - 2022-06-20 at 16.59.01のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/c90fb1ed-78e4-e362-b118-c1f4ae33d30a.png)


## TranslationPageと_TranslationPageState

翻訳画面です。翻訳実行と、翻訳結果のNCMBへの保存を行います。

![Simulator Screen Shot - iPhone SE (3rd generation) - 2022-06-20 at 17.00.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/bc3f12e4-9a21-739e-7fc3-940b2d3fb7e3.png)


## HistoryPageと_HistoryPageState

履歴画面です。翻訳結果の一覧表示を行います。

![Simulator Screen Shot - iPhone SE (3rd generation) - 2022-06-20 at 17.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/a4124bec-0e6d-a76d-04c2-422832546703.png)


## NCMB SDKのインストール

NCMB SDKは `flutter pub add ncmb` でインストールできます。

```
flutter pub add ncmb
```

記事執筆時点での最新版は `2.4.0` です。

## その他必要なライブラリ

今回はDeepL APIを呼び出すのに便利な[deepl_dart](https://pub.dev/packages/deepl_dart)と環境変数用の[flutter_dotenv](https://pub.dev/packages/flutter_dotenv)を利用しています。

```
flutter pub add deepl_dart
flutter pub add flutter_dotenv
```

## .envの用意

必要なキーはプロジェクトルートにある `.env` 内に記述しています。

`.env` の内容は以下の通りです。各キーはニフクラ mobile backendとDeepLのWebサイトにて取得してください。

```
APPLICATION_KEY=YOUR_APPLICATION_KEY
CLIENT_KEY=YOUR_CLIENT_KEY
DEEPL_AUTH_KEY=YOUR_DEEPL_AUTH_KEY
```

pubspec.yaml にて.envを追加します。

```yaml
flutter:
  # 以下を追加
  assets:
    - .env
```

## NCMB SDKの初期化

まず main.dart にてNCMB SDKをインポートします。

```dart
import 'package:ncmb/ncmb.dart';
```

main.dart のmain関数でNCMBの初期化をします。

```dart
void main() async {
  // .envファイルを読み込み
  await dotenv.load(fileName: ".env");
  // NCMBを初期化
  NCMB(dotenv.env['APPLICATION_KEY']!, dotenv.env['CLIENT_KEY']!);
  runApp(const MyApp());
}
```

これでNCMB SDKの利用準備が整います。

## まとめ

今回は各画面の説明とNCMB SDKの初期化までを行いました。[次回は日本語を入力してDeepLを使って翻訳するまでを解説します。](https://qiita.com/goofmint/items/e92ce8a4617cd768ab27)。
【基本情報技術者】ネットワーク管理

基本情報技術者試験の分野「ネットワーク管理」についてご紹介いたします。
## SDN
SDN（Software Defined Networking）とは、**ソフトウェアを用いてネットワークを制御する技術の総称**です。ルーターやスイッチなど、ネットワークを構成する機器をソフトウェアで一括して制御することにより、たとえばネットワークの構成やルーター・スイッチの設定を柔軟に変更することが可能。
### OpenFlow
SDNを実現する技術の一つ。ネットワーク機器内部の「経路制御機能」と「データ転送機能」を分離し、**コントローラ（ソフトウェア）でデータ転送機能をもつネットワーク息を集中的に制御**する。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/70e798f3-75be-7271-26e9-8fce915374da.png)
※それぞれを交通整理しているイメージ。途中で混雑するとデータの転送速度が落ちる。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/6e1240a1-4563-5727-848c-735505a1be2c.png)
※管制室により交通整理が一元管理されているイメージ。
### SDNのメリット・デメリット
メリットは**ネットワークを総合的に管理できること**
これまでのネットワークでは、運用管理者がポリシーに応じて手作業で個々のルータやスイッチなどのネットワーク機器の配線や設定を行っていましたが、SDNでは、ソフトウェアへの設定だけで完了することになります。ネットワーク運用管理の負担が軽減されるとともに、追加設定、または設定変更要件が出た際に即応する事が出来る。設備投資・運用コストの削減にも繋がる。

デメリットは**SDNにシフトするハードルの高さ**。
自社内の全ネットワーク機器のポリシーを一括管理するとなると、全ての機器と共通のプロトコルが必要になります。まだ「SDN」というの言葉の浸透率に追随出来ていない。導入コストやリスクを考え条件が揃わないのが現実。
## URL
Web上で取得したいWebページなどの情報源を示すための表記。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/fea50b1f-c8d9-5599-f4e5-b8016c72867e.png)
## CGI
CGI（Common Gateway Interface）は、**Webブラウザからの要求に対して、Webサーバが外部のプログラムを呼び出し、その結果をHTTPを介してWebブラウザに返す仕組み。**
## MIME
MIME (Multipurpose Internet Mail Extensions)は、**電子メールの規格を拡張して、漢字や音声、画像などの様々な形式を取り扱えるようにした規格。**
## メールヘッダ
**SMTPでメールを送信する際、メール本文のデータに加えて付加される様々な制御情報。**
| ヘッダ | 概要 |
|:-------:|:--------|
|**From**|メールの送信者|
|**To**|メールの送信者|
|**Cc**|一つのメールを複数に送る場合の宛先|
|**Bcc**|Ccのように同一の内容のメールを送信することができますが、他の送り先にアドレスが表示されないことが特徴|
|**Return-Path**|「戻り道」と訳せるように、正常にメール受信が行えなかった場合などの返送先を示す。|
|**X-Mailer**|メール作成時使用したメールソフトが書かれた情報|
|**Received**|メールがたどってきたサーバの経路情報|
APIのバージョン管理どうしてる？

# はじめに
<!-- 発端や概要を記載 -->
去年までFintechな企業でマイクロサービス化とAPI周りの設計をやっていたのですが、最近他業種でも「APIを始めたいんだよね」と言った声をよく聞くようになってきました。API(WebAPI)自体はもう十分枯れた領域で特別なことはないのですが、今からAPIを始める方のために実際にAPIを作った際の話をまとめてみます。今回は資産管理（バージョニング）についての話から

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [APIのバージョニング](#Chapter2)
1. [参考文献](#reference)

<!-- 各チャプター -->



<a id="#Chapter2"></a>
# APIのバージョニング

APIの役割はシステム間の統合（インテグレーション）にあります。APIを構築したのち、さまざまなサービスからAPIを呼び出していると用件に応じてインターフェースに差異が生まれることがあります。APIの多くは公開し続けながらアップデートを行なっていく必要があり、相手はWebの先にいるため従来のスタンドアロンなシステムのように全体を透過的にリファクタリングするだけでは対応ができないことも多々あります。たとえば

```UserAPI.yaml
paths:
  /user:
    post:
      summary: "顧客情報更新"
      description: "指定されたユーザの情報を更新します"
      parameters:
      - id: "Id"
        name: "名無しさん"
        age: "20"
        address: ""
```
このようなリクエストでAとBとCのサービスから呼ばれていたUserAPIがあるったとして、Cのサービスのアップデートの影響でUserAPIでも電話番号の管理が必要になったとします。Bのサービスのために、UserAPIに以下のように項目を追加してしまうと、AとCのサービスからの問い合わせ時にリクエストパラメータの不足による不整合が生じてしまうかもしれません。

```UserAPI.yaml
paths:
  /user:
    post:
      summary: "顧客情報更新"
      description: "指定されたユーザの情報を更新します"
      parameters:
      - id: "Id"
        name: "名無しさん"
        age: "20"
        address: ""
        tel: "000-0000-0000"
```
ここでバージョン化を検討し始めます。AとBには古いバージョンのAPIを呼び出してもらい、Cには新しいバージョンのAPIを呼び出してもらうことでこの差を解消していこうと考えたりします。RESTfulなAPIだと、たとえば以下のようにバージョニング表記ができます。

1. パスベースでの解決だと一般的にはこんな感じ。
`/user/v1/`
1. もう１つはクエリストリングに追加する。
`/user/?v1`
1. リクエストパラメータにバージョンを追加するようにする。
```yml
parameters:
     ver: 1.1.0
```
など。

この中で個人的に一番勝手が良かったのはクエリストリングに追加する方法でした。一般的にはパスベースが選択されるケースが多いのではないでしょうか。ちなみに最初はリクエストパラメータで管理をしていたのですが、ログを見てもどのバージョンが呼ばれたのかわからず視認性が良くないです。ついでにリクエストは利用側の入力フォームでの制御として呼び出し側の仕掛け（POST前にVerのパラメータを追加するなど）が必要で大変不評でした。パスベースだと設定をミスると呼び出しが成功しないのもマイグレーション時には不便だったりしました。クエリに預けておけばアプリまでは到達してくれるのがポイント高かったです（個人の意見）

バージョンを用意すると今度はプログラム側で分岐判定が発生するので、[クリーンアーキテクチャ](https://blog.tai2.net/the_clean_architecture.html)のようにインターフェースを完全に分離しておく必要があります。しかしインターフェースでバージョンを吸収していると、今度は次第にインターフェースが肥大化してしんどくなります。

上記のような話からAPI設計・実装する際は後方互換を検討しておくのがセオリーですが、私は以下のように対応してみました。

```java
    @RequestMapping(path = "/user", params = "v2", method = RequestMethod.POST)
    public List<String> updateUser(@RequestParam("id") String userId, @RequestParam("tel") String tel) {
        // アプリケーションの本処理へ
    }

    @RequestMapping(path = "/user", params = "v1", method = RequestMethod.POST)
    public List<String> updateUserV1(@RequestParam("id") String userId) {
        // telを擬似的に作成するなどして処理する
        updateUser(userId, tel) 
    }
```
古いAPIからのリクエストを実装側で新しいAPIのリクエストに整形して呼び出すようにして、秘伝のタレみたいに継ぎ足していました。あまり設計上よろしくないのですが、リクエストがなくなった後に古いバージョンのAPIをきれいに捨てられるので管理は非常に楽になりました。

今回は実体験からの話ですので、参考にならない部分も多いのですが、もっと詳しく学びたい方は
「[Web API: The Good Parts](https://www.oreilly.co.jp/books/9784873116860/)」なんかを読んでみるといいのではないでしょうか。



<a id="#reference"></a>
# 参考文献
- [クリーンアーキテクチャ完全に理解した](https://gist.github.com/mpppk/609d592f25cab9312654b39f1b357c60)
- [クリーンアーキテクチャ(The Clean Architecture翻訳)](https://blog.tai2.net/the_clean_architecture.html)
- [Web API: The Good Parts](https://www.oreilly.co.jp/books/9784873116860/)
【Unity】Addressables Asset System について調べる ③

#### 素材を Addressables に登録してビルドする
今回はサンプルとして簡単な構成にする。
いらすとやの素材を使用して、Food, Drink, Music という３つのグループで以下のように画像ファイルをまとめる。
![Addressables_img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/5f493afa-25c3-dd6a-fe74-765e72ab2edd.jpeg)


次にこれらのアセットをAddressableAssetGroupとして登録する。
`Window/Asset Management/Addressables/Groups` を選択するとウィンドウが出てくる。
![スクリーンショット 2022-06-20 15.50.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/07842c4d-d760-f4b1-3300-ca7234e2bdf6.png)


![スクリーンショット 2022-06-20 15.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/1998b64d-519e-d16e-5cec-703492fea531.png)

ここの New を選択し、 `Packed Assets` を選択
![スクリーンショット 2022-06-20 15.49.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/a8f0f670-f331-700f-49f4-22de4d658cfe.png)

`Packed Assets (Default)` というグループが作られる
![Addressables_img_0620_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/7f816cd4-860f-4f0f-0dd1-3da1f4090e46.jpeg)
このグループは **ScriptableObject** として設定されているらしく、
グループを追加すると同時に `Assets/AddressableAssetsData` 以下に `AssetGroups` というフォルダが作られ、そこに作成したグループのアセットが追加される。
![Addressables_img_0620_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/ee29a423-2ecb-21fa-031d-6cb30da32f03.jpeg)
このAddressableAssetGroupにはビルド時のオプションが設定されている。

今回はそれぞれ
・Image_Food
・Image_Drink
・Image_Music
という名前で、以下のようにグループ分けをしてみる。
ファイルを選択してAddressableにチェックを入れる
![Addressables_img_0620_003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/2f061465-116d-57b3-7eeb-fbc11c11db41.jpeg)

もう一度Addressables Groupを確認すると `Packed Assets (Default)`にチェックを入れたアセットが追加されているので、これをドラッグ&ドロップでそれぞれのグループに移動する。
![スクリーンショット 2022-06-20 16.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/3c51ec39-5b0e-023d-dffb-d8ea2620df9c.png)

`Addressables Group`のウィンドウから `Build/New Build/Default Build Script` を使用することでビルドできる。
![スクリーンショット 2022-06-20 16.57.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/634b82ba-4a3d-3b3a-de75-291d3a26d6e4.png)

ビルド結果は `Library/com.unity.addressables/aa` 以下に出力される。
![スクリーンショット 2022-06-20 17.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421285/a5320947-a3c9-4fa2-e04e-47df6fd2c478.png)
ABC256E問題をトポロジカルソートっぽく解いた話

### E問題をトポロジカルソートっぽく解いた話
公式解説のYoutube放送中にコメントで「トポロジカルソートで解いた」と書いたら[snuke](https://atcoder.jp/users/snuke)さんに「どうやって解くんだろ」と言われたので「あれ？あまり一般的な解法ではないのかな」と思ってここで共有させていただきます。Qiitaに解法記事を載せるのは初めてなので、図や文章が読みづらかったらゴメンナサイ。
### 問題を見たときまず考えたこと
[ABC256E](https://atcoder.jp/contests/abc256/tasks/abc256_e)これ見た瞬間に、まず真っ先に頭に浮かんできたのは[ABC223D](https://atcoder.jp/contests/abc223/tasks/abc223_d)だったんですよね。こういう「AさんはBさんより先に」みたいな問題構造はA→Bの有向グラフだと捉えると上手くいくケースが多いです。

実際に今回の問題の入力例２を元にすると、こんな感じの有向グラフが出来上がります。
![スクリーンショット 2022-06-20 16.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2315683/ec01ff5a-22c4-eeee-bdee-10310da652dd.png)


### 具体的にどう解いたか
トポロジカルソートの説明自体は他に優良な記事がいくらでもあると思うので割愛します。上の図で考えると６は入次数が０なので不満度０でキャンディを配ることが出来ます。６にキャンディを配ると次は4の入次数が0になるので4も不満度０でキャンディを配ることが出来ます。ただのトポロジカルソートであればここで終了です。トポロジカルソートの結果がlen([6,4])!=nなので「このグラフはDAGじゃないね」でオワリ。
そうすると残ったのは[1,7]と[2,3,5,8]の有向閉路グラフが残ります。この有向閉路グラフは「誰かに先にキャンディを配ると必ず誰かが不満になる」ということなので、どうせ不満が貯まるならこの閉路のメンバーの中で最も不満度が低い人に不満になってもらおう、そういう方針でコーディングしたらACでした。この「閉路メンバーの中で最も不満度が低い人」を取り出すために、私は優先度付きキューを使用しました。以下が、実際にコンテスト中に提出したコードになります。(コメントを追加しています)
```Python:ABC256E
import heapq
n=int(input())
x=list(map(int,input().split()))
c=list(map(int,input().split()))
in_deg=[0]*n#indegree=入次数のこと
g=[[] for _ in range(n)]
for i in range(n):#0_index派です
    g[i].append(x[i]-1)
    in_deg[x[i]-1]+=1
q=[]
for i in range(n):
    if in_deg[i]==0:
        heapq.heappush(q,(0,c[i],i))#入次数０なら頭に0をつけておく
    else:
        heapq.heappush(q,(1,c[i],i))#入次数>0なら頭に1をつけておく
visit=[False]*n
ans=0
while q:
    ind,point,now=heapq.heappop(q)#入次数0のものから取り出せる。次に不満度が低い順に取り出せる。
    if visit[now]:
        continue
    visit[now]=True
    if ind==0:#入次数が０なら不満度は０
        for to in g[now]:
            if visit[to]:
                continue
            in_deg[to]-=1
            if in_deg[to]==0:#新たに入次数０の頂点が出現したらキューに入れる
                heapq.heappush(q,(0,c[to],to))
    else:#入次数>0なら不満が貯まる
        ans+=point
        for to in g[now]:
            if visit[to]:
                continue
            in_deg[to]-=1
            if in_deg[to]==0:#新たに入次数０の頂点が出現したらキューに入れる
                heapq.heappush(q,(0,c[to],to))
print(ans)
```
Pypyで1600ms程度だったのでまず問題ない速さだと言えるでしょう。

### 余談
提出した後に「これってSCC(強連結成分分解)でも解けるやん」と気付きました。SCCのライブラリ貼っつけて提出したらPypyで300msだったのでこっちのほうが圧倒的に速いですね。また解説放送や公式解説に出て来ましたがUnionFindを使う方法など、もっと効率的なアルゴリズムがたくさんありましたね。
Oracle Analytics Cloud、Oracle Function ハンズオン アソシエー ション分析

OAC6.5から、機械学習や形態素解析などのインターネット上に広く公開されているスクリプトをOracle CloudにOracle Functionsとして登録し、OACから利用する事が可能になりました。当機能の適用範囲が結構広いため、今回Oracle Functionsの機械学習で販売分析を行い、その結果をOACで表示するハンズオンを作成しました。ご参考ください。
ソースコードがここからダウンロード：https://github.com/feixueshu/src
PDF資料がここからダウンロード：https://speakerdeck.com/feixueshu/oracle-analytics-cloud-oracle-function-hanzuon-asosie-siyonfen-xi
![Slide13.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387966/f15ec4fd-e3eb-ed97-057b-c109ef4acb1d.jpeg)
![Slide15.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387966/dd898c80-e066-c6e8-9bbe-7b65d5113d29.jpeg)
![Slide16.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387966/6bdb46b8-3dad-0144-c268-8985f97c825c.jpeg)
![Slide73.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387966/b9328c5e-6000-e8ef-4e70-4ad0764bbe9c.jpeg)
デザイン画像からアプリを作成するPower Apps のExpress Designとは

みなさん、こんにちは。
日本マイクロソフトの向井です。

今回は先日のMS Build 2022 で発表のあったPower Apps の新機能Express Design について紹介します。

# 1. Express Design とは
Express Design はデザインからアプリを作成することができる、Power Appsの新しい機能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/c2d61bd7-c438-b9ca-4814-195dadb456d0.png)

デザインを描いた画像やPDFファイル、外部のサービスであるFigma(アプリのデザインができるサービス）のファイルを読み込んで、Power Appsのキャンバスアプリを作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/102c17ea-ff6c-7b94-c126-82db1a4bcd4a.png)

# 2. Express Design の使用方法
Power Appsのサイトにアクセスすると、アプリの作成方法に新しく画像から作成とFigmaから作成が追加されています。
これらがExpress Designです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/63d2aae4-e3d0-9898-1973-06b6b5d7265a.png)

ここでは画像から作成の方法を簡単にご紹介します。
デザインを描いた画像をアップロードすると、画像のどの部分がテキストラベルでどの部分がボタンなのかAIが判別をしてタグ付けを行います。
タグ付けに間違いがあるときは手動でタグ付けも行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/38aac059-7131-f321-055f-e7ea3fe2c3aa.png)

また、デザインからデータを格納するテーブルを作成することができるのもポイントの一つです。
今まではアプリを作成する前にテーブルを用意しておく必要がありましたが、Express Designでは先にデザインを決めてから必要なテーブルを作成できるので、アプリ開発になれていない方にもさらに使っていただきやすくなったと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/d31e15d0-eb36-fcf4-c556-fe427b3b6eeb.png)

データを入力させる場所をクリックして、そこに入力されたデータをテーブル内の何という列にどのようなデータ型で格納したいかを設定していきます。
たとえば、ここでは「氏名」の欄に入力されたデータを「name」という列にテキスト型で格納するという設定をしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/aea06dd4-561f-b170-7600-53f02629c372.png)

すべての列の設定をすると、作成するテーブルの詳細を確認できます。
デフォルトではアプリ名がテーブル名となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/73594743-80dc-0b33-59f2-3acb48e7bbc5.png)

ここで作成をクリックし、しばらく待つと、テーブルとアプリが作成されます。
テーブルを新規作成する場合は少し（私が試したときは1分30秒ほどでした）時間がかかりますが、テーブルを作成しない場合は瞬時にアプリが作成できます。

あとは、従来のキャンバスアプリの開発手法でアプリを作成していくことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/b928ed7f-27c0-ba1a-5744-e12e5891c194.png)

# 3. まとめ
こちらの記事でご紹介したExpress Design で画像からアプリを作成する方法はMS Build の日本語セッションでも紹介しています。
動画ベースで確認したい方はこちらをご覧ください。
[進化が止まらないローコード開発最前線！日本市場 最新情報アップデート](https://mybuild.microsoft.com/en-US/sessions/e62f0470-f817-4cf5-9591-8ef1f811f563?source=/home)
(18:25~ Express Designの説明をしています）
React学習に付随する疑問点等まとめ

# はじめに
React超初級者が学習しながら気になったことや発生した問題、思考を書くだけ。

ちなみに下記の書籍で学習中。
[モダンJavaScriptの基本から始める　React実践の教科書　（最新ReactHooks対応版）](https://www.amazon.co.jp/gp/product/B09BV2HGN3/ref=ppx_yo_dt_b_d_asin_title_o02?ie=UTF8&psc=1)

## npm, npxの違い
Node.jsに触れるのも始めてゆえなんじゃいこれはとなった。

- npm: Node Package Manager
Node Packageを管理(manage)するコマンド  
install, startなど
- npx: Node Package Executer
Node Packageを実行(execute)するコマンド
create-react-appなど

package.jsonに定義されていればnpm、されていなければnpxで実行ってくらいの理解だけど、
調べるほど沼が深そうなので一旦これくらいにする。

## Reactのプロジェクトを始めるために必要なこと
### プロジェクトの作成
```
$ npx create-react-app [任意のプロジェクト名]
$ cd [任意のプロジェクト名]
$ npm start
```

### 注意事項
- src配下には【index.js】が必須

## パッケージの最新版を信用してはいけないのか……？
- styled-componentsやEmotionを利用しようとしたが挙動がおかしい
    - コンパイルは正常に実行されるが画面にレンダリングされない（＝画面が白飛びする）
    - コンソールに大量にエラー
        - The above error occurred in the < ～ > component

### 解決
バージョンが原因だった。
「npm install styled-components」で最新版をインストールしていたが、
一度削除し「styled-components@4.3.2」をインストールすることで無事に表示された。
Emotionも同様に、最新版を削除し安定版(11.8.2)をインストールした。

- バージョン確認に使ったコマンド
    - npm info [パッケージ名] versions

## EmotionとStorybookが競合する？
Storybookの記述があったためお試しでインストールしてみるとEmotionコンポーネント使用時に下記のエラーが発生した。
```
Module not found: Error: Can't resolve '@emotion/core' in '～'
```

### 解決
「@emotion/core」なるパッケージが削除されたのか？と思いインストールしてみたところ解消した。原因はStorybookインストール時にファイルが削除されたこと……？

## 「npm install @craco/craco」実行時にエラーが発生する
Tailwind CSSの項目で必要になったCRACOのインストールコマンドを実行すると下記のエラーが発生した。
```
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: practice@0.1.0
npm ERR! Found: react-scripts@5.0.1
npm ERR! node_modules/react-scripts
npm ERR!   react-scripts@"^5.0.1" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react-scripts@"^4.0.0" from @craco/craco@6.4.3
npm ERR! node_modules/@craco/craco
npm ERR!   @craco/craco@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\[ユーザー名]\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\[ユーザー名]\AppData\Local\npm-cache\_logs\2022-05-29T12_19_13_400Z-debug-0.log
```

色々試したが動作する見通しが立たなかったため、Tailwind CSSの学習は保留とする。
（メインは「Reactを学習すること」としているため）

## 今後は・・・
- Next.jsに取り組みつつサイト構築
- Storybookの理解

## 参考
- [npmとnpx。なにが違う？](https://qiita.com/sivertigo/items/622550c5d8ec991e59a6)
- [npmとnpxの違いを理解して使い分けられるようになろう](https://www.investor-daiki.com/it/npm-npx-difference)
- [Invalid hook call error when I use my own library from styled-components](https://github.com/styled-components/styled-components/issues/3187)
Windows上でEmacsからripgrepを日本語で動作させる

# どういうこと?
WindowsでEmacsとripgrepを組み合わせて使いたいとします。
このとき、Emacsでは `(prefer-coding-system 'utf-8-unix)` と設定しています。
また `rg` へのパスは通しているものとします。

この状態でEmacsから `ripgrep-regexp` や `consult-ripgrep` など、`rg` コマンドで日本語を含んだ検索をしようとしても、うまく動作しません。 

# どうして?
Windowsのプロセスはcp932で受けとるからです。

# どうした?
対象の関数のときだけで `coding-system-for-write` を切り替えると動作しました。
例えば `consult-ripgrep` なら
```elisp
(defun advice:with-cp932 (orig-fun &rest args)
  (setq coding-system-for-write 'cp932)
  (apply orig-fun args)
  (setq coding-system-for-write 'utf-8-unix)) ; 使っているcoding-systemに戻す
(advice-add 'consult-ripgrep :around 'advice:with-cp932)
```
とすれば動作しました。

なお、`consult-ripgrep`中に `C-g` すると、 `coding-system-for-write` が `cp932` のままになります。とりあえず、
```elisp
(add-hook 'before-save-hook (lambda () (setq coding-system-for-write 'utf-8-unix)))
```
として、むりやり `coding-system-for-write` を戻しています。
うまいやりかたを知っていたら教えてください。
【Udemyで勉強】テスト駆動開発とドメイン駆動開発

テスト駆動開発と、ドメイン駆動開発について、
Udemy動画で勉強した時のメモ。

### 見た動画
https://www.udemy.com/course/domain-1/

### テスト駆動開発
とにかく、テストコードが先、（実際の実装）コードが後。
しつこくしつこく、「まずテスト書いて～」。
テスト書き終わったら、実装のためのコードを書く、テスト実行する、（そして、エラーや足りない部分を直す・加える）の繰り返し。

### ドメイン駆動開発
「プログラムから複雑さを取り除くための手法。オブジェクト指向やデザインパターンは単発で紹介されることが多いけど、実際にアプリケーションを開発する際に、どういうクラスをどういうフォルダに入れて～とかは解説されていない事が多い」とのことで、
この機能を持つクラスはこのフォルダに入れて～とか、パターン化されている。
(Domain、Infrastructure、Viewの３つにフォルダ分けする。Domainにはビジネスロジックのクラスを入れる。InfrastructureにはDB（SQLiteやSQL Serverなど）との接続用クラスを書く。また1つのViewにつき、対応するViewModelを1つ作る、など）
あと、ValueObject（値として扱うクラス。値とロジックをなるべく一体化させて散らばらないようにする）とかも学んだ。