OmniAICreator/Qiita-1.07M huggingface dataset:
Arch Linux on WSL2 で Electron アプリをビルド・実行する

# まえがき

[WSLg](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps) が凄すぎてあっさりとできてしまったのですが、一応、手順を書き残しておこうと思います。

# 環境

- Windows 11 Home (21H2)
- [Arch Linux on Windows](https://github.com/yuk7/ArchWSL)
    - 日本語環境 構築済み

# 手順

## 1. 依存関係を解決

結果として、以下のパッケージをインストールすることで解決できました。

```sh
yay -S nss atk at-spi2-atk libcups gtk3
```

<details><summary>作業ログ</summary><div>

### libnss3.so

```sh
yay -S nss
```

### libatk-1.0.so.0

```sh
yay -S atk
```

### libatk-bridge-2.0.so.0

```sh
yay -S at-spi2-atk
```

### libcups.so.2

```sh
yay -S libcups
```

###  libgtk-3.so.0

```sh
yay -S gtk3
```

</div></details>

## 2. 日本語フォントをインストール

何でもいいのですが、個人的に読みやすいなと感じたので [IPAexフォント](https://forest.watch.impress.co.jp/library/software/ipaexfont/) を選びました。
既に何らかの日本語フォントを導入済みであれば、この手順を踏む必要はありません。

```sh
yay -S otf-ipaexfont
```

# エラーが出力されつづける

起動中、コンソールに `Failed to connect to the bus: Could not parse server address` というエラーが出力され続けるのですが、これについては原因が分かりませんでした。

WSL のリポジトリに issue が上がっていたので、様子を見たいと思います…。

https://github.com/microsoft/WSL/issues/7915

# あとがき

![seri.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286055/9a99bc06-c138-c8c7-d085-6ae5d108ac44.gif)

Win10 の WSL2 で同じことをしようとして手こずった記憶があるので、特に大きな不具合もなくスッと動いたことに感動しました。

音声もしっかり出ているので、かなり実用的と言えるのではないでしょうか……😺

# 参考

- [WSL で Linux GUI アプリを実行する | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps)
ど素人でもわかる css 横並べ

横に並べたい "だけ" なのに。

floatは論外。
flexを使うと回り込みが複雑になる。
よってtable-cellで。

全部コピペすりゃ動く。
あとは、自分で変更してね。


完成品

![hoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/5bbd277d-769e-9515-3032-e625d9660b21.png)


```hoge.html

<div style="display: table;width: 100%;">
    
    <div style="background-color:red;display: table-cell;width: 20%;vertical-align: middle;">
        赤を真ん中に
    </div>
    <div style="background-color:yellow;display: table-cell;width: 80%;">
        
        <div style="display: table;width: 100%;">
            <div style="background-color:pink;display: table-cell;width: 20%;">
                ぴんく
            </div>
            <div style="background-color:blue;display: table-cell;width: 80%;">
                ぶるー
            </div>
        </div>

        <div style="width: 100%;">
            これは、ぴんくとブルーのした
        </div>
    </div>
</div>

<hr/>

<div style="display: table;width: 100%;">

    <div style="background-color:red;display: table-cell;width: 20%;">
        赤
    </div>
    <div style="background-color:yellow;display: table-cell;width: 80%;">
        黄
    </div>
    
</div>



```
Next.jsでMaterial UIとTailwind CSSとStorybookを併用する時のメモ

Material UIとTailwind CSSは事前に導入されている前提です。
StorybookとTailwind CSSを併用する場合、ちょっと設定が必要なのでメモ

Storybookに@storybook/addon-postcssを導入しないとyarn storybook実行時にエラーがでてしまいます。
StorybookとTailwindでPostCSSが競合？してしまうことが原因みたいです。(よくわかっていない)

```
addon-postcssを導入
yarn add -D @storybook/addon-postcss
```

```.storybook/main.js
module.exports = {
  addons: [
    // 追加
    {
      name: '@storybook/addon-postcss',
      options: {
        postcssLoaderOptions: {
          implementation: require('postcss'),
        },
      },
    },
  ],
};
```

Material UIのコンポーネントにclassName属性にTailwind CSSのクラスを指定すると、既存のスタイルを上書きします。
```tailwind.config.js
module.exports = {
  variants: {
    extend: {},
  },
  plugins: [],
+ important: true, //追加
}
```

```test.tsx
<Button variant="contained" className="bg-blue-500 hover:cursor-pointer hover:bg-blue-600"></Button>
```

StorybookもでTailwindのスタイルが反映するようにする
```.storybook/preview.js
// 追加
import '../styles/globals.css';
```
```globals.css
@tailwind base; // 追加
@tailwind components; // 追加
@tailwind utilities; // 追加
```
PHP初心者は必ず見ろ！　PHPの書き方(初心者向け)

# はじめに
PHPの基本をこの記事で書いていきます。
PHPの初学者の方向けの記事です。実際にコードを書いたりして
実際の挙動などを確認してみてください。

# 環境
```MAMP```をインストールします。
エディタはVScodeです。

# 環境構築方法
MAMPの環境構築が動画でわかりやすく載っていました。
PHPで出力する時はMAMPで出力するのでこちらを確認してください。

https://www.youtube.com/watch?v=I9xgwLfNnD4&list=PLErg7aSNT21xAVbJAEWS1oxgGLL__ySK2


# PHPの書き方

### 1. 基本的な書き方

```index.php
<?php 
   処理を書く
      ?>
```
```<?php 　~~~?>```の<? ?>の間に処理を書いていきます。この間でPHPの処理が走るので、
<? ?>の外に書くとPHPとして処理されません。

***?>は省略することができます***。そうすると<? php から下は全部PHPの処理になります。

⚫︎補足
ファイル名は```.php```になります。


### 2. 出力方法
PHPの出力方法は以下の通り```echo```と```print```が使えます。

```sample.php
<?php  
echo "PHP入門";
```

```sample.php
<?php  
print "PHP楽しい";
```
出力する時はブラウザのURLに
```http://localhost/sample.php```か```http://127.0.0.1/sample.php```
を記載して出力します。(sample.phpはファイル名)
フォルダ名を入れる時は(127.0.0.1/フォルダ名/sample.php)
みたいにして出力する場合もあります。わかりづらい場合は上の動画をご覧ください。


もしこのように書いた時に

```sample.php
<?php  
echo "PHP入門";
echo "PHP楽しい";
echo "エンジニアになるぞ";
?>
```
このような出力になります。

```
PHP入門PHP楽しいエンジニアになるぞ
```
と出力されます。


上のように改行されていない状態での出力となります。

```php
<?php  
echo "PHP入門";
echo "<br>";
echo "PHP楽しい";
echo "<br>";
echo "エンジニアになるぞ";
```
のように書くと改行されます。
もしくは
```php
<?php  
echo "PHP入門"."<br>";
echo "PHP楽しい"."<br>";
echo "エンジニアになるぞ";
?>
```
で出力すると
```
PHP入門
PHP楽しい
エンジニアになるぞ
```
これで綺麗に改行されました。


#### PHPを書くときの注意
***行の終わりには;(セミコロン)をつける必要***があります。
ない場合エラーになってしまいます。

### 3. PHPのバージョン確認
PHPのバージョンを確認する場合は```phpinfo();```を書きます。

```php
<?php  
phpinfo();
?>
```
今回のバージョンは7.4.21です。

![スクリーンショット 2022-03-31 1.32.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/a3a83f23-1ba1-6e36-7d77-7d8531989048.png)

### 4HTMLにPHPを組み込む
PHPはHTMLに組み込んで書くことができます。

```php
<!DOCTYPE html>

<head>
</head>

HTMLで書いた

<?php  
echo "PHPで書いた"
?>

</body>
</html>
```
これで
```
HTMLで書いた PHPで書いた
```
と出力されます。


# 基本的のルール

```php
<?php
echo('PHP');
echo("PHP");
//PHP  コメント

/*
PHP
Laravel
AWS */   //複数業コメント


?>
```
1.文字は```半角```
2.数字は```半角``` 。***全角だと文字認識***
3.コメントは```//(スラッシュ)```です。
4.***複数行のコメントは/*と*/***を使います。
5.()は使ってもいいし、使わなくてもいい
6.```シングルクオテーション''```と```ダブルクオテーション""```はどちらを使ってもいい

# 最後に
この記事は本当に初歩的なことしか投稿していないです。
配列や条件分岐、変数、関数などは別の記事でお願いします。


# 参考資料
https://qiita.com/mackeyTA/items/069900b5c2366fb30e3a
UbuntuでCMakeのversionを変更

## 環境
- Ubuntu18.04
- ROS環境が構築済み

## 経緯
ビルド中にCUDA系のエラーが発生。
↓出くわしたエラー
`Error NOTFOUND: CUDA_cublas_device_LIBRARY (ADVANCED)`
この場合CUDA10.0に対して、CMakeのバージョンが3.12.2以上が必要であることが明らかに。

このように、CMakeのバージョンが使用するパッケージに対応しないことは時々起きるので、既存のCMakeを変更することに。

## 既存のCMakeバージョン確認
```
$ cmake --version
```
<font color=red>注意：最初にCMakeを消去するようなコマンドを入力するとROSが壊れるので、やらないでください。</font>
## CMakeダウンロード
① 下記サイトから特定のバージョンのCMakeを選択してダウンロードします。
- <a href=https://cmake.org/files/>CMakeダウンロード</a>

例えば、CMakeのバージョンを3.15.5でダウンロードする場合、v3.15/を選択し、
次のページの一覧から`cmake-3.15.5-Linux-x86_64.tar.gz`を選択します。
末尾に`Linux-x86_64.tar.gz`がついたものを選択すると良いです。

② ダウンロードできたら`~~.gz`を解凍します。

③解凍先のディレクトリに移動し、以下を行います。（以降バージョンを自分用に書き換えてください。）
```
$ cd (解凍先のディレクトリ)
$ sudo mv cmake-3.15.5-Linux-x86_64 /opt 
$ sudo ln -s /opt/cmake-3.15.5-Linux-x86_64/bin/* /usr/bin
```
※LinuxのLが小文字になっている場合があるので注意

④ `.bashrc`の内容を任意のエディターで追加、または変更します。 
```
$ gedit ~/.bashrc
```
⑤ 開いたら以下を末尾に追加します。すでに他のバージョンが記述されている場合は書き換えます。
```
export PATH=/opt/cmake-3.15.5-Linux-x86_64/bin:$PATH
export CMAKE_PREFIX_PATH=/opt/cmake-3.15.5-Linux-x86_64:$CMAKE_PREFIX_PATH
```

## 変更後のCMakeバージョン確認
一旦コマンドを立ち上げなおしてください。下記のように表示されたらOKです。
```
$ cmake --version
cmake version 3.15.5

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```
Pythonで「Hello World」を表示

## やること

まっさらな状態からcurlを叩いて「Hello World!」を表示する

## 仮想環境

・・・一時的に作成する実行環境

- プロジェクト直下に仮想環境をvenvとして作成しておく
※ライブラリをvenvディレクトリで管理できるようになる
`python3 -m venv venv`

- 仮想環境に移動
`source venv/bin/activate`
または
`. venv/bin/activate`

- 仮想環境の終了
`deactivate`

## VSCodeで設定
毎回、仮想環境に移動することがめんどくさいので、VSCodeで`f1`をクリック
`Python：インタープリターを選択`が出てくるので、`venv`がいる階層のpathを入れると毎回入ってくれる！

## ファイル　

requirements.txt

    flask

app.py

    from flask import Flask

    app = Flask(__name__)

    @app.route("/")
    def test():
        return "Hello World!"

#### ライブラリのインストール
`pip install -r requirements.txt`

#### 別のインストール方法
- Flaskのインストール
`pip install flask`

- Flaskが入っているか確認
`pip freeze`



1. ターミナルで`flask run`を実行すると、`Running on　http://....`と表示される
1. 別のターミナルで`curl http://....`を実行して、「Hello World!」が表示されればOK！

return文の下に

    if __name__ == "__main__":
        app.run(debug=False, host='0.0.0.0', port= 8080)
上記文を追加すると`python3 app.py`を実行でサーバーが立ち上がる(ポート8080)

    if __name__ == "__main__":
        app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
(デプロイする時エラーが出るので、上記に変更)

こちらも同様に
1. ターミナルで`python3 app.py`を実行すると、`Running on　http://....8080`と表示される
1. 別のターミナルで`curl http://localhost:8080`を実行して、「Hello World!」が表示されればOK！

## 確認しながら開発
今回、デバックを行っていないが、コードの左に`ブレークポイント`があるので設定し、実行 > デバックの開始を行うと確認しながら開発ができる。

## 最後に
この記事が環境構築と呼べるかわからないですが、curlを叩いて「Hello World!」を表示することができました。
JSにはない仮想環境、初めてPythonを触って理解するには時間がかかりそうです。
新たな発見があれば、更新していきます。

## 参考文献

https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e

https://flask.palletsprojects.com/en/2.1.x/quickstart/
[Azure x IoT] Azure IoTHub クックブック.とりあえず何か作ってみたい人必読!!

# はじめに
「IoT興味あるしAzureIoTHubでとりあえず何か作りたいけどあんまり情報ないな。。」という方向けに、興味度合い・目的に応じてつまみ食いの度合いを選べるように自分の過去記事を分類してみました。
ちょっと触ってみたいだけの方は"メッセージ送信"だけ覗くもよし、ガッツリプロダクトで触りたい方はDB連携、リアルタイム通知なども覗いてみてください。
Terraformも用意してある記事もあるのでUI操作がめんどくさい方にはおすすめです。

自分が構築した際は日本語の情報がAWSほど豊富にはなくそこそこ構築に苦労したのでこの記事で少しでも他の方のお役に立てれば！と思います。
※本記事は筆者のIoTHubの応用範囲が増えるたびに更新予定です。

# IoTHubにメッセージを送りたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/e96bc129-5462-4429-d279-009dc7f48b2b.png)


[[Azure x IoT]Azure IoTHubにメッセージを送ろう](https://qiita.com/iron-samurai/items/3015971f15a20ccf954c)

# IoTHubとAzureFunctionを連携したい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/6e62ede9-b448-cf45-f882-2ffee94b60c7.png)


[[Azure x IoT]Azure IoTHub とAzure Functionsを連携しよう](https://qiita.com/iron-samurai/items/d5015f4bb18609f71aaa)

Terraformでサクッと構築したい人はこちら

[[Azure x IoT] AzureIoTHubとAzureFunctionを連携しよう(Terraform編)](https://qiita.com/iron-samurai/items/b1d52ffc420b0189839d)

# IoTHubで受信したメッセージをDBに入れたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/0fcef62f-9fbf-c334-40d8-b5b5c87a8d2c.png)


[[Azure x IoT] Azure IoTHubで受け取ったメッセージをDBに保存しよう](https://qiita.com/iron-samurai/items/efb422e75e43c3414e51)

Terraformでサクッと構築したい人はこちら

[[Azure x IoT] Azure IoTHubで受け取ったメッセージをDBに保存しよう[Terraform編]](https://qiita.com/iron-samurai/items/566a429e5f5f49ca7ac8)

関連記事

[[Azure] Azure FunctionsからVnet内のRDBを操作する](https://qiita.com/iron-samurai/items/b86777889df16829775d)

[[Azure] Azure FunctionsからAzure Key Vaultの値を参照する](https://qiita.com/iron-samurai/items/0ca65cf7262111bc62a0)

# IoTHubで受信したメッセージをリアルタイムにクライアントに通知したい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/738a0626-7b43-d076-742a-eaf6f055446c.png)


[[Azure x IoT] IoTHubで受け取ったメッセージをリアルタイムにクライアントに通知しよう](https://qiita.com/iron-samurai/items/ab07c68803f514b48a19)

Terraformでサクッと構築したい人はこちら

[Azure x IoT] IoTHubで受け取ったメッセージをリアルタイムにクライアントに通知しよう[Terraform編]WIP

関連記事

[[Azure] AzureでSingalRを使ってリアルタイム通知を行う](https://qiita.com/iron-samurai/items/2fa7fb950c7aac94f64a)

# その他Azure記事
[[Azure] Azure Resource Manager と Terraform どちらがいいのか調べてみた](https://qiita.com/iron-samurai/items/376d51a6431c94ebdf90)
Pythonの組み込みhash関数を使ってバグを作った話

# 経緯と問題

DynamoDB で効率よいシャーディングの実施のために、キーの末尾に特定の識別子を付与する方法はベストプラクティスとして公式でも紹介されている。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-partition-key-sharding.html#bp-partition-key-sharding-calculated

今回は、このシャーディングを行うためにユーザー固有のID (文字列) を元に識別子を計算したいと考えた。 その対策として、以下のようなコードを書いた。

```python:バグありなのでこのコードは利用しないこと！
def primary_key(uid: str) -> str:
    num = hash(uid) % 10
    return f'SampleData.{num:02d}'
```

[`hash` 関数](https://docs.python.org/ja/3/library/functions.html#hash) は Python の組み込み関数であり、整数を返す。
実際にこれでテストをすると、同じ `uid` の入力に対して、同じ結果を返してくれるため、一見正しそうに見える。

しかし、このプログラムを AWS Lambda 上で動かしたところ、**同じ `uid` を使っているにも関わらず、異なる値が出力されることがあった。** 例えば、`primary_key('ABC')` に対して、`SampleData.00` と返すこともあれば、`SampleData.02` を返すこともある、ということである。


# 原因

例えば以下で説明されている。 Python3.2 以前は実は同じ値が返っていたようだが、Python3.3 以降はデフォルトでは実行環境が変わると異なる値が返るようになっている。

https://stackoverflow.com/questions/27522626/hash-function-in-python-3-3-returns-different-results-between-sessions

[Python の データモデルのドキュメント](https://docs.python.org/ja/3/reference/datamodel.html) に以下の様な記載がある。

> 注釈 デフォルトでは、文字列とバイト列の __hash__() 値は予測不可能なランダム値で "ソルト" されます。 **ハッシュ値は単独の Python プロセス内では定数であり続けますが、Python を繰り返し起動する毎に、予測できなくなります。**
この目的は、慎重に選ばれた入力で辞書挿入の最悪性能 O(n^2) 計算量を悪用することで引き起こされるサービス妨害 (denial-of-service, DoS) に対する保護です。 詳細は http://www.ocert.org/advisories/ocert-2011-003.html を参照してください。
> 
> ハッシュ値の変更は、集合のイテレーション順序に影響します。Python はこの順序付けを保証していません (そして通常 32-bit と 64-bit の間でも異なります)。
> 
> バージョン 3.3 で変更: ハッシュのランダム化がデフォルトで有効になりました。
> 
> 引用 (一部強調) - https://docs.python.org/ja/3/reference/datamodel.html#object.__hash__

AWS Lambda では実行系（コンテナ）の個数は自動的に起動／停止されて管理されるため、`hash` の結果は環境ごとに異なり、結果として同一の値を返さないという問題が発生していた。


# 対処方法

`hash` ではなく `hashlib` を使って入力が同じなら同じ出力を得るようにする。
以下は異なる Python の対話環境を立ち上げて処理した一例だが、`hashlib` を使う場合は同一の整数が得られており、組み込みの `hash` 関数を用いた場合は異なる値が得られていることが分かる。

```bash
$ python
>>> import hashlib
>>> uid = 'ABC'
>>> int(hashlib.sha256(uid.encode()).hexdigest(), 16)
82243227265268364450164513578198692919354401419942992332018465930427597709176
>>> hash(uid)
-6783415564974188218
```

```bash
$ python
>>> import hashlib
>>> uid = 'ABC'
>>> int(hashlib.sha256(uid.encode()).hexdigest(), 16)
82243227265268364450164513578198692919354401419942992332018465930427597709176
>>> hash(uid)
6230289585255038598
```

テスト用のハッシュ算出には sha256 を用いたが、DynamoDB で用いる場合には簡単な計算で良いと書いてあるため、MD5 でも十分だとは思う。 

```python:修正版
import hashlib
def primary_key(uid: str) -> str:
    num = int(hashlib.md5(uid.encode()).hexdigest(), 16) % 10
    return f'SampleData.{num:02d}'
```
アジャイル検定合格しました！：市場価値を飛躍的に向上させるエンジニアの革新

# 試験結果
スコア：83
![Prometric_Report.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/853c974e-ed74-5c08-d478-033662468e7c.png)


# アジャイル検定
http://agilecert.org/

# アジャイルとは？
アジャイルは、ソフトウェア開発におけるフレームワークで、柔軟性と反応性を重視しています。主な特徴としては、短いスプリント、定期的なフィードバック、継続的な改善などがあります。アジャイルを導入することで、チームの生産性とプロジェクトの成功率が向上することが多いです。

# アジャイル検定Lv1とは？
アジャイル検定Lv1は、アジャイルの基本概念と実践方法を理解していることを証明する資格です。試験はオンラインで行われ、選択問題形式です。以下のトピックが含まれています。

* アジャイルの基本原則
* スクラムとカンバン
* スプリントプランニングとデイリースクラム
* バックログ管理とインクリメントの定義

# 学習方法
「アジャイル検定公式テキスト」の１冊のみです。（読書２周）

https://booklive.jp/product/index/title_id/20022448/vol_no/001

# 次のステップ
アジャイル検定Lv1を取得したことで、アジャイルの基本的な知識と実践方法をより深く理解することができました。今後は、チームのアジャイルプロセスを改善していきたいと思います。
eclipseにおける「クリーン」とは

	■まとめるきっかけ
	
	・原因不明のエラーで悩まされて、サーバーをクリーンすると解決したという場面が何度かあり、真剣にクリーンの機能について調べ、利用するタイミングを確認しておきたい。
	
	■ここでまとめる機能
	・プロジェクトのクリーン
	・サーバーのクリーン
	・リフレッシュ
	
	それぞれの概要と、実行タイミングを記載する。
	
	■プロジェクトのクリーン
		"全て"のビルド成果物を削除し、
		"全て"のモジュールをビルドしなおすこと。
		
		一部モジュールを修正した際に、自動でビルドが行われるが、あれは修正した箇所のみをビルドしなおしている。
		クリーンビルドは、一旦ビルドによって、作成されたクラスファイルなどのファイルを削除し、全てのモジュールをビルドしなおす。
		
		●実行タイミング
		サーバーで実行する前には一度は行うべき、依存関係にあるモジュールを特定することは難しいため。
	
	■リフレッシュ
		Eclipse外で中身を変更した時、それをEclipse内に反映させたい時などに使う。
		ビルドは行っていない。
		
		●実行タイミング
		エクスプローラーなどで、ワークスペース内のモジュールを触ったときなど
		(サーバー実行前に行ってもあまり意味がない。)
		
	■サーバーのクリーン(※仮)
		サーバー上の
		"全て"のビルド成果物を削除し、
		新しくビルドしなおしたモジュールをデプロイすること。
		(「プロジェクトのクリーン」とやっていることは似ているが、厳密には、ワークスペースでのクリーンか、サーバー上のクリーンかというクリーン対象環境が違う)
		
		●実行タイミング
		サーバーで実行する前には一度は行うべき。
【Laravelエラー】Cannot drop table '' referenced by a foreign key constraint

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 状況
usersテーブルを```php artisan migrate:rollback```したときのエラー。

```
Cannot drop table 'users' referenced by a foreign key constraint 'posts_user_id_foreign' on table 'posts'. (SQL: drop table if exists `users`)
```

## 原因
usersテーブルに```post_id```が外部キーとして設定されており、postsテーブルよりusersテーブルを先に```rollback```しようとしたため。

## 解決法
migrationファイルで外部キーを削除する。

```php
public function down()
{
  Schema::table('posts', function (Blueprint $table) {
     $table->dropForeign('posts_user_id_foreign');
  });
}
```
再度```php artisan migrate:rollback```でrollback!
Node.js: Elastic Cloud の filters の使い方

こちらと同じことを Node.js で記述しました。
[Elastic Cloud の filters の使い方](https://qiita.com/ekzemplaro/items/1ab696e2d230a59b548d)

```elastic_filter.js
// ---------------------------------------------------------------
//	elastic_filter.js
//
//					Apr/01/2022
//
// ---------------------------------------------------------------
'use strict'

import * as https from "https"
import * as fs from 'fs'

const host="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
const search_key="search-******"
const name_engine="national-parks-demo"
const json_query="query01.json"

console.error ("*** 開始 ***")

const json_str = fs.readFileSync (json_query,'utf8')

const url=host + "/api/as/v1/engines/" + name_engine + "/search"

const options = {
	method: "POST",
	headers: {
		"Content-Type": "application/json",
		"Content-Length": json_str.length,
		"Authorization": "Bearer " + search_key
		}
	}


const request = https.request(url, options, response => {
	console.error(`statusCode: ${response.statusCode}`)
	response.on('data', (dd) => {
		process.stdout.write(dd)
		})
	console.error ("*** 終了 ***")
	})

request.write(json_str)
request.end()

// ---------------------------------------------------------------
```

```json:query01.json
{
  "query": "",
  "filters" : { "states": [ "Texas", "Minnesota" ] }
}
```

```json:package.json
{
  "type": "module"
}
```

実行コマンド

```bash
node ./elastic_filter.js | jq .results[].states.raw
```

実行結果

```text
$ node ./elastic_filter.js | jq .results[].states.raw
*** 開始 ***
statusCode: 200
*** 終了 ***
[
  "Texas"
]
[
  "Minnesota"
]
[
  "Texas"
]
```

次のバージョンで確認しました。

```text
$ node --version
v17.8.0
```
『ゼロから作るDeep Learning』ひとり購読会 #01

（#01って、二桁で読み終われるのだろうか…。）

大変よろしくないことに仕事が停滞してしまっているので、すき間時間を使って『[ゼロから学ぶDeep Learning](https://www.oreilly.co.jp/books/9784873117584/)』の勉強を始めました。私は何ごとに付け基本がなっていないし、機械学習をまともに学習したこともないので、最も基本となるところはここかなと本書に手を出した次第です。

＃まあ、QIITAでリンクを貼る必要はないかもしれないですけどね

とりあえず今日は1章をさらさらっと。Python自体はすでにインストールしてあって、VS Codeも使えるようにはしてある程度の経験者なので、NumPyのところ以外は復習という感じもありました。

NumPyはまったく初めてではないですが、今まで読んだ書籍で紹介されていたサンプルプログラムに出てきたくらい。そこでの解説を読めば「なるほど」とは思いますが、あんまり理解できた感じはしない。ましてやNumPyを使ったコードなど書けません。そもそも、NumPyが必要なプログラムを着想することもできなさそうという感じ。

＃と書いた先から「あそこで使えるのかも」と思ったところがあったりなかったり

さて、今日読んだ中から覚えておきたいところを先々の自分向けにまとめてみました。

### ブロードキャストによる配列計算
行列の計算は文系出身者としては頭の痛いところです。かなりのおじさんなので高校時代に確かに行列は教わりました。「ややこしいよね」という印象だけが残っている感じ。

ただ、NumPyの配列クラスは同じ位置の要素同士で演算する（という認識で正しいかはちょっと自信ないけど）ので、「どことどこをかけ算して、それをあっちのかけ算とたし算して…」は不要なところにはちょっとホッとできる。それだけに要素数の異なる配列の演算になると「？？？」と急にフリーズしてしまっていたのです。

でも、本書のブロードキャストの解説はものすごく腑に落ちました。

~~~p.14のコード
>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([10, 20])
>>> A * B
~~~
というコードだと、
```
array([[ 10, 40],
       [ 30, 80]])
```
という結果になりますが、これはNumPyの側で自動的に
```
>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([[10, 20], [10, 20]]) # 後ろの[10, 20]を補完
>>> A * B
array([[10, 40],
       [30, 80]])
```
と抜けている分の要素を補完して計算してくれるということなんですね。これは何かものすごく「演算のコードをどう書けばいいか」がよくわかった気になれました。

### 要素へのアクセス
解説でも基本的には通常のリストのように記述するとあったので、まあまあ理解していることをおさえ直したという感じです。

ところが！ `flatten`には「おおっ！」となりました。

```p.15のコード（抜粋）
>>> X = np.array([[51, 55], [14, 19], [0, 4]])
>>> X = X.flatten()
>>> print(X)
[51 55 14 19  0  4]
```

配列が苦手な私としては何かこうしちゃったほうがわかりやすいかも、と思える場面もありそうで、こんな簡単にフラットにできちゃうメソッドが用意されているなんて！と感激した次第です。

それと、
```p.15のコード（下のほう）
>>> X[np.array([0, 2, 4])]
array([51, 14,  0])
```
配列から要素を離散的に呼び出すことができるというのも初めて知りました。入門書では`list[1:3]`的な解説がほとんどなので、連続してるところしか取り出せないのかと思っていました。これ、使いでありそう。さらに、
```p.16のコード
>>> X[X>15]
array([51, 55, 19])
```
も、知っていたら活用できそうな感じがしました。

### ［雑］plt.legend――レジェンド？
今までの写経ではあまり気に留めていなかったのですが、matplotlibでグラフを描画する際、`plt.legend`という行があるのに引っかかりました。p.17の「1.6.2 pyplotの機能」で紹介されているコードの文脈からすると、「軸ラベルとかタイトルを設定したので、それを表示する要素として扱ってね」というのが`plt.legend`の意味なんだろうなあとは思いました。実際、matplotlibの解説記事を検索すると「タイトルや凡例などのこと」と説明されていることが多いです。

逆にmatplotlibの公式ドキュメントには
> Place a legend on the Axes. 

とあるので（[matplotlib.pyplot.legend](https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.pyplot.legend.html#matplotlib-pyplot-legend)</a>）、各軸に配置するものがlegendなのだなあと。

プログラミング的にはそこで疑問が晴れたのでいいんですが、伝説と見出しといったように日本語では同じ方向を向いていないように見えても、言葉として同じなんだったら語源が同じなんだからどこかに通じるところがあるはずだよなあと。なので、語学的にちょっと調べてみました。

すると、

> 「レジェンド」の語源はラテン語の “legenda” です。
>
> legenda はラテン語の直訳で「読まれるべき」という意味の言葉です。


という解説（[レジェンド」の意味とは？使い方から英語までわかりやすく解説](https://gimon-sukkiri.jp/legend/)）を見て、納得しました。伝説もグラフの凡例や見出しも「読んでおくべきもの」として通底するものがあるというわけですね。

まとめられるほどの勉強はしていないので、今回はメモ代わり。本文にも
> 本章は、ディープラーニングの下準備のページです。

とある通り、まったく本論に入っていないのにちょいちょい気付きがあって、この先スムーズに学びが進むのかなあととても心配になったエイプリルフールなのでした（本記事の内容はまったくうそ偽りはございません）。
S3からherokuにデータリストアメモ

パケットを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/70542284-d95f-09a2-a8f7-79925b720379.png)
ファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/147fbec0-ad9b-aa80-0666-584e9ad3b3da.png)
アップロードが正常に終了したことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/b2a43d37-d058-8efc-a02f-cde8c595ed2b.png)
真ん中のボタンを押下して、AWSのコマンド実行ツールを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/1831b87a-4978-b5a5-34c7-099944e79fc0.png)
コマンドを実行します。
'''
aws s3 presign s3://URL
'''
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/f8e81482-6324-97c0-ed71-feeedfcae026.png)
作成したURLをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414365/0e527071-90b0-d2b2-75d3-193d25c6b590.png)

次の<SIGNED URL>を上記URLで置き換えます。アプリの名前を忘れずに置き換えます。
```
heroku pg:backups:restore '<SIGNED URL>' DATABASE_URL -a appname
```
Python の BeautifulSoup.find() の戻り値を確認

BeautifulSoup.find() の戻り値を簡単に確認してみた。

```python
$ python
Python 3.10.3 (main, Mar 29 2022, 01:35:20) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup
>>> inner_html = r'''
...     <body>
...     <div class="summarycount">524</div>
...     <div class="foo">
...     <a href="https://www.example.com/">go to exmaple.com</a>
...     </div>
...     </body>
... '''
>>> soup = BeautifulSoup(inner_html)
>>> score = soup.find('div', attrs={'class' : 'summarycount'})
>>> print(type(score))
<class'bs4.element.Tag'>
>>> print(score.contents)
['524']
>>> score = soup.find('div').get('class')
>>> print(type(score))
<class'list'>
>>> print(score)
['summarycount']
>>> print(score[0])
summarycount
>>> score = soup.find('div', attrs={'class' : 'foo'})
>>> print(type(score))
<class'bs4.element.Tag'>
>>> print(score.contents)
['\n', <a href="https://www.example.com/">go to exmaple.com</a>, '\n']
>>> score = soup.find('a').get('href')
>>> print(type(score))
<class'str'>
>>> print(score)
https://www.example.com/
>>> score = soup.find('a').get('target')
>>> print(type(score))
<class'NoneType'>
>>> print(score)
None
>>> score = soup.find('span')
>>> print(type(score))
<class'NoneType'>
>>> print(score)
None
>>> exit()
```
pdftoppm で PDF を PNG にするメモ

## 背景

PDF を画像にしたい

Linux だととりあえず pdftoppm がありました.

## PNG にする

`-png` を指定します.

## 指定した解像度にしたい

`pdftoppm -scale-to 1024 input.pdf -png output.png`

と `-scale-to` で指定する.
ただ, 丸め誤差とかできっちり指定した解像度にならないときがあります.
`-x` などのクロップで対応しましょう.

## DPI で指定

`-r` で指定できます.
Navicat ：データベース管理ツール

Navicat ：データベース管理ツール
avicat Premiumは、MySQL、MariaDB、SQL Server、SQLite、Oracle、PostgreSQLデータベースに単一のプログラムで同時に接続できるデータベース管理ツールです。また、Drizzle、OurDelta、Percona Serverと互換性があり、Amazon RDS、Amazon Aurora、Amazon Redshift、SQL Azure、Oracle Cloud、Google Cloudなどのクラウドデータベースをサポートしています。

Navicat Premiumは、他のNavicatメンバーの機能と組み合わせて、ストレージ・プロシージャ、イベント、トリガ、関数、ビューなど、現在のデータベース管理システムで使用されている機能の大部分をサポートします。

Navicat Premiumは、さまざまなデータベース・システム間でデータを迅速に転送したり、SQL形式とエンコードされた純粋なテキスト・ファイルに転送したりすることができます。異なるデータベースのバッチ・ジョブを計画し、指定した時間に実行します。その他の機能には、インポートウィザード、エクスポートウィザード、クエリー作成ツール、レポート作成ツール、データ同期、バックアップ、作業計画、その他があります。

Navicatの機能は、プロフェッショナル開発者のすべてのニーズに対応するのに十分ですが、データベース・サーバの初心者にとってはかなり勉強しやすいです。

![Snipaste_2022-04-01_16-11-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/9586a5b8-56f1-5ba4-9123-256e2ba3b38d.png)
![Snipaste_2022-04-01_16-11-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/cfb1158c-312b-c22c-5bdb-7a7c0bb0deaa.png)


Navicat16-まったく新しい方法でデータベースを管理します。
Navicat 16は、データベース開発のニーズを満たすために、いくつかの改善と新機能を備えています。 100を超える拡張機能と更新されたインターフェイスにより、新しい方法でデータベースを作成、管理、および保守できます。
ユーザーインターフェース
シンプルで美しく、より効率的です。
Navicat 15には、以前のバージョンに比べていくつかのユーザーインターフェイスの改善があります。合理化された作業環境と再配置されたボタンを備えた新しいユーザーインターフェイスは、作業に関連する情報を提供します。これで、複雑なジョブをこれまでになく速く完了することができます。


![Snipaste_2022-04-01_16-12-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/38587b69-d46b-0b9e-7670-89249872b788.png)

14日間の無料トライアルがあります（クラッカーはzipファイルに含まれています,割れた後は無期限に使用できます）

ダウンロード接続:https://test1.czfkyy.top/navicat160_premium_jp_x64.exe
![Snipaste_2022-04-01_16-10-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/cf849bbf-f45c-5824-c237-4a1fdd9a6682.png)


以下はクラックチュートリアルです
1.このプログラムを開く

![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/a2b5e18e-7a98-f540-c7da-6dcbd7af4364.png)

2.navicat.exeを選択します
![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/b4339104-0cbb-6626-64b2-a6de820ccc41.png)


3.Generateをクリックしてkey値を生成し、copyボタンをクリックします

![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/b21e9343-ea6e-9720-0eea-b081dd47955a.png)

4.次にNavicat Premiumソフトウェアを開き、登録をクリックしてcopyの値をコピーします。アクティブ化をクリックし、アクティブ化に失敗したことを示します。クリックして手動でアクティブ化
5.上のリクエストコードをコピーし、解読ソフトを開き、上のテキストボックスにコピーし、下のGenerateをクリックします。

![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610732/b0258316-cc98-c3c8-1ac3-7056640c4d07.png)

6.生成されたActivation Codeをアクティブ化インタフェースに埋め込むとアクティブ化が完了します
ダウンロード接続:https://test1.czfkyy.top/navicat160_premium_jp_x64.exe
[GENESIS64]AlarmWorXにフィルタ用の列を追加する

AlarmWorX Viewerでアラームをフィルタリングするための列を追加する方法を記載します。
大量のアラームが発生した場合など、発生した装置やラインなどでフィルタリングできるようになると便利かと思います。

# 完成イメージ
AlarmWorX Viewerの一番右の列にフィルタリング用の「カテゴリー」列を追加してみます。
![alarm7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/f7081d45-4da1-a6af-c5d6-a67fae04755d.png)

# Workbenchの設定
「AlarmWorX64 Server」→「設定」からアラームタグを追加します。
タグの「その他」タブの「関連する値」に今回フィルタリング用に使う値を入力します。今回は「関連する値1」を使います。
Workbench側はこれだけです。
![workbench_alarm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/f2822605-1cf1-eac6-ec1f-b958a8081654.png)

# AlarmWorX Viewerの設定
GraphWorXを開いて、AlarmWorX Viewerのコントロールを貼り付けます。
デフォルト状態では、以下のようになってます。
![alarm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/058c177b-a41a-20b4-183c-d03b2c89e118.png)

AlarmWorX Viewerコントロールをダブルクリックして設定画面を開きます。
「ソース」タブから「＋」→「リアルタイムサブスクリプション」を選択します。
![alarm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/1fc7a8ee-e8e6-55a6-a9e2-878a896d7658.png)

以下のフィールド編集ボタンをクリックします。
![alarm3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/4ba9386c-9499-f2c8-c645-2484551e9fbf.png)

以下のように「RELATED_VALUE_01」にチェックを入れます。
![alarm4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/e945c1c8-aabe-3ca4-5403-f2a666003a03.png)

次に、「列」タブに移動します。
すると、以下のように「RELATED_VALUE_01」が増えているので、「見出し」を任意に変更します。今回は「カテゴリー」とします。
編集後、画面右下のチェックボタンを押すのを忘れずに。
これで完成です。
![alarm5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/9471e36e-2b6f-3962-6393-86daa221396e.png)

# 完成
「カテゴリー」列が右端に追加されてます。Workbenchで関連する値1に入力した文字が表示されているはずです。
![alarm7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/8c95f3e3-3ef7-4f06-4207-23312ba54aa8.png)

列のヘッダーをクリックすると、フィルタリングができます。
![alarm8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/025a64dd-de95-9939-1b76-9595107e9496.png)

以上です。
microCMSでserviceDomain or endpoint may be wrongを解決する方法 

# 概要
Next.jsとmicroCMSの組み合わせでブログを作成しているのだが、
今まで本番用のmicroCMS環境しかなくて、開発用環境が欲しくなった。。！

ローカルでは開発環境用のmicroCMSに接続したく、microCMSのサービスを新規作成してみた！
現在の本番用の環境をコピーするだけなのだが…！(余裕じゃねーかと思っていたのはココまで)

`yarn dev`コマンドでローカルサーバーを起動した際に
microCMSを用いて、serviceDomainもAPIキーも絶対合っているはずなのに
下記のエラーが発生する。。
```
Error: serviceDomain or endpoint may be wrong.
 Details: Error: fetch API response status: 401
```

**なぜだ！！！**
と三時間程度、髪を散らかしていたのだが(心なしか髪が薄k略)、ようやく原因が判明した。

# 解決方法
まずは解決方法からご覧いただこう
```
yarn upgrade --latest
```
このコマンドを打つことで解決。

# どーゆーことー？？
更新されたpackage.jsonを見てみよう
![package.json - dremater - Visual Studio Code 2022-04-01 14.18.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231358/5ff6b179-4c57-5108-bc1b-5d80b11f20f1.png)

ほう。メジャーバージョンが上がっているな。
ところで私が~~ブログの更新をサボって~~microCMSを使っていない間に下記記事によるとmicroCMSが大幅に更新されたよう。
[APIキーをX-MICROCMS-API-KEYへとリニューアルしました。https://blog.microcms.io/renew-x-microcms-api-key/](https://blog.microcms.io/renew-x-microcms-api-key/)
この記事を見ていると
![APIキーをX-MICROCMS-API-KEYへとリニューアルしました。 _ microCMSブログ - Google Chrome 2022-04-01 14.23.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231358/5239a9a2-5fb4-3234-5538-68c885f5dd78.png)
**microcms-js-sdkのバージョンが2.0.0が必要にも関わらず、1.2.0を使用していること**
が今回のエラーの原因であることが判明

前microCMSを使用した時は、1.2.0で問題なかったが
時は移り、2022/4/1時点では2.0.0以降のバージョンが必要になったのか。なるほど。

# まとめ
APIが更新されたら、しっかり更新してやらないと変なところで詰んだりするという教訓だった。
(的確にmicrocms-js-sdkをv2.0.0に更新してというエラーだったらすぐ解決だったのだが、
この辺りのエラー解決の勘は今後身につけていきます💪💪)
PowerApps Collect利用時の空が混ざると結果がすべて空になる事象の解決

# PowerApps でCollectした結果が空になる

```
ForAll(
  openList
  Collect(
     summaryList,
     targetField
  )
)
```
この`openList`の`targetFeld`が空のものが一つでもあるとうまく収集できません・・・。

# 解決策
以下のように変更することで、空を解決したデータ収集が可能になります。

```
ForAll(
  openList
  Collect(
     summaryList,
     If(IsEmpty(targetField), 代替となるデータ, targetField)
  )
)
```
VPC内のLambdaからインターネットに接続する

# 背景・目的
インターネット上のAPIを呼び出して、データを取得したい。
これを、Lambdaで実現する方法を試す。

# 内容
## 概要
- [Qiita API](https://qiita.com/api/v2/docs#get-apiv2tags)の``/api/v2/items``を使用して記事の一覧を作成日時の降順で取得する。


## 前提
- ネットワーク（VPC、サブネット、ルートテーブル）、インターネットゲートウェイ、NATゲートウェイなど正しく設定されているものとする。

## 実践
### Lambda関数の作成
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/69fa33af-a95d-c8f6-7af7-07371b412c8d.png">

- 上記の他に、予め作成したVPC、サブネット、セキュリティグループを指定する。


### コード
- 以下のコードを書いて、Deploy&Testを実行。
```
import urllib.request
import json

# エンドポイント
url = 'https://qiita.com/api/v2/items?page=1&per_page=10'

# リクエスト
req = urllib.request.Request(url)

try:
    with urllib.request.urlopen(req) as res:
        body = json.load(res)
        for item in body:
            print("{0}".format(item['title']))
        
except urllib.error.HTTPError as e:
    if e.code >=400:
        print(e.reason)
    else:
        raise e

```
- 指定したエンドポイントに対して、リクエストを実行しタイトルを取得するプログラム。
- [Qiita API](https://qiita.com/api/v2/docs#get-apiv2tags)を見ると、他にもURLやタグなども取得できるようだ。


#### 結果
- 以下のように結果が返ってきました。
```
ABC245のA, B, C, D問題 を Elixir で解く
Flutterで作成したアプリをリリースした話
Azure x IBMCloud Active/Active 冗長化接続(IPsecVPN+BGP)
ISLispでラムダ計算インタプリタを作った話
ドメインモデルで設計上の問題を解決する
OData #3 Intune データ ウェアハウスでデバイス管理のためのレポートを作成する
text-align: center;の使い方
Python3: Elastic Cloud の filters の使い方
Dynatraceでダッシュボードの作成
Go言語 HelloWorld
```
# 考察
- 次回は、この関数を定期的に実行する。
- 今後、QiitaAPIから、取得したデータを利用した分析など試してみたい。

# 参考
https://qiita.com/api/v2/docs#get-apiv2tags

https://docs.python.org/ja/3/library/urllib.request.html
text-align: center;の使い方

学習記事初投稿となります。
学習記録のためのoutputの場にしようと思うので、温かい目で見守って頂けると幸いです。

## なぜtext-align: center;を調べようと思ったか
progateの中級編（6.レイアウトを整えよう）を行っていた際に、
text-align: center;を使用することでh1やpのブロック要素も中央に寄せられているのを見て、
**「あれ？text-align: center;　ってインライン要素、インラインブロック要素を中央に寄せるんじゃなかったっけ？」**
って思ったからです。

```html:html
    <div>
        <h1>これはh1です</h1>
        <p>これはpです</p>
        <a>これはaです</a>
    </div>
```


![text-align1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606269/f80e322e-d44f-83d9-6b9d-7899953314e7.png)

#### ⇩divにtext-align: center;を適用

![text-align2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606269/39c40ee8-ebfa-cfcc-49e0-54f9139868ea.png)


プロック要素のh1やpもtext-align: center;で中央に寄るのってなんでだろう。。


## progateのtext-align:center; 説明文
>text-alignプロパティを用いることで、 **テキスト、インライン要素、インラインブロック要素** の配置を指定することができます。


インライン要素、インラインブロック要素の他にテキストの配置を指定できるとのことでした。

## テキストとは？
今回でいうh1やpが中央に寄せられるのはテキストとして扱われているから（？）だと思われるので実際に確かめてみた。
h1、p、aにそれぞれbackground-colorを付けて確認。

![text-align3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606269/1943a72d-c810-3533-124b-ccd99c296eb1.png)

#### ⇩divにtext-align: center;を適用

![text-align4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606269/524d5778-7648-0570-c1dc-58bf25d8d9bc.png)


text-align: center;をした際、ブロック要素に関しては **ブロック要素内のテキスト部分がの中心に寄せられる** みたい！

## 結論
text-align: center;をした際、
-  **インライン要素、インラインブロック要素** ‥ 要素が中央に寄せられる。
- **ブロック要素** ‥ テキスト部分がブロック要素内の中心に寄せられる。
Python3: Elastic Cloud の filters の使い方

こちらと同じことを python3 で記述しました。
[Elastic Cloud の filters の使い方](https://qiita.com/ekzemplaro/items/1ab696e2d230a59b548d)

```py:elastic_filter.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	elastic_filter.py
#
#					Apr/01/2022
#
# ------------------------------------------------------------------
import  sys
import  json
import  requests
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
	str_out = ""
	try:
		fp_in = open(file_in,encoding='utf-8')
		str_out = fp_in.read()
		fp_in.close()
	except Exception as ee:
		sys.stderr.write("*** error *** file_to_str_proc ***\n")
		sys.stderr.write(str (ee))
#
	return	str_out
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
host="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
search_key="search-******"
name_engine=sys.argv[1]
json_query=sys.argv[2]

url=host + "/api/as/v1/engines/" + name_engine + "/search"
headers = {"Content-Type": "application/json",
	"Authorization": "Bearer " + search_key}
json_str = file_to_str_proc(json_query)
#
#
rr=requests.post(url, headers=headers, data=json_str)
#print(rr.text)
#
dict_data = json.loads(rr.text)
#
for unit_aa in dict_data['results']:
	print(unit_aa['states']['raw'])
#
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

```json:query01.json
{
  "query": "",
  "filters" : { "states": [ "Texas", "Minnesota" ] }
}
```

実行結果

```text
$ ./elastic_filter.py national-parks-demo query01.json
*** 開始 ***
['Texas']
['Minnesota']
['Texas']
*** 終了 ***
```

次のバージョンで確認しました。

```text
$ python --version
Python 3.9.7
```
Go言語 HelloWorld

## Code
```Go
package main

import "fmt"

func main() {
	fmt.Println("Hello, World!");
}
```
## Comment
Go言語は、「go run」コマンドによって、ビルドプロセスを隠蔽出来る。
もちろん、「go build」コマンドによって、明示的にビルドすることも出来る。

## Output Sample
$ go run hello.go  
Hello, World!  
$ go build -o hello hello.go  
$ ./hello  
Hello, World!  

## GitHub
https://github.com/GL-Kageyama/Go_HelloWorld
cscの作法 その85

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題

認知症チェックアプリを作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3925c7c6-4059-07f9-2831-910c13d85e6f.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace App
{
	public class Form1 : Form {
		string[] toi = new string[] { 
			" 同じことを何回も言ったり聞いたりする",
			" 今切ったばかりなのに電話の相手の名前を忘れる",
			" しまい忘れ・置き忘れが増え、いつも探しものをしている",
			" よく知っている人の名前を忘れる",
			" ものの名前が出てこなくなった",
			" 簡単な計算の間違いが多くなる、いつも大きなお金で支払いをする",
			" 料理・片付け・運転などのミスや、蛇口・ガス栓の閉め忘れが多くなった",
			" 雑誌や新聞、テレビ番組の内容が理解できなくなった",
			" 薬の飲み忘れが多くなった",
			" 今日の日付・時間がわからない",
			" 慣れているところでも道に迷うことがある",
			" 約束の日時・場所を忘れたり 間違えたりする",
			" ささいなことで怒りっぽくなった",
			" 自分の失敗を人のせいにしたり、以前よりも疑い深くなった",
			" 趣味や好きなテレビ番組に興味を示さなくなった",
			" 身だしなみに気をかけなくなった",
			" 一人で外出することが減った",
			" 気分が落ち込みやすくなった",
		};
		Button button1;
		public Form1() {
			Text = "認知症チェックシート";
			button1 = new Button();
			button1.Font = new Font("MS UI Gothic", 12F, FontStyle.Regular, GraphicsUnit.Point, ((System.Byte)(128)));
			button1.Location = new Point(68, 32);
			button1.Name = "button1";
			button1.Size = new Size(104, 32);
			button1.TabIndex = 1;
			button1.Text = "Start";
			Controls.Add(button1);
			button1.Click += button1_Click;
		}
		private void button1_Click(object sender, EventArgs e) {
			int[] ans = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
			int h = 0;
			for (int i = 0; i < 18; i++)
			{
				DialogResult res = MessageBox.Show(toi[i], "問い", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
				if (res.ToString() == "Yes")
					ans[i] = 1;
			}
			for (int i = 0; i < 18; i++)
			{
				if (ans[i] > 0)
					h = h + 1;
			}
			if (h > 4)
				MessageBox.Show("5つ以上チェックがある人は認知症の可能性があります。");
			else
				MessageBox.Show("まだ、大丈夫です。");
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}




```

以上。
Boomによるエラーハンドリング NodeJS

[hapi/Boom](https://hapi.dev/module/boom/)

インストール
`npm install @hapi/boom`

# 実装
```index.js
require('dotenv').config()
const express = require('express')
const errorHandler = require('./helpers/error') // ←こちらを指定

// 省略
// 

// エラー処理ミドルウェア
app.use(errorHandler)

const listener = app.listen(3000, function(){
  logger.info('Listening on port ' + listener.address().port)
})
```

ミドルウェア処理

```helpers/error.js
const boom = require('boom')
const config = require('../config/default')
const log4js = require("log4js");
const logger = log4js.getLogger("default");

const errorHandler = (err, req, res, next) => {
    if (res.headersSent) return next(err)
    if (!err.statusCode) err = boom.boomify(err)

    if (err.hogehoge)  { // 各分岐処理
      // error
      }
      return
    }
    if (isMongodbErr(err)) { // mongoとかのエラー
      logger.warn(req.userId, err.message)
      res.status(500).json({message:err.message})
      return
    }

    if (err.isServer) {
      logger.error(req.userId, err)
      res.status(500).json({message: '予期せぬエラーとか'})
      return
      // boom通した500番台のエラーはisServerでtrueが返る
    }
    err.isBoom ? logger.warn(req.userId, err.output.payload) : logger.error(req.userId, err)
    return err.isBoom
      ? res.status(err.output.statusCode).json(err.output.payload)
      : res.status(err.statusCode).json(err)
  }

  const isMongodbErr = (err) => {
    return err.name === 'MongoServerSelectionError'
  }

module.exports = errorHandler
```

ハンドル方法

```hoge.js

// モンゴDBからデータを取得する処理
router.get('/endpoint', async function (req, res, next) {
  try {
　　// if (await cheackEndpoint(req.params.endpoint)) return next(Boom.badRequest('メッセージ')) //みたいにパラメーターチェックも可
    const obj = { Name: { $eq: req.params.hogehoge } }
    const result = await db.find(obj, 'ccc')
    if (result.length === 0) return next(Boom.notFound('data not found')) //0件の場合エラーとしたい時など
    res.json(result)
  } catch (error) {
    next(error) // try Catchに引っかかるとミドルウェアへnextされる
  }
})
```

クライアントには以下が返る。

```
{
    "statusCode": 400,
    "error": "Bad Request",
    "message": "invalid query"
}
```

BoomではbadRequestやnotFoundなどデフォルトのテンプレがあるので、それをうまく使おう。 クライアントへ送るメッセージはこちらでも設定できるので便利
【Salesforce】メールアラートを使用して外部にメール送信する

# はじめに
外部へのメール送信にSingleEmailMessageを使用すると、ガバナ制限（1組織1日5,000件が上限）に抵触する可能性があるので、SingleEmailMessageの使用回数を消費しない代替案としてSalesforce標準機能のメールアラートを使用した場合の設定手順を備忘として以下に記載しておきます。

# メールテンプレート作成
Classicメールテンプレートに任意のメール内容を設定し、テンプレートを作成します。

|項目|設定値|
|---|---|
|フォルダ|任意のフォルダ|
|有効|チェックあり|
|メールテンプレート名|任意のメールテンプレート名|
|テンプレートの一意の名前|任意のテンプレートの一意の名前|
|文字コード|任意の文字コード|
|説明|任意の説明|
|件名|任意の件名|
|メール内容|任意のメール内容|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/1e750cfe-3bcb-6d72-f701-0256b2d46571.png)

# メールアラート作成
メールアラートを作成します。
（ここでは最低限の設定として例を記載していますので、実際には要件を満たすように詳細な条件を設定する必要があります。）

|項目|備考|
|---|---|
|説明|説明を記載します。|
|一意の名前|一意の名前を記載します。|
|オブジェクト|ここでは例として「取引先責任者」を選択します。|
|メールテンプレート|上記で作成したメールテンプレートを指定します。|
|受信者種別|「取引先責任者」にあるメール項目を使用するので「メールの項目」を選択します。|
|メール受信者|「メールの項目：メール」を選択します。|
|追加のメール|任意で追加します。|
|差出人メールアドレス|任意の差出人を指定します。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/79c1fbc0-cd8d-8769-1bb2-fb69001b97d1.png)

# フロー作成
フローを作成します。

【開始条件】

|項目|設定値|
|---|---|
|オブジェクト|取引先責任者|
|トリガ|レコードが作成または更新された|
|エントリ条件|任意の条件|
|更新されたレコードでフローを実行するタイミング|条件の要件に一致するようにレコードを更新したときのみ|
|フローを最適化|アクションと関連レコード|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/6adbd7e0-dbab-94a2-1c45-d2a5ad224a3b.png)

【新規アクション】

|項目|設定値|
|---|---|
|アクション|テストメールアラート|
|表示ラベル|メールアラート送信|
|API参照名|sendMailAlert|
|説明|任意|
|カスタムオブジェクトID|{!$Record.Id}|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/1377e4af-cbe6-fa7f-d62c-2b408acaea19.png)

【保存】

|項目|設定値|
|---|---|
|フローの表示ラベル|テストメールアラートフロー|
|フローのAPI参照名|TestMailAlertFlow|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/9e81f1c1-0d7d-4979-23b5-ddc5668a2d12.png)

※フローイメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344923/7f039ce0-f154-cb06-54cb-12f0c8472191.png)

# 動作検証
取引先責任者のメール項目に送信先メールアドレスを設定しオブジェクトを新規登録すると、設定した送信先メールアドレス宛にメールが送信されます。

【メール内容】

|項目|値|備考|
|---|---|---|
|送信元|取引先責任者を作成したユーザのメールアドレス||
|送信先|取引先責任者のメール項目に設定したメールアドレス||
|件名|テスト件名|メールテンプレートの設定値|
|本文|テスト本文|メールテンプレートの設定値|

# おわりに
最終的には外部のメール配信サービスを使用してガバナ制限を回避する様にしたため、この案は採用しませんでした。
ガバナ制限に引っかかるほどのメール数をメールアラートを使用して回避できるケースならよいのですが、恐らく別の箇所で問題が発生する可能性があります。（私がぶち当たった問題はここでは割愛します。）
Salesforceではこういうメール送信も出来るよ！くらいで覚えておけばよいかな。
クラウド環境について

プログラミングスクールでAWSを使っていますが、調べてみると他にもある。と言うことで、実際のところどうなのという感想を書いてみた。
# 使い始め
AWSの無料プランに登録し、カリキュラム通りに設定などをやっていたが、多要素認証（MFA）でつまずく。後で、メンターの人に聞いたら、やらなくてもいいことが判明。
自分であれこれやっていたが、結局元に戻らなくなったので、アカウントを新たに作成。
それ以降は、別のアカウントで進めている。（必要がないのなら、そう書いてあってもいいと思う)

# なんかもやもやするので
なんかもやもやするので、AWSのサポートに電話して、AWSのMFAデバイスを解除してもらうことにした。空いているのが、7日なので、電話してもらってサインインのところまで操作することにしました。


# 他のクラウド環境としては
paizaがやっているPaizaCloudというのがあります。Paizaラーニングをやっているひとにはなじみがあるかもしれない。
機能的には、AWSには劣るらしいが、複数人で開発をする必要がないのなら、使う価値はありそうだ。

# 注意が必要
結局のところ、クラウド環境を使う場合は注意が必要なので、よく調べてから使うのをおススメします。
私はどっちがいいかわかりませんが。
【JavaScript, 正規表現】replace()で複数文字列を置換した際のエラーについて

## はじめに
+ 実行環境：Google Apps Script
+ 文字列 `log(x)` から `Math.log(x)` への置換

## エラー内容
`log(x)` が１つの場合は問題なかったが、`log(x) + log(y)` のように複数になると一部しか置換されなかった。

```javascript:js
function convertExpression(str){
  str = str.replace(/log\((.+)\)/g, "Math.log($1)");   
  console.log(str);  // Math.log(2) + log(3) ← 置換されていない
  return String(eval(str));
}

console.log(convertExpression("log(2) + log(3)"));  // ReferenceError: log is not defined
```

## 原因
[基本的な正規表現一覧](https://murashun.jp/article/programming/regular-expression.html)によると
> `+` : 直前の文字が １回以上 繰り返す場合にマッチします。**最長一致**。条件に合う**最長**の部分に一致します。
> `+?` : 直前の文字が １回以上 繰り返す場合にマッチします。**最短一致**。条件に合う**最短**の部分に一致します。

つまり、最初のコードでは最長一致になっていたため、１つ目の `)` はスルーされ、`.+` の部分に `2) + log(3` がマッチした。それが `Math.log()` の中に入って  `Math.log(2) + log(3)` となったようだ。

## 解決
`.+` の部分を `.+?` にすることで解決した。
```javascript:js
function convertExpression(str){
  str = str.replace(/log\((.+?)\)/g, "Math.log($1)");   
  console.log(str);  // Math.log(2) + Math.log(3) ← 置換された
  return String(eval(str));
}

console.log(convertExpression("log(2) + log(3)"));  // 1.791759469228055
```

## 参考
https://note.affi-sapo-sv.com/js-regular-expressions.php#i6
GitLab.comのCI/CDパイプラインで SSL certificate problem: unable to get local issuer certificate が出る

gitlab.comで "Specific" のRunnerを作った時に出たエラー。
その対応方法。

## このメッセージが出た環境
このメッセージが出た環境。
* `gitlab.com` を利用している。
* 自分の保持するプロジェクトに Specific Runner(Docker) をローカルに作った。

## メッセージ全文
`fatal: unable to access 'https://gitlab.com/<ユーザーのNameSpace>/<リポジトリ名>.git/': SSL certificate problem: unable to get local issuer certificate`
![Qiita投稿用画像02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609745/88f03da0-da2f-9e48-8d2f-43dd9df34356.png)

## 回避方法
まず、`gitlab.com` の証明書をブラウザ経由で入手する。
Runnerの構成ディレクトリの直下に `certs` ディレクトリを作成し、そこへ先ほどの証明書を入れる。
Runnerの `config.toml` に `tls-ca-file` を追加して、証明書へのフルパスを記載する。

例えばRunnerの構成ディレクトリが `/etc/gitlab-runner` なら、以下の通りになる。

```config.toml
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "<runnnerの名前>"
  url = "https://gitlab.com/"
  token = "<トークン>"
  tls-ca-file = "/etc/gitlab-runner/certs/gitlab.com.cer"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "ruby3.1.1"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
 ```

設定ファイル `config.toml` は保存後に即時反映されるので、Runnerの再起動は不要。
メタデータコンテンツについてその２~linkタグ編~

## ＜link＞タグとは
ドキュメントと外部リソースを関連付ける要素。

|  |  |
|:-:|:-:|
| 場所  | メタデータコンテンツを内包できる要素内で使用できる。head要素が親要素であるnoscript要素内で使用できる。  |
| コンテンツモデル  | 空  |
| 属性  | グローバル属性。外部スタイルシートを読み込むlink要素におけるtitle属性は、特別な意味を持つ。必須：href属性、rel属性。任意：media属性、hreflang属性、type属性、sizes属性。  |
| ブラウザ対応  | Internet Explorer、Google Chrome、Safari、Firefox、Opera  |

### 必須属性
| 属性 | 説明 | 属性値 | 説明 |
|:-:|:-:|:-:|:-:|
| rel  | 現在の文書から見たリンク先の関係  | リンクタイプ  | 半角スペース区切りで複数指定可能  |
| href  | リンク先の指定  | URL  | 関連文書類のURL  |

### 任意属性
| 属性 | 説明 | 属性値 | 説明 |
|:-:|:-:|:-:|:-:|
| hreflang  | リンク先の記述言語  | 言語コード  | ja,en,zh等  |
| type  | リンク先のMIMEタイプ  | MIMEタイプ  | CSSの場合はtext/css  |
| media  | 対象とするメディア  | メディアクエリ  | カンマ区切りで複数指定可能（初期値はall）  |
| sizes  | アイコンのサイズ  | any/横幅✖︎高さ  | 可変サイズ（SVG等、ベクター形式の画像向け）/ピクセル数で指定、半角スペース区切りで複数指定可能  |
| crossorigin  | 別のドメインにあるリソースの扱い方法  | anonymous/use-credentials  | 認証を利用しない/認証を利用する  |
| rev | リンク先から見た現在の文書の関係 |　リンクタイプ | 半角スペース区切りで複数指定可能　　※HTML Living Standardでは対応していない　|

### グローバル属性
| 属性 | 説明 | 属性値 | 説明 |
|:-:|:-:|:-:|:-:|
| title  | リンク先のタイトル  | 文字列  | 任意のタイトル  |

:::note alert
link要素におけるtitle属性は、スタイルシートのグループ名という特別な意味を持つ。代替スタイルシートを用意し、スタイルシートを切り替えられるようにするときに使う。
↓詳しくはこちらの記事にまとめています↓
[スタイルシートの構文](https://qiita.com/Manami_mer0814/items/3dec3264cf91c32ec0e5)
:::


## サンプルコード
~~~html
<!DOCTYPE html>
 <html lang="ja">
  <head>
   <link rel="stylesheet" href="stylesheet.css">
   <title>ドキュメントのタイトル</title>
  </head>
  <body>
   ドキュメントの内容
  </body>
</html>
~~~

## 参考サイト

https://web.havincoffee.com/html/tag/link/

http://html5.cyberlab.info/elements/metadata/link.html

https://www.tagindex.com/html5/page/link.html
【Deno1.20～】import-mapを自動検出する

昔は実行時にimport-mapを自動で検出する方法が無かったため、コマンドラインフラグの`--import-map`を渡す必要がありました。

```shell
deno run --import-map=./import_map.json ./mod.ts
```

しかし、Deno1.20以降では[deno設定ファイル](https://qiita.com/access3151fq/items/7aa44ee69b4a5ff867c7)が自動検出されるようになったため、この機能を利用してimport-mapを自動検出できるようになりました。

## import-mapを自動検出する方法

#### 1. deno.jsonを作成する

`deno.json`または`deno.jsonc`（deno設定ファイル）を作成します。
作成する場所はプロジェクトフォルダのルートディレクトリでOKです。

```:プロジェクトフォルダ（例）
project/
 ├ deno.json
 └ mod.ts
```

ファイルの中にはimport-mapを直接記述します。

```json:deno.json
{
  "imports": {
    "lodash": "https://esm.sh/lodash@4.17.21"
  }
}
```

あるいは、別のファイルにimport-mapを切り出すこともできます。その場合、`importMap`キーにパスを指定します。（`"import_map.json"`の所は各自の環境に合わせてパスを書く）

```json:deno.json（こちらの書き方でもよい）
{
  "importMap": "./import_map.json"
}
```

#### 2. 実行する

プロジェクトのルートフォルダに`deno.json`がある状態で`deno run`コマンドを実行すると、`deno.json`が自動検出されます。そして、`deno.json`の中で指定したimport-mapも自動で読み込まれます。

```shell
> deno run ./mod.ts # deno.jsonがあれば自動検出される
```

deno.jsonの検出アルゴリズムは、

- ファイル名を指定した場合（例：`deno run ./src/mod.ts`）→ファイルがある場所からルートディレクトリに遡って探索
- ファイル名を指定しない場合（例：`deno fmt`）→カレントディレクトリからルートディレクトリに遡って探索

という形になっています。
なおdeno.jsonではなくdeno.jsoncでも同様に動作します。

## まとめ

- import mapを自動検出するにはdeno.jsonを置く。
デザインにおける一貫性の重要性

読者の皆さんこんにちは！本日は、タイトルのとおりデザインの一貫性の重要性についてお話ししていきたいと思います！

＜スケールアップの問題をデザインシステムで解決する方法＞
少し前に、弊社のCEOであるMarcin Trederは、社内デザインシステムの構築をについて、一連の記事を書きました。業界のリーダーにインタビューした結果、彼はデザインの一貫性の欠如が明らかに世界中の開発チームの共通問題であると結論付けました。そして、デザインチームとユーザーにとってこの一貫性の欠如は多くの問題を引き起こす可能性があります。

ユーザーの混乱：異なるパターンで同じ動作をすると混乱する。
スローデザインプロセス：再利用可能なデザインアセットが少ないと発生するワークフロー全体での遅れ。
オンボーディングの難しさ：文書化されていないシステムに新しいデザイナーや開発者を巻き込むのは困難。

Q：では、どのようにデザインの不整合を最小限に抑えているのでしょうか？

A：我々の調査では、「デザインシステムの構築と維持」が最も多く得た回答でした。
![1_-6R704Zl5LNLaVG6GKa4aw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037046/981c5111-feb0-0ec8-4bc6-cd25bc3c666c.png)
世界の69% の企業がデザインシステムの導入を検討中・構築中です。 Salesforce, IBM, Airbnb , Atlassian などの企業が先頭に立ちこの動きをリードしています。

これらは確かに理にかなっており、企業規模が大きくなればなるほど不整合の問題は苦痛なものになります。また、デザインシステムは開発の一部つまりプロセスであるため、常に準備ができていると同時に時流に合わせてアップデートが必要です。

— UXPin CEO , Marcin Treder

＜デザインシステムを構築する理由＞

デザインシステムは単なるスタイルガイドやパターンライブラリでは無く、製品開発の青写真です。（全てのデザイン原則、ビジュアルセット、パターンは徹底的に文書化されている必要があります。）

AtlassianのシニアUXデザイナーのAllard van Helbergen氏は、2018年のバーチャルデザインサミットでデザインシステムから学んだことを以下のように述べています。

「多くの人がデザインシステムを構築する理由を異なる製品やチーム間で一貫性を保つためと答えます。しかし、前記理由よりも勝る理由は認知的な負荷を軽減し開発スピードを高速化することなのです。そして、究極的にはユーザーを助けることにつながるのです。」
![1_RhYqZn4BxR1NL9n76rBoew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037046/15406ffc-90b3-3d27-4522-911261f89b31.png)
「全ての製品に完璧に対応するワンサイズ・コンポーネントは存在しないため、ある程度のカスタマイズ性を持たせることは必要です。Atlassianは、デザインシステムに成長の余地を残すことで製品のニーズに合わせてコンポーネントを少しずつ変更できることを発見しました。」

— Atlassian シニアUXデザイナー , Allard van Helbergen

＜デザインシステムのROI＞
市場投入への時短：1箇所に集約され、誰でも容易にコードベースコンポーネントにアクセスできるためクオリティに妥協することなくアジャイル開発が可能になる。
製品価値の向上：再利用可能なコンポーネントは製品の外観、感触、動作に一貫性を与えます。
コラボレーションと知識共有の促進：共有・承認されたデザインシステムによって、デザイナーや開発者のサイロ化を防止します。
時間とコストの削減：デザイナーと開発者が重複した質問・作業に追われることが無くなるため、より高い付加価値を提供することに注力することができます。