OmniAICreator/Qiita-1.07M huggingface dataset:
MB-910受験記

# はじめに
私はPower Platformについて学習し、社内外の課題解決を行っていきたいと思っており、
Power Platform App Makerの資格は保持しています。
App Makerの勉強を進める中で、Dynamics 365（以下D365）についても知識もあったほうがより理解が深まるのではないかと思い、D365についても勉強を始めることにしました。

というわけで今回取得した資格はこちらです。
[MB-910: Microsoft Dynamics 365 Fundamentals (CRM)](https://learn.microsoft.com/ja-jp/certifications/exams/mb-910)

定期的に開催されているVirtual Training Dayで無料バウチャーをゲットできます。

# D365 Fundamentals（CRM）って何？
CRMとはCustomer Relationship Managementの略です。
顧客とのリレーションシップを管理するサービスのことを指します。
D365の顧客管理系のサービス(Dynamics 365 Customer Engagementアプリ)に関する基礎知識を問われるのが、MB-910です。

## D365 Fundamentals（CRM）の対象サービス
### Microsoft Dynamics 365 Marketing
見込顧客を獲得・管理・商談化を行うためのサービス。マーケターをサポートする。
マーケティング活動に必要な全ての機能を提供。

### Microsoft Dynamics 365 Sales
商談情報や、商談化した顧客を管理するサービス。営業をサポートする。

### Microsoft Dynamics 365 Customer Service
既存顧客のサポートを支援するためのサービス。お客様窓口をサポートする。
Zendeskとかその辺のサービスと近いイメージ。

### Microsoft Dynamics 365 Field Service
技術者を派遣する際のもろもろを管理するサービス。
洗濯機や車が壊れたから直す技術者を派遣するとか、そういった作業のイメージっぽい。

### Microsoft Dynamics 365 Project Operations
プロジェクトを管理する。PMや管理職をサポートする。

## おさえておくべきLinkdIn連携
LinkdInとはビジネス特化型のSNSで、Facebookのビジネス版と呼ばれています。
LinkdInにはLinkedIn Campaign Managerを使用してLinkdInで広告キャンペーンをうてるので、それをD365 Marketingに潜在顧客情報としてインポートしたり、
LinkedIn Lead Gen Forms からリードを同期したり、
LinkedIn Sales Navigatorを使用して高度な検索機能を使用して見込み顧客を探せるので、Dynamics 365 Salesと連携したりできます。

# 受験した感想
780点くらいで合格しました。
私は職務上、市場調査～リード獲得～商談～受注あたりのプロセスをなんとなくわかっているので、「こういうことがきっと出来るだろう」というイメージでざっと2時間くらい勉強したら受かることができました。
LinkdInに馴染みがなく、そこが理解できていなかったため、上位資格受験時にはしっかり勉強したいと思います。
Power Platform App Makerを持っているので「これビジネスプロセスフローだな」とことが分かり理解を助けてくれましたが、この資格を持っているからと言ってApp Makerの勉強に役立ったかというと、不要だったとおもいました。

次はMB-910と同等の資格である[MB-920：Microsoft Dynamics 365 の基礎 (ERP)](https://learn.microsoft.com/ja-jp/certifications/exams/mb-920)を受験予定です。
スマートウオッチ作る (2)ファームの書き換え

# 今回の内容
- 前回 [改造](https://qiita.com/nora_wanko/private/858071e6bf2fc2e4f393) した腕時計のファームを公式で配布されている別のファームに更新してみます
- 実機を入手されてない方は、ブラウザ上で見られる標準ファームのエミュレータが[ココ](https://www.sensorwatch.net/docs/firmware/simulate/focus/)にありますが、ファーム書き換えにはEmscriptenインストールが必要なのでそれは次回に解説します
- 今後、自分で作ったソースの書き込み手順も同じになります
# 1.ビルド済ファームの入手
[ここ](https://www.sensorwatch.net/docs/firmware/prebuilt/)に公開されている各種プレビルド済ファームが複数置いてあります。
これらファームは、それぞれ　世界時計、ストップウオッチ…など[沢山の機能・画面 ＝ Face](https://www.sensorwatch.net/docs/watchfaces/)を3～5個セットにしてプレビルドしたバイナリです。

例えば、標準で搭載されているファームは、[このプレビルド ファームウエア](https://www.sensorwatch.net/docs/firmware/prebuilt/)ページ内の先頭のMovement Standard部分にあります。
このファームに含まれる5つの画面(Face)の概要およびプレビルドファームのダウンロードリンク(赤枠)があります。

![標準ファーム.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/46eae946-52a1-2bdb-c86a-4351ae6cddfe.jpeg)

書き換えたいファームのGreen Boardsリンクから ～.uf2ファイルをダウンロードしておいてください。

なお、各機能(画面)や操作方法が知りたいときは、Simple Clock（緑枠）のような画面(Face)名を覚えておき、[Watch Face Documentation](https://www.sensorwatch.net/docs/watchfaces/)の中から、Simple Clockの項を探してみることが出来ます。

# 2.ビルド済のダウンロードと書き込み
上でダウンロードしたファームに書き換えてみます

### 2-1.接続
センサー ウォッチ ボードを腕時計から取り出し、PCとUSB Micro B ケーブルに接続してから、ボードの背面にある小さなリセット ボタン(下図赤部)を**素早く**ダブルクリックします。
結構な速さのダブルクリックでないと認識されないので注意してください。
![USB接続と書き込みIMG_20230104_122943_126.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/c68264a2-f4a0-dba8-cc8d-dafae4f33196.jpeg)
成功すると、ボード上のLED が赤色に点滅し始め、「WATCHBOOT」というドライブが表示されるので、ここに先ほどダウンロードした *.uf2ファイルを１つ貼り付けます。
![WATCHBOOTドライブ出現s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/dde7b90a-eadf-af70-bddf-8b1947a91524.jpeg)
貼り付けると、即座にストレージクラス接続が解除されますのでUSBケーブルを抜き、元通り組付けます。

なお、書き込むファイルのファイル名は何でもよく、自動的にCURRENT.UF2に置き換わります。

# 3.次回

開発環境とエミュレータの導入とビルドを行おうと思います
開発環境はWin10 上の Subsystem for Linux（’22/11のWSLg/Store版) に作る予定です

# 参考サイト

- [SensorWatch公式](https://www.sensorwatch.net/docs/firmware/prebuilt/)
スマートウオッチ作る(3)  SAM L22開発環境準備

# 今回の内容
・Win10 上の Subsystem for Linux（WSL2 ’22/11のWSLg/Store版) に開発環境を作り
・ブラウザで動作するエミュレータも導入します
・使うSubsystem for Linuxは、せっかくなので[WSLg](https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps)対応のストア版を使いました。最近はWin10でもWSLg使えるようになったので。ただ、今回はLinuxのGUI使ってないので別のWSLでも良いかと思います。

# 環境
- Windows 10 Pro 22H2 + ストア版WSL2
- HDD空 3GB程度必要(WSL導入後の空き領域）

# 1.開発環境の準備

### 1-1.ストア版Subsystem for Linux/Ubuntuを導入

ストア版Subsystem for Linuxは[ここ](https://www.microsoft.com/store/productId/9P9TQF7MRM4R)にあるので導入します
HyperVなど必要な設定はしておいてください。X server準備しなくても良いって便利ですね。
![WSL2_store版_WSLg対応版.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/3fd2d1dd-a2bc-aaf2-d5cd-009d4a57a0a3.jpeg)

続いて、同じくストアで「linux」と検索してUbuntu20.04.5LTSwを導入します
![WSL2_ubuntu20_04_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/b69c7f8d-e41a-92ea-5d86-1db8cc06e841.png)

スタート- [Ubuntu 20.04.5]で起動し、初回起動時にIDをパスワード聞かれるので設定し、
最初に以下を行っておきます
```sh
sudo apt update
sudo apt dist-upgrade
```

### 1-2．コンパイラ導入
[公式ページ](https://www.sensorwatch.net/docs/movement/building/)の通り、
GNU ARM Embedded Toolchain for 64-bit Linuxを導入します。

```sh
sudo apt install gcc-arm-none-eabi
sudo apt install make
```
### 1-3．エミュレータの導入

```sh
cd ~
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
git pull
./emsdk install latest
./emsdk activate latest
echo 'source "/home/kazuhito_noro/emsdk/emsdk_env.sh"' >> $HOME/.bash_profile
source ./emsdk_env.sh
```
### 1-4　公式ソースのクローン

```sh
cd ~
git clone https://github.com/joeycastillo/Sensor-Watch
```

### 1-5　エミュレータ用コンパイル

```sh
cd Sensor-Watch/movement/make/
emmake make

python3 -m http.server -d build-sim
```
Win10のブラウザで以下にアクセスすると
```sh
http://localhost:8000/watch.html
```
こんな風にブラウザで動作確認できます。
毎回、F91腕時計を分解して書き込んでいると、そのうち物理的に破損しそうなのでエミュレータは助かりますね。
![WSL2_store版_WSLg_使わずにpythonでWebサーバ起動忘れてた件→無事エミュレータ動作GW2k.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436645/d5d9424f-314f-e50d-c172-0445e21dcab6.jpeg)

### 1-6　実機用コンパイル
実機用のバイナリは以下実行すると、
```sh
cd Sensor-Watch/movement/make/
make
```
./build/watch.uf2
が出来上がるので、前回の通りPCに繋いで書き込めばOKです


# 関連サイト・参考サイト
[センサーウオッチ公式](https://www.sensorwatch.net/docs/movement/building/)
[公式Github](https://github.com/joeycastillo/Sensor-Watch/tree/main/PCB/Sensor%20Boards)

# ご参考
- 素のUbuntu上に入れる場合は手順1-2からでOKです。
- [関連記事1 スマートウオッチ作る (1) SAM L22ボードの入手・組付け](https://qiita.com/nora_wanko/items/858071e6bf2fc2e4f393)
- [関連記事2 スマートウオッチ作る (2)ファームの書き換え](https://qiita.com/nora_wanko/items/c0cc7a80a8911276813e)
vSphere,ESXi,ハイパーバイザーとは何ぞや？

# Why｜なぜ調べようと思ったのか？
- 「vSphere」を利用し始めてから1年弱、ざっくりの理解で進んでいた。
- 脆弱性情報に関するニュースで「VMware Workstation」の存在を知り、都度調べるよりもいちど全体像を理解しておく必要性を感じた。

# How｜情報整理の意図
- 「ESXi」「Hyper-V」など含めて、その用語が製品名なのか、仮想化手法の概念名なのか、を分かるように纏める。

# What｜調べた内容
### ＜「vSphere」の構成要素と機能＞
- 構成要素
    - `VMware vSphere`（仮想化ソフトウェアのパッケージ）
        - `VMware ESXi`（**ハイパーバイザー**）
        - vCenter Server（監視・管理）
        - vSphere Client（管理コンソール）
- 機能
    - vMotion
        - 起動中の仮想マシンを瞬時に別の物理サーバに移動（ライブマイグレーション）
    - vSphere HA（High Availability）
        - サーバ停止時に自動的に別のサーバで仮想マシンを再起動する
    - vSphere FT（Fault Tolerance）
        - 複数のサーバで同一の仮想マシンを動作させて障害に備える
### ＜ハイパーバイザーとは？？＞
- コンピュータを仮想化し、複数の異なるオペレーティングシステム（OS）を互いに干渉させずに並行して動作させられるようにするソフトウェア。
- （語源）｜**supervisor（SV）** が「管理者」という意味の英単語なので、「上位層からプログラムを管理する」という意味から生まれている？、らしい。

### ＜ハイパーバイザーの種類＞
#### ベアメタル型
- OSに拠らずハードウェア上で直接動作し、実行されるOSがすべて仮想マシン上で動作するような制御プログラム。完全な仮想化環境を得られ性能劣化も小さい。
    - （通常はこれを「ハイパーバイザー」と呼ぶ。狭義のハイパーバイザー）
- 構成は、【ハードディスク＞ハイパーバイザー＞OS】
- 製品は、「`Xen`」「`VMware vSphere`」「`Hyper-V`」など

#### ホスト型
- 基盤となるOS上で仮想マシンを提供するソフトウェア。この方式では、コンピュータ上で直接実行されるOSを「ホストOS」、仮想化環境上で実行されるOSを「ゲストOS」という。仮想化ソフトに加えてホストOSを経由してハードウェアにアクセスするため性能の劣化は大きい。
    - （仮想化ソフトウェア。あまりこれを「ハイパーバイザー」とは呼ばない。広義のハイパーバイザー）
- 構成は、【ハードディスク＞ホストOS＞仮想化ソフト＞ゲストOS】
- 製品は、「`VMware Workstation(Player/Pro)`」「`VMware Fusion`」「`Virtual PC`」「`VirtalBox`」「`Parallels Desktop`」など
    - VMware Workstation：Windows／Linuxホスト向け
    - VMware Fusion：Macホスト向け

# 参考サイト
- [VMware ESXiとは - 意味をわかりやすく - IT用語辞典 e-Words](https://e-words.jp/w/VMware_ESXi.html)
- [ESXiとは？ - Qiita](https://qiita.com/miyuki_samitani/items/3ce7ea10b3a078d42d56)
- [ハイパーバイザとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12196.html)
- [ハイパーバイザーとは  | クラウド・データセンター用語集／IDCフロンティア](https://www.idcf.jp/words/hypervisor.html)
wsh でマウス操作をする

通常 wsh だけの機能ではマウスを操作することはできません。

手段としては EXCEL がインストールされていれば `ExecuteExcel4Macro` を呼び出して Win32API を叩けますが、
それ以外だと Win32API を叩く実行ファイルをダウンロードして、`WScript.Shell` から実行する方法しかありません。

.dll や .exe のダウンロードが厳しい場合は下記 C# を自身でコンパイルして実行ファイルを作成します。

```c#:mouse.cs
using System;
using System.Runtime.InteropServices;

namespace Device {
    public class Mouse {
        public static void Main (params string[] args) {
            string method = args[0];
            int posX = args.Length > 1 ? Int32.Parse(args[1]) : 0;
            int posY = args.Length > 2 ? Int32.Parse(args[2]) : 0;

            if (method == "pos") {
                SetCursorPos(posX, posY);
            }

            if (method == "click") {
                mouse_event(0x2, posX, posY, 0, 0);
                mouse_event(0x4, 0, 0, 0, 0);
            }

            if (method == "leftDown") {
                mouse_event(0x2, posX, posY, 0, 0);
            }

            if (method == "leftUp") {
                mouse_event(0x4, posX, posY, 0, 0);
            }

            if (method == "rightClick") {
                mouse_event(0x8, posX, posY, 0, 0);
                mouse_event(0x10, 0, 0, 0, 0);
            }

            if (method == "rightDown") {
                mouse_event(0x8, posX, posY, 0, 0);
            }

            if (method == "righttUp") {
                mouse_event(0x10, posX, posY, 0, 0);
            }
        }

        [DllImport("USER32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void SetCursorPos(int X, int Y);

        [DllImport("USER32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
    }
}
```

こちらを

```bat
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:exe /out:mouse.exe .\mouse.cs
```

でコンパイルして

```javascript:mouse.js
var Shell = WScript.CreateObject('WScript.Shell')

function SetCursorPos (x, y) {
    Shell.Exec('mouse pos 100 100')
}

function Click () {
    Shell.Exec('mouse click')
}

SetCursorPos(100, 200)
WScript.Sleep(500)
Click()
```

で操作できます。

もし .dll や .exe などの実行ファイルのダウンロードやコンパイルが出来ない環境の場合は
wes から C# を直接実行して操作ができます。

[wes](https://github.com/wachaon/wes) は WSH のスクリプトを今風の記述で開発できるフレームワークです。

+  `require/module.exports` や `import/export` が記述でき、モジュール単位で開発可能
+  一般的なファイル操作はビルトインモジュールで対応しているので「車輪の再開発」をしなくても良い
+  WSHのフレームワークなので、EXCEL などの COM 操作も従来通り可能
+  外部パッケージをインストールすることも可能。

などの特徴があります。

wes の入手方法は [wes](https://github.com/wachaon/wes) から wes.js をコピーしてファイルを作成するか、
コンソールで次のコマンドを実行してください。

```bat
bitsadmin /TRANSFER GetWES https://raw.githubusercontent.com/wachaon/wes/master/wes.js %CD%\\wes.js
```

[@wachaon/mouse](https://github.com/wachaon/mouse) をインストールします。
[@wachaon/mouse](https://github.com/wachaon/mouse) は powershell を使用して先ほどの C# ファイルを実行します。
詳しくはソースを直接ご確認ください。

```bat
wes install @wachaon/mouse --bare
```

```javascript
const mouse = require('mouse')

mouse.pos(100, 100)
mouse.click()
```

wes を使えば wsh だけでは解決が難しい問題も比較的簡単に処理できます。
【ServiceNow】NextExperienceモードにおけるテーマの設定について

# 【ServiceNow】NextExperienceモードにおけるテーマの設定について

従来のServiceNowでは「システムの設定」からテーマで色合い等を選択できるのだが
NextExperienceでは標準状態だとテーマの設定自体が選択できなくなってしまう。

※そもそもNext Experienceって？
バージョンケベックから新しく導入された、効率と生産性を高めるために作られた新たなServiceNowのUIの形とのことです。

詳細は以下のページに記載
[ServiceNow Next Experience](https://docs.servicenow.com/en-US/bundle/tokyo-platform-user-interface/page/get-started/servicenow-overview/concept/next-experience-landing-page.html
)

で、このNext Experienceでは従来のようにテーマを変更することができるのか？

答えはイエス。ただし、デフォルトで用意されたものでなく、自分の方でカラーバリエーションを定義する必要がある。
ということで、下記にそのやり方を記載していく。

# 具体的な手順
1. 【前提】NextExperienceモードへの変更
    1.  フィルタナビゲータで「sys_properties.list」と入力し、sys_propertiesの中身を表示
    1. 「glide.ui.polaris.experience」の設定をTrueにする。
     ⇒以上の設定でNext Experienceモードになります。

2. ダークモードの追加
   NextExperienceに標準でテーマとしてされているダークモードを表示させるようにする
    1. フィルタナビゲータで「sys_properties.list」と入力し、sys_propertiesの中身を表示。
    1. 「glide.ui.polaris.dark_themes_enabled」の設定をTrueにする。 
     ⇒以上の設定でダークモードの設定を選択できるようになります。
     　この状態で設定をみるとテーマの項目が出現し、デフォルトモードかダークモードかを選択できるようになる。
 
3. オリジナルのテーマ色を追加
  手順2でテーマの設定ができる状態になったので、ここからはテーマの定義を作成する。
    1. フィルタナビゲータで「Theme」(日本語の場合は「テーマ」)と入力しNow Experienceのテーマを選択。
    1. UX ThemeでPolarisを選択。
    1. UX Theme SyleでDarkを選択。
    1. 「Insert and Stay」を選択し、適当な名前を入力し保存(以降はこちらのUX Styleを編集することになります)
    ※この際sn-themesアプリケーション内にあるのでGlobal状態だと編集できないと忠告メッセージが出ますが、「Insert and Stay」を行いコピー先のUX Theme Styleを編集することでGlobalでも編集できるようになります。
    1. UX Theme Style選択画面に戻りColorsを選択し、Styleの中身をコピー
    1. 新しく作成したTheme StyleのStyleをColorsでコピーしたもの[^1]に上書き貼付し、保存。
    1. baseで定義されている各色の箇所を任意の色に設定する。
    　色のメインとされている部分は大体以下であり、色の定義はRGB表記でそれぞれ0～255で設定できる。
    　"--now-color_chrome--brand"
    　"--now-color_brand--secondary"
    　"--now-color--primary"
    　"--now-color--secondary"
    　"--now-color_selection--secondary"
    　"--now-color--interactive"
    　"--now-color_surface--brand"
    　"--now-color_brand--primary"
    　例を挙げると従来のローズのようなテーマにしたい場合はbaseの上記の定義を「205,87,98」で設定してすると似たようなテーマを作成できる
    　色の定義を保存することで再度設定画面からテーマを確認すると、今回新たに追加したテーマを設定することができる。

    [^1]: Styleの中身はJSon形式になっており以下の定義がされている
    　base…色の定義を行っている(RGB形式)
    　property…各パーツ部分をbaseで設定した定義(primary,secondary,neutral)に割り当てている

 
# 感想
　Next Experienceにしたことでシンプルな機能以外は全部そぎ落とした感じ？
　やはりテーマはNEでもデフォルトでいくつか用意してほしかった
　(開発で環境ごとにテーマの見た目を分けてすぐ分かるようにしてたというのもあって)
Pythonの宣言等

Pythonの記載を忘れるので、備忘録として記載。

## 注意点
- ブロックごとにインデントを合わせないとエラーになる
- javaのブロックを示す`｛｝`はPythonでいうと`:`で示す。

## pythonの変数定義
宣言は型を指定しなくてよい。

```
配列: array = []
変数: intVariable = 0
     strVarinable = ""
連想配列: array2 = {}
```

## String、int変換方法
基本的に、型が違っていて処理できない場合はエラーになってしまう。
その際は、以下のように型を変換する。
文字列に変換する場合：`str(数値)`
数値に変換する場合：`int(文字列）`

## ユーザー定義関数の宣言方法

```
def 関数名(変数, 変数)
    return 戻したい変数など
```

## リストの件数を調べる
`len(リスト)`

## リストのソート
```
リスト.sort() #この場合昇順
リスト.sort(reverse=True) #この場合降順
リスト.sort(key=キーに使用するリストの内容) #リスト内の値を使ってソート
```

## リストにデータを追加する
`リスト.append(追加するデータ)`

## 文字列の分割
```
文字列.split() #この場合空白文字列でsplitを行う
文字列.split("文字列") #指定した文字列でsplitを行う。
```

## FOR文の書き方
```
for ループ変数 in range(ループしたい数値)

#この場合1ずつインクリメントして、rangeに指定した範囲文ループを行う。
```

## 文字列の切り取り
### 1番目から3番目を切り取る
```
#ABCDEの場合
#インデックスの指定のため、数え年と同じ風に考えると1ずれてしまう

文字列[0:3] → 結果:"ABC"
```

## ifのキーワードについて
`if` = `if`
`else` = `else`
`else if` = `elif`

### 連想配列の指定方法
```
変数名 = {'key名'：キー値, 'key名'：キー値, ...}
```

新しいキーに追加する場合は、そのまま別のものを指定すればよい

```
変数名['キー名'] = 値
```

別の連想配列を、コピーしたい場合は.updateメソッドを利用する
```
コピーしたい変数名.update(コピー元変数名)
```
mysqldumpの使い方

## DBのバックアップ
```
# DB内の全てのテーブルをバックアップ
$ mysqldump -u USER_NAME -p -h HOST_NAME DB_NAME > ファイル名.sql

# DB内の特定のテーブルをバックアップ
$ mysqldump -u USER_NAME -p -h HOST_NAME DB_NAME TABLE_NAME > ファイル名.sql
```

## DBのリストア
```
# ダンプからDBを復元
$ mysql -u USER_NAME -p -h HOST_NAME DB_NAME < ファイル名.sql
```

## mysqldumpの応用
例えばテストコード内でmysqldumpを取得したい場合など
```php:test.php
$cmd = sprintf(
    "MYSQL_PWD=%s mysqldump -u %s -h %s %s > ファイル名.sql",
    config('database.connections.mysql.password'),
    config('database.connections.mysql.username'),
    config('database.connections.mysql.host'),
    config('database.connections.mysql.database'),
);
exec($cmd);
```
Windows10 pro の Visual Studio Code の設定初期化

# はじめに
題名の通り。
毎回調べるハメになっているので、書き残しメモ。
※ログインしているユーザーの設定における初期化方法となる

# 環境
Windows10 pro

# 方法
1. PowerShell を起動
    - Windowsキー → Power..
    - 管理者権限は不要

2. 以下コマンドを実行
```
rm -r -fo .\.vscode\
rm -r -fo .\AppData\Roaming\Code\
```
※起動時に使用ユーザーのフォルダになっていますので、フォルダ移動はしなくてもよいかと思います
※上記をコピペしたらバックスラッシュは円記号の表示になるかと思います

# 終わりに
コマンドプロンプトのdelで試してみましたが、うまくいかずPowerShellで対応…
Azure Machine Learning ことはじめ（Microsoft Learn もくじ）

Azure Machine Learning について、Microsoft Learn の簡易目次を作成しました。
あと自分の勉強記事の目次も併せてリンクを張っています。

* [機械学習](https://learn.microsoft.com/ja-jp/training/paths/create-no-code-predictive-models-azure-machine-learning/)
  * [回帰モデル](https://learn.microsoft.com/ja-jp/training/modules/create-regression-model-azure-machine-learning-designer/)
  * [分類モデル](https://learn.microsoft.com/ja-jp/training/modules/create-classification-model-azure-machine-learning-designer/)
    * [Azure Machine Learning ことはじめ（Azure Machine Learning Studio を使ったデータ分類）](https://qiita.com/tnishiki/items/e33142a68dcdcede27d9)
  * [クラスタリングモデル](https://learn.microsoft.com/ja-jp/training/modules/create-clustering-model-azure-machine-learning-designer/)
* [Computer Vision](https://learn.microsoft.com/ja-jp/training/paths/explore-computer-vision-microsoft-azure/)
  * [画像の分析](https://learn.microsoft.com/ja-jp/training/modules/analyze-images-computer-vision/)
    * 画像の説明
    * 視覚的な特徴のタグ付け
  * [オブジェクトの検出](https://learn.microsoft.com/ja-jp/training/modules/detect-objects-images-custom-vision/)
    * ブランドの検出
  * [顔の検出](https://learn.microsoft.com/ja-jp/training/modules/detect-analyze-faces/)
    * Face API
  * [画像の分類](https://learn.microsoft.com/ja-jp/training/modules/classify-images-custom-vision/)
    * 物体の検出 
      * [Azure Machine Learning ことはじめ（Custom Vision による画像分類）](https://qiita.com/tnishiki/items/26d1d3d31f2eeb8a1a2b)
    * ドメイン固有のコンテンツの検出
      * ランドマークの検出
      * 有名人の検出
  * [光学式文字認識](https://learn.microsoft.com/ja-jp/training/modules/read-text-computer-vision/)
      * Read API
  * [帳票分析](https://learn.microsoft.com/ja-jp/training/modules/analyze-receipts-form-recognizer/)
    * [Azure Machine Learning ことはじめ（Form Recognizer version 2.1）](https://qiita.com/tnishiki/items/a45d300072928505d9c3)
    * [Azure Machine Learning ことはじめ（Form Recognizer version 3.0 2022-08-31版）](https://qiita.com/tnishiki/items/18872e8dc670958528f2)
* [自然言語処理](https://learn.microsoft.com/ja-jp/training/paths/explore-natural-language-processing/)
  * [テキスト分析](https://learn.microsoft.com/ja-jp/training/modules/analyze-text-with-text-analytics-service/)
    * 言語識別
    * キーワード検出
    * 感情分析
    * エンティティ検出
     * [Azure Machine Learning ことはじめ（テキスト分析）](https://qiita.com/tnishiki/items/d4df523866683cd6ecf2) 
  * [音声の認識と合成](https://learn.microsoft.com/ja-jp/training/paths/explore-natural-language-processing/)
    * [音声処理](https://learn.microsoft.com/ja-jp/training/modules/recognize-synthesize-speech/)
      * Speech to Text
      * Text to Speech
    * [テキストと音声の翻訳](https://learn.microsoft.com/ja-jp/training/modules/translate-text-with-translation-service/)
      * テキストの翻訳
      * 音声の翻訳
    * [会話言語理解](https://learn.microsoft.com/ja-jp/training/modules/create-language-model-with-language-understanding/)
 * [意思決定支援](https://learn.microsoft.com/ja-jp/training/paths/explore-fundamentals-of-decision-support/)
macbook pro 2014はアプリ開発に使えるか

# はじめに
これまでwindowsデスクトップを使っていたけど手軽にプログラミングの勉強など開発・お遊びに使えそうなノートPCを検討していて旧型のmacbook proが値段も手頃で性能もそこそこ良さそうなので購入して試してみた記録メモ。

# 環境
* [MacBook Pro (13-inch, Mid 2014)](https://support.apple.com/kb/SP703?locale=ja_JP&viewlocale=ja_JP) [i7 メモリ16GB SSD512GB]
* macOS Big Sur 11.7.2

# 結論
macbook pro 2014でも結構いける。
現時点の最新のXcode 14.2は使えないけどXcode 13.2.1は使える。
※最近は新しいXcodeじゃないとリリースできないとか要件があった気がするので本格的にリリースしたい場合は注意。
Android studioは最新の安定版2021.3.1 Patch11が使える。
Flutterも最新安定版3.3.10が使える。
アプリ開発の勉強などには問題なく使えそう。
macはディスプレイも解像度が高くて見やすいのも良い。
バッテリー駆動で色々セットアップしていると3時間ほどで電池がなくなる感じだったが、家の中で使う予定なので3時間も使えれば問題なさそう。

# バッテリー
中古で充放電回数は500回を超えていたので最大1000回のうち半分以上は使っている状態。
https://support.apple.com/ja-jp/HT201585
そのせいかわからないけど、公式ではインターネットやムービー再生程度なら9時間持つらしいけど、そこまでは持たない気がする。
https://support.apple.com/kb/SP703?locale=ja_JP&viewlocale=ja_JP

# ビルド時間
IDEのテンプレートをビルドしたくらいの確認だけど、それほど時間はかからない。
個人開発くらいなら問題なさそう。
## Xcode
ビルド、実行合わせて30秒もかからない。

## Android Studio
初回ビルドは依存モジュールのダウンロード、ビルドに数分かかるけど、clean build→build apkは10秒くらいで終わる。

# 作業メモ
## xcodeインストール
xcodeは最新を使えないので古いのをダウンロードしてインストール。
以下にて自分のApple Idでサインインしてmac osに対応したxcodeをダウンロード。
https://developer.apple.com/download/all/

macbook pro 2014のbig surに対応しているのは13.21までなので[xcode 13.21](https://download.developer.apple.com/Developer_Tools/Xcode_13.2.1/Xcode_13.2.1.xip)をダウンロードしてインストール。

## Android Studio
公式からダウンロードしてインストールするだけ。
https://developer.android.com/studio?hl=ja

## Flutter
公式からダウンロードしてインストール。
https://docs.flutter.dev/get-started/install/macos

flutter doctorのチェックの解消は基本はメッセージを参照して対応だが、
cocoa podsは[こちら](https://qiita.com/yoshinyan/items/2c9a59e5a3bd80b9bdbd)のようにbrew install cocoapodsで解消。
Angular13->14へバージョンアップ後、Jestデバッグ時に`Error: Unknown arguments: testMatch, runInBand`エラーが出た際の対処法

# はじめに
AngularのテストフレームワークをJestに移行後、
Angular13->14へバージョンアップした際に起きたエラーについての備忘録です。
単純に自分の確認不足のエラーでしたが、戒めとして残します。

## エラー時のバージョン
```bash

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 14.2.10
Node: 16.10.0
Package Manager: npm 7.24.0 
OS: linux arm64

Angular: 14.2.12
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.1402.10
@angular-devkit/build-angular      14.2.10
@angular-devkit/core               14.2.10
@angular-devkit/schematics         14.2.10
@angular/cdk                       14.2.7
@angular/cli                       14.2.10
@angular/material                  14.2.7
@angular/material-moment-adapter   14.2.7
@schematics/angular                14.2.10
rxjs                               6.5.5
typescript                         4.6.4

```


# 現象
Angular14にバージョンアップ後、
VSCodeのデバッガでデバッグ実行をすると下記のエラーが発生しました。

```bash
Error: Unknown arguments: testMatch, runInBand
```

`npx test ${filepath}`ではテストが実行されますが、VSCode拡張機能のJestRunnerでも同様のエラーが発生する状態でした。

ちゃんと確認してみると、angular-buildersのMIGRATION.MDに記載がありました。

https://github.com/just-jeb/angular-builders/blob/master/MIGRATION.MD#migration-from-version-13-to-version-14

> キャメルケースのコマンドライン引数はサポートされなくなりました。

# 解決
VSCodeのデバッガの引数が原因だったので、
settings.jsonの`args`をケバブケースに修正することで解決しました🎉

### 変更前
```settings.json
{
  // 省略
  "launch": {
    "configurations": [
      {
        "type": "node",
        "request": "launch",
        "name": "Jest All",
        "program": "${workspaceFolder}/node_modules/@angular/cli/bin/ng",
        "cwd": "${workspaceFolder}",
        "args": [
          "test",
          "--testMatch=\"**/+(*.)+(spec|test).+(ts|js)?(x)\"",
          "--runInBand"
        ],
        "console": "integratedTerminal",
        "internalConsoleOptions": "neverOpen"
      },
    ]
  },
  // 以下、省略
}

```

### 変更後
```settings.json
{
  // 省略
  "launch": {
    "configurations": [
      {
        "type": "node",
        "request": "launch",
        "name": "Jest All",
        "program": "${workspaceFolder}/node_modules/@angular/cli/bin/ng",
        "cwd": "${workspaceFolder}",
        "args": [
          "test",
          "--test-match=\"**/+(*.)+(spec|test).+(ts|js)?(x)\"",
          "--run-in-band"
        ],
        "console": "integratedTerminal",
        "internalConsoleOptions": "neverOpen"
      },
    ]
  },
  // 以下、省略
}

```

# まとめ
Angularのバージョンアップ時は[angular-buildersのMIGRATION.MD](https://github.com/just-jeb/angular-builders/blob/master/MIGRATION.MD)も忘れず確認する。
【ServiceNow】Content Publishingでの機械翻訳①

<p>今回はServiceNowで利用できる機械翻訳機能について紹介します。</p>
<p>
ServiceNowでは下記のようなケースで日本語以外を使う場面が想定されます。<br/>
・海外のカスタマーとのやり取り<br/>
・別言語で書かれたナレッジの確認　などなど……<br/>
このようなケースで機械翻訳サービスを連携することで、より効率的に業務を進めることができます。
</p>
<p>
ServiceNowで連携利用できる翻訳サービスは下記です。<br/>
・Microsoft (Azure)<br/>
・IBM (Watson)<br/>
・Google (GCP)<br/>
今回はAzureを利用して説明します。<br/>
※ServiceNowとAzureADの連携については下記Docsをご参照ください。<br/>
<a href="https://learn.microsoft.com/ja-jp/azure/active-directory/saas-apps/servicenow-tutorial">チュートリアル:Azure Active Directory シングル サインオン (SSO) と ServiceNow の統合</a>
</p>
<h1>設定方法</h1>
<p>下記①～③の順に設定を行います。</p>
<h4>①プラグインのインストール</h4>
<p>
ServiceNowインスタンスでプラグインをインストールします。<br/>
エージェント画面で「プラグイン」画面を開き、下記のプラグインを検索・インストールします。<br/>
・Dynamic Translation (id: com.glide.dynamic_translation)<br/>
プラグインにはMS, BM, Googleの翻訳機能を利用するために必要な機能が同梱されています。<br/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/7678442c-d345-cd51-44f5-6a59b860577c.png" alt="プラグインインストール画面">
</p>
<h4>②Azure側の設定</h4>
<p>
次にAzure側の設定を行います。<br/>
Azureポータルを開き、下記の手順で翻訳サービスを作成します。<br/>
1. Azure Cognitive Service画面を開き、左メニューで「翻訳」を選択。<br/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/b18d7897-1b29-1dd2-a07b-8b11be690f2e.png" alt="Azure設定画面01">
</p>
<p>
2. 「作成」ボタンから翻訳サービスを新規作成。<br/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/58e762af-7002-4db1-9634-13ba3b5c39ae.png" alt="Azure設定画面02"><br/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/09e94d0a-f1fc-cdee-c9fe-1b0cbb09cd3a.png" alt="Azure設定画面03"><br/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/705e58c8-9c29-34b2-1562-994002034a7d.png" alt="Azure設定画面04"><br/>
</p>
<p>
※翻訳サービスの料金パターンについては下記を参照。今回はFreeプランを利用しました。<br/>
<a href="https://azure.microsoft.com/en-us/pricing/details/cognitive-services/translator/">Translator pricing</a>
</p>

<h1>次回</h1>
<p>次回は機械翻訳を利用するにあたって必要な設定を紹介します。</p>
画像認識における前処理

# 画像認識における前処理

## はじめに

この記事では備忘録もかねて画像データの「前処理」にフォーカスして、ディープラーニングなどで使用する際に最低限何を実施すべきかを記載していきます。  
詳しいやり方というより、こういう工程・項目を入れた方がよいなどを記載していきます。  

## 今回の前提

画像は撮影済みで、「前処理」を行い、この後の「物体検出」や「分類」に繋げていく場合を想定しています。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225931/690132a1-3ced-6961-a09f-600e1c2cd2d0.jpeg)


## 前処理

- ファイルネーミング変更
- ファイルをランダムに分割
- アノテーション
- リサイズ
- パディング
- データ拡張
- 画像確認ツール


## ファイルネーミング変更
ファイルのネーミングに関して、撮影後にルールを決めてネーミングを変更しておいた方が以降の処理で扱いやすいです。  
例えば、iPhoneで複数人で撮影して画像を集める場合、画像名が「IMG_<数字>.JPG」などで被る可能性があるからです。   
「<日付>-<撮影者>-<クラス>-<数値(インクリ)>.jpg」などにしておけば被ることはありません。  
撮影者の情報も入れておけば人ごとに仕分けをするなども可能になります。  
プロジェクトごとで必要な情報を付与するとよいです。


## ファイルをランダムに分割
ディープラーニングで画像を扱う際は、ファイルをランダムに分割ということをよく行います。  
rand関数等を使用して7:3や8:2などにすぐに分割できる用意をしておくとよいです。    
この時に注意なのが、オリジナルのフォルダは残しておくという点です。  
違うパターンで再度分割したくなった時にオリジナルがないと分けられなくなるので注意が必要です。

例：  
オリジナルフォルダ-|  
　　　　　|- 学習用フォルダ(8)  
　　　　　　　|-<日付>-<撮影者>-<クラス>-<数値(インクリ)>.jpg  
　　　　　　　|-・  
　　　　　　　|-・  
　　　　　|- 評価用フォルダ(2)  



## アノテーション
アノテーションは物体検出特有ですが、下記のツールを使用して行うことが多いです。

- VoTT  
　https://github.com/microsoft/VoTT

- labelImg  
　https://github.com/heartexlabs/labelImg

また、ネガティブを学習させる際に空のアノテーションファイル(名前はアノテーションファイルと同じだが、中身は空)を事前に別フォルダに作成しておくと、ネガティブ用のデータとして使用できるので効率がよいです。

## リサイズ
学習する入力サイズに合わせてリサイズをすることがあります。  
Pythonでは下記のライブラリを使用してリサイズを行うことが多いです。   
PillowとOpenCVはどちらかに統一して使用する方が無難です。  

- OpenCV  
　https://docs.opencv.org/4.x/  
　※デフォルトはBGRで読み込まれるので注意が必要です

- Pillow(Imageモジュールのメソッドresize)  
　https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.resize

## パディング
例えばアスペクト比を16:9のままに維持して正方形の形にリサイズを行いたい場合などがあると思います。  
その場合、アスペクト比を維持したままリサイズを行うと正方形にならないので、パディングする必要があります。  
縦横をルールなく撮影した場合はパディングをする場所にも注意が必要です。  
（縦長の場合は右側にパディング。横長の場合は下側にパディングなど）

- OpenCV  
　http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_core/py_basic_ops/py_basic_ops.html  

- Pillow(Imageモジュールのメソッドpaste)  
　https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.paste


## データ拡張
データ拡張は下記のようなツールを使用して拡張することが多いです。  

- ImageDataGenerator  
　https://keras.io/ja/preprocessing/image/

- labelImg  
　https://github.com/heartexlabs/labelImg

データはやみくもに増やせばよいというわけではなく、実際使用するシチュエーションを意識してデータ拡張する必要があります。  
例えば、オリジナルの画像を上下反転するような実際のシチュエーションはないのに、その画像を上下反転でデータ拡張で増やしても余り意味はありません。

## 画像確認ツール
サーバーなどで操作をしていて前処理を行ったり、推論結果をみたくなった場合に備えて、簡単に画像を確認するツールを準備しておくと便利です。  
筆者はjupyter notebook等を使用してPillowなどのモジュールで画像を確認するツールを作成し、その場で確認するようにしています。


## 最後に
記載の内容ですべてではありませんが、撮影してきた画像データをその後の処理に繋げるための最低限の前処理の内容は記載したと思います。  
今後も必要に応じて内容をアップデートしていきたいと思います。
gitlabでアクセストークンを用いたリモートとの通信

## 概要
アクセス権限で保護されたgitlabのリポジトリと通信する必要があったので、
その方法を備忘録としてまとめた。

## アクセストークンの発行
gitlabのアクセストークンは以下の記事がわかりやすかった
- オプションなどについて網羅的にまとめられている
https://www.gitlab.jp/blog/2021/12/06/access-token/

- アクセストークン発行がわかりやすくまとめられている
https://capibara1969.com/55/

## アクセストークンをリモートURLに設定する
リモートURLを確認
`git remote -v`

リモートURLを設定
`git remote set-url origin {リモートURL}`

リモートURLは以下の法則性がある
`https://{new access token}@github.com/{username}/{repository name}.git`

これで通信できた。
データ構造の連結リストって何ですの？

[Leetcode](https://leetcode.com/problemset/all/)をやっている中で連結リストというのに遭遇したんですけど、これまで1回も実務で見たことがなかったので、今回ちゃんと調べていこうとおもいます。

## 概要
めちゃくちゃザックリいうと、配列と似てるんですけど、配列の弱みを補ってくれるデータ構造なんです。
配列のデメリットは以下の通りです。
- サイズが固定されていて静的なデータ構造であること
- 要素が連続したメモリに格納されるため、挿入処理と削除処理にコストがかかる

2個目の挿入処理と削除処理にコストがかかるというのは、どういうことかというと、例えば以下の`JavaScript`のコードで、`shift`メソッドを使ったとしましょう

```
var array = [1, 3, 4, 5, 6, 8]
array.shift()
console.log(array)
// [3, 4, 5, 6, 8]
```
この処理を行うと、配列から1が消えて、それぞれの要素が左詰めになるように処理がされますね。そしてアドレスもそれによって変わるので、これが1000個とかあったらかなりのコストがかかりますね。`pop`メソッドも同じです。それを解決するのが連結リストです。

連結リストのイメージは以下の画像のようなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/eba73866-dbae-7b2a-69f5-d53cb617b3b7.png)

【参考資料】

https://towardsdatascience.com/how-i-taught-myself-linked-lists-72c4837ea721

連結リストにはそれぞれ`Node`というのがあって、そこに値とポインタというのがセットになっています。
先ほどの画像を見てみると分かるとおもいますが、`Node1`には14という数字があって、次に参照する`Node2`の参照場所の2つを持っているんです。こうすることで挿入処理が配列よりコスパがよくできます。
`Node1`の次に新しい要素を加えたいとき、Node1のポインタに次の参照場所を変更すれば済むだけの話なので簡単ですね。

実際に連結リストのコードを`JavaScript`で書いてみます。
```
var head;

class LinkedList {
    constructor(head = null) {
        this.head = head
    }
}

class ListNode {
    constructor(data) {
        this.data = data
        this.next = null                
    }
}

let node1 = new ListNode(2)
let node2 = new ListNode(5)
node1.next = node2

let list = new LinkedList(node1)
console.log(list)
//   LinkedList {
//      head: ListNode { data: 2, next: ListNode { data: 5, next: null } }
//   }
```
上記のコードで連結リストが作成することができます。

## 挿入するメソッド
一例として挿入するメソッドを以下に記述していきます。
```
function insert(prev_node, new_node){
    var new_node = new ListNode(new_node);
    new_node.next = prev_node.next;
    prev_node.next = new_node;
}

insert(node1, 8)

// LinkedList {
//  head: ListNode { data: 2, next: ListNode { data: 8, next: ListNode { data: 5, next: null } } }
// }
```

【参考資料】

https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B-%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%A4%A7%E6%A7%BB-%E5%85%BC%E8%B3%87/dp/4065128447

https://www.geeksforgeeks.org/what-is-linked-list/

https://www.thecrazyprogrammer.com/2021/05/advantages-and-disadvantages-of-array.html

https://towardsdatascience.com/how-i-taught-myself-linked-lists-72c4837ea721
[Hyper-V + Ubuntu 22.04] IPアドレスを固定する方法

# はじめに
Hyper-V (Windows10)でIPアドレスを固定するのに手こずってしまったので備忘録として投稿します。

# 1. ホストOS側の設定(Hyper-Vの設定)
［仮想スイッチマネージャー」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/0bd715e0-5142-65c1-e528-a90d9ae93baf.png)
［接続の種類］で［内部ネットワーク］を選択し、仮想スイッチを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/bd3a3fdf-fe7e-1c84-eb1c-64b317d80806.png)
仮想マシンの設定から［ネットワークアダプター］を開きます。
さきほど作成した［Internal-Switch］を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/cc89e1cd-b9da-3baa-28bf-82a7a9f60b81.png)

# 2. ホストOS側の設定(ネットワークアダプタの設定)
ファイル名を指定して実行（［Ctrl + R］を同時押し）を開きます。
［ncpa.cpl］と入力して［ネットワーク接続］の設定画面を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/9cb546e7-2141-540d-eba3-e5e2192ec7a8.png)
さきほど作成した［Internal-Swtich］を右クリックしプロパティを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/4a856298-f368-3461-f3e5-e96c57a78bce.png)
［プロパティ］ > ［インターネットプロトコルバージョン4］のプロパティを開き次の通り入力します。
※IPアドレスは適宜変更してOKです。
* IPアドレス: 10.100.1.254
* サブネットマスク: 255.255.0.0
* デフォルトゲートウェイ: 空欄
* 優先DNSサーバー: 空欄
* 代替DNSサーバー: 空欄
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140967/63d63120-3044-cfee-0873-09ab59a7274b.png)

# 3. ホストOS側の設定(NATテーブルの作成)
PowerShellを管理者権限で開きます。
下記のNATテーブルを追加するコマンドを入力します。
```powershell
New-NetNat -Name "10.100.1.0/24" -InternalIPInterfaceAddressPrefix 10.100.1.0/24
```

※削除したい場合は下記のコマンドを入力してください。
```powershell
# NATテーブルの一覧を表示
Get-NetNat | fl *
# さきほど作成したNATテーブルを削除
Remove-NetNat "10.100.1.0/24"
```

# 4. ゲストOS側の設定(Ubuntu 22.04)
以下のコマンドを入力してIPアドレスを変更します。
```bash
nano /etc/netplan/00-installer-config.yaml
```

下記の通りファイルを変更します。
```yaml:00-installer-config.yaml
network:
  ethernets:
    eth0:
      addresses:
        - 10.100.1.1/16
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
      routes:
        - to: default
          via: 10.100.1.254
  version: 2
```

変更を反映します。
```bash
netplan apply
```

# 5. pingコマンドで疎通確認
```bash
# 執筆環境におけるルーター（ホストマシンと同一ネットワーク）に到達できるか？
ping 192.168.1.1
# Google Public DNSに到達できるか？
ping 8.8.8.8
# 名前解決できるか？
ping google.com
```
git mv でファイル名変更をRenameと認識させよう

Git管理をしているソースに対して、ファイルの名前を変えなきゃいけない状況が起きることがある。
ソースコードを修正せず、ファイル名を変更するような状況…
例えば、ファイル名を間違えたとか、大文字小文字を間違えたとかそんな話の時だ。

## 普通にファイル名を変更した場合
エクスプローラーなどで、作業ファイルを直接変更した場合、どうなるか？
下記のようなファイルを、直接別の名前に変更する。
#### 変更前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/7802a516-f89b-c928-6d9b-29da52203649.png)
#### 変更後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/5643ae3b-b5e9-3e21-d390-de8f28e386dd.png)

#### git statusで状況を見た場合
この状態で`git status`を見ると、以下のように2種類の内容になっています。
- 変更前のファイルを削除
- 新しい変更後のファイルを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/3a12f9dc-2b27-ab59-81dd-e0fb8aad1ef6.png)
この場合、今までのレビュー状況であったり、ソースの差分履歴を見ることができなくなってしまいます。
完全に新規のソースで未レビューであればこのままでも問題はないのだが
基本的には、「ファイル名を変更した」というコミットにした方がよい。

## git mv コマンドによりRenameとGitに認識させる
こういう状況になった場合は、一度変更を元に戻して
Rename扱いとしてファイル修正する必要がある。

この場合、ファイル変更を認識させる方法として、以下のコマンドを使用する。
`git mv 変更するファイル名　変更後のファイル名`

こうすると、以下のように「ファイル名を変えました」とGitが認識してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/1febfed8-1df9-b764-f15b-184aaa20e152.png)
リモート会議はカメラオンにしませんかという話

2023年なりました。

年末での出来事があったので記憶があるうちに書いておく。

# 忘年会での話

忘年会があった訳ですが、多々大勢の人が集まって会食していました。
その時に見覚えのある顔...だけど名前が出てこない人から声かけられた。

「お久しぶりです。○○です。お会いするのは3ヶ月ぶりですねー」

リモートMTGでは毎日進捗伺っているけど、面と向かっては3ヶ月ぶり。パソコン受け渡しの時以来か。

声は聞いていたからなんとなくわかったけど顔見るのは久しぶりなんで。。いや、マジで浦島太郎っすよ。
申し訳ないけど誰だよって思いました。


# 開き直ってカメラつけようぜ

その方はカメラオフでした。声だけで判断しろってどんなクイズですか？IQ200の問題かなにか!?

もうコロナ禍なって3年目ですよ。

リモートワークが一般化して、デメリットとしてコミュニケーションが取りずらいと言うのであれば、個々でやれることしませんか!?
やっぱ声だけより声+顔がわかった方がその時の調子とか温度感わかりやすくないですか!?

・家が散らかっている!?背景ぼかし使いましょう。もしくは背景設定しましょう。

・パジャマのまま!?それでもいいんじゃないですか。自分は上に普段着のコート着てごまかします。
あとはみんながみんな聖人君子じゃないですよ。パジャマかい！ってネタになるのも受け入れましょう。

・恥ずかしい!?そこまであなたに注目していないですよ多分。。


エンジニアの深層心理でなるべく目立ちたくない、影に隠れていたいって意思があると思うんですが、
声だけの人って自分はやりずらいと思います。。

自分はカメラオンでやります。家散らかっててゴメンナサイ!!
【JS】オブジェクト内の要素をキーにして並べ替え

## やりたいこと
以下のようなオブジェクトがあったとします。
今回は各メンバーをscoreの高い順に並べ替えたいと思います。
```
let member = {
0 : {name : 'タナカ', score : 70}, 
1 : {name : 'ヤマダ', score : 80},
2 : {name : 'スズキ', score : 100},
3 : {name : 'サトウ', score : 60},
4 : {name : 'ヨシダ', score : 75}
}
```


## 実装
以下のようにすることで並べ替えることができます。
```js
let result = Object.keys(member)
                    .map(function (key) {
                        return member[key]
                    })
                    .sort(function (a, b) {
                        return b.score < a.score ? -1 : 1 
                    })
```

解説すると、以下の流れで処理を行っています。

① .mapメソッドでオブジェクトのキー配列を取得
② .sortメソッドで並び替え

昇順にしたいときは最後の部分を逆にしてあげればOKです。

```js
let result = Object.keys(member)
                    .map(function (key) {
                        return member[key]
                    })
                    .sort(function (a, b) {
                        return a.score < b.score ? -1 : 1 
                    })
```

是非参考にしてみてください。
Perl で ハッシュ値を生成する

Perlの標準モジュールには、ハッシュ値を生成するモジュールは存在しないので、CPAN(Comprehensive Perl Archive Network)からハッシュ値を生成するモジュールをインストールします。

尚、Windows版のPerlである、Strawberry Perl for Windows では、Strawberry Perl for Windowsをインストールした時にハッシュ値を生成するモジュールもインストールされているため、追加でインストールする必要はありません。

## SHA系ハッシュアルゴリズムのモジュールのインストール (Linux系)

Digest::SHAモジュールには、SHA系ハッシュアルゴリズムを生成する関数が提供されています。

以下のコマンドでDigest::SHAモジュールをインストールします。

```
# sudo cpan Digest::SHA
```

SHA1, SHA256アルゴリズムでハッシュ値を生成し、出力するプログラムです。

```perl
use Digest::SHA qw(sha1 sha1_hex sha1_base64);
use Digest::SHA qw(sha256 sha256_hex sha256_base64);

my $digest1 = sha1_hex('Hello World');
my $digest2 = sha256_hex('Hello World');

print "SHA1\n";
print $digest1;
print "\n";
print "SHA256\n";
print $digest2;
print "\n";
```


## 参考情報
https://ez-net.jp/article/2B/jZqRHUFI/Zpjrf3adK9Mf/
Reactを基本からまとめてみた【30】【import や constで{} を使う時使わない時】

## 【React】import や constで{} を使う時使わない時の違い

##### export defaultで公開してある（コンポーネントなど）<br>⇨ 中括弧なしでimportできる

##### exportで公開してある（関数やフックなど）<br>⇨ 中括弧をつけてimport

```
 //  import時
import hogehoge from 'fugafuga' //①
import { hogehoge } from 'fugafuga'//②
// const宣言時
const hoge = hogehogehoge//③
const { fuga } = fugafugafuga//④
```
##### import時（モジュール機能）
① fugafugaの中でexportする時、export defaultで公開してある。この場合、中括弧なしでimportできる。またimport時に任意の名前に変更可能である。 しかしexport default が使用できるのは1ファイルにつき1個まで。
② fugafugaの中でexportする時、exportで公開してある。この場合、中括弧をつけてimportする。またimport時の名前変更は{ xxx as yyy }とすることで可能。 export は1ファイルの中で何個使用しても問題ない。export default との併用もできる。

##### const宣言時
③ 通常の定数宣言である。任意内容を定義可能。
④ 分割代入といい fugafugafuga= {a:1, b:1, c:1}のような場合、const { a }=fugafugafugaによりオブジェクトの一部を取り出し定数化することができる。



## 参考サイト
[【React】import や constで{} を使う時使わない時の違い](https://zenn.dev/hirof1990/scraps/a0ac0ea372cf02)
[Power Automate] サクサクなデータソースは何か試して比較してみた


# はじめに
:::note info
速度を上げるばかりが、人生ではない。

**マハトマ・ガンディー**（宗教家、政治指導者）
:::
ガンディーは義務教育で習うので説明は不要かと思いますが、関連するトピックとしてつい最近国連本部にガンディーの胸像ができました。

https://www.hokkoku.co.jp/articles/-/938474

現代のビジネスパーソンは忙しいです。バースト的に到着するタスク、なぜか短縮される納期、突然来なくなったエンジニアの尻拭いなど、毎日の業務に忙殺されゆとりのない人生を送っている人も多いでしょう。OA化でオフィスへのコンピュータ普及が始まったのが1990年代。それから30年経ちテクノロジーも進化してもっと便利になったはずですが、不思議なことに私達の仕事にゆとりが生まれる気配は一向にありません。逆に昔と比べてゆとりが無くなったなんて声も聞きます。

仕事だけではありません。いまZ世代の間ではタイパ（タイムパフォーマンス）が重視されるようで、タイパ至上主義なんて言葉もあります。私はZ世代ではありませんがYouTubeとか倍速で視聴してたりするので、図らずもタイパを実践していたことになります。

そんな現代人にガンディーの言葉は我が身を省みるきっかけを与えてくれます。もっと社会全体がゆとりを持ち、できれば週休3日制を導入してほしいというのが私の願いです（勿論給料はそのままで）。

# 本題
ガンディーは速度を上げる必要はないと言っていますが、アプリに関しては基本的に高速であるべきです。ガンディーが現代に転生して「速度を上げるばかりが、アプリではない」などと宣ってもクライアントから怒られるだけです。もし相手が体育会系だったりしたらガンディーの非暴力に付け込んで拳が飛んでくるかもしれません。マイクロソフトもアプリのパフォーマンスについて以下のように言及しています。

https://learn.microsoft.com/ja-jp/training/modules/build-mobile-optimized/mobile-optimized-applications

>アプリケーションのパフォーマンスを最適化する場合は、以下を行う必要があります。
>* 使用されているデータ ソースと、取得するデータの複雑さを検討する。
>* アプリケーションで使用されているデータ コネクタを評価する。
>* 複雑で不必要なデータ ソースを削除しようとする。
>* 特定のアクションに必要な特定の数のレコードのみを取得しようとする。

これを読んでデータソース毎にどの程度差が生まれるのだろうと思ったので検証してみました。比較するデータソースはPower Platformで利用されることが多いであろう以下のものです。

* Dataverse
* Azure SQL Database
* SharePointリスト
* OneDriveに置いたExcel

# 検証方法
Power Automateを使って各データソースにレコードを追加し掛かった時間を計測します。

### Power Automateフロー
こんな感じのフローを作ります。開始時にデータソースと追加するレコード数を指定し、Switchで各々の追加処理へ分岐するという流れです。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/f1f28730-dcad-b89b-89c4-8418f77378e0.png)

レコード追加処理はすべてのデータソース共通でこんな感じです。開始時に指定された回数だけループしてレコードを挿入します。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/481d0131-5962-4b3c-874f-1958c1a4fc0d.png)

開始時の入力内容はこんな感じです。
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/7a234571-641a-f7e0-66ce-b1b98884bafb.png)

### テーブルとデータ
レコードの追加先となるテーブルはこんな感じです。図はAzure SQL Databaseの場合ですが、他のデータソースも似たような型で定義しておきます。
![013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/a18fc4d1-e1e0-aef5-0fc9-f8e438d818b1.png)

テーブルには以下のようなデータをフローから追加していきます。
![014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/be585dc9-aeff-6e0c-eeeb-5309524b0434.png)

### 実行時間の計測
フローの実行履歴で確認します。
![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/2eb52efe-8909-e6b8-cf07-e89d3a8be02b.png)

# 結果
それぞれ3回ずつ実行して平均をとった結果がこちらです。
![015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/fabbe407-285b-68ec-3d3a-e9e6b733dbd4.png)

OneDriveに置いたExcelが飛び抜けて遅いです。他3つはAzure SQL Databaseが若干速いくらいで似たり寄ったりですね。

# 感想
検証前はOneDriveに置いたExcelが一番遅いだろうと予想しており、結果はその通りだったのですが数値は予想以上でした。DataverseとSharePointリストも同様に遅い部類だろうと思っていましたが、Azure SQL Databaseとあまり変わらない結果になったのは意外でした（Webから使うとあんなに遅いのに）。

以上、本記事が仕事と人生において何かしらの参考となれば幸いです。
[Power Automate] メール送信アクションで「テスト接続に失敗しました」と表示された場合の対処

# 事象
メール送信アクションを追加したら「テスト接続に失敗しました。」とエラーになる。

**追加したアクション**
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/4fecd0f5-ff3a-6f0d-802d-8667604d62c1.png)

**エラーメッセージ**
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/64758bf6-80e0-42fc-bb36-8fe8ca73e564.png)

画面の指示通りにサインインしても直らないケースがあるので対処法をメモしておきます。

# 対処
[接続]を選択し"接続の修正"を選択します。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/be4ba744-c4a0-fa8a-72fe-ab2132273e98.png)

アカウントを選択してサインインします。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/e0bbeb84-84af-8da3-3354-c06a94de1c9f.png)

サインインしても解消しない場合は、メール送信アクションの三点リーダーからコネクションの状態を確認します。現在のコネクションに「無効な接続」と表示されている場合は、別の有効なコネクションを選択します。
![016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951879/e31d156d-cd7e-0f67-1dd1-808aba4ecc31.png)
Lightsailで新たなユーザでSSHに接続する

<h2>前書き</h2>
AmazonのLightsailでは管理用の画面から簡単に暗号鍵を生成できます。<br>
今回はその鍵を基にSSHで接続するまでをまとめます。<br><br>
今回の内容はLightsailのLAMPインスタンスで行いました。

<h2>事前準備</h2>
デフォルトユーザー以外のユーザを作成しておく必要があります

<h2>Lightsailの暗号鍵</h2>
当然コンソールからコマンドを入力すれば通常通り暗号鍵/公開鍵を作成し、使用することは可能です。<br>
しかしながら管理画面から簡単に暗号鍵をダウンロードできるため今回はこちらで作成していきます。
新しく鍵を作成し、ログインするまでに
<a href="https://aws.amazon.com/jp/premiumsupport/knowledge-center/lightsail-troubleshoot-lost-ssh-keypair">こちら</a>の手順を参考にします。
<h3>鍵の作成</h3>
まず、Lightsailの管理画面から「アカウント」を選択し、「SSHキー」のタブを選択していきます。

![ssh_adm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2314585/43834f07-2d94-d43a-6aa1-ed7dab9200ad.png)

リージョンを選択し、キーの名前を入力すると作成が完了です。<br>
![region.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2314585/8ca7c45f-845f-6f1f-e968-ba99e73654da.png)
![create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2314585/d1d0b804-f68b-81d2-b36f-e1de9e73dd99.png)

新規作成できた暗号鍵は一度しかダウンロードできないため、注意が必要です。
![done.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2314585/35e698a7-4962-90d8-ba67-951d0bb567ae.png)


<h3>公開鍵の取得</h3>
暗号鍵をダウンロードできた後は、そのファイル(pem)から公開鍵を取得します。<br>
使用している端末のコマンドラインから以下のコマンド実行すると公開鍵の内容が表示されます。

 `ssh-keygen -y -f 暗号鍵のファイルパス`

![command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2314585/a88213dd-3fc0-9da0-1857-d8661fcf6ea7.png)


<h3>公開鍵のアップロード</h3>
ユーザのホームディレクトリに.ssh/authorized_keysを作成し上記の公開鍵を記録しておきます。<br>
今回は中を確認するために直接弄って記録しましたが、ssh-copy-idなどを介すと楽に行えるようです。

<h3>SSHログイン</h3>
ダウンロードした暗号鍵を使用して接続してみます。コマンドプロンプトからアクセスするには以下のように接続します。

```
ssh -i 暗号鍵 ユーザ名@接続先ホスト
```

<h2>参考文献</h2>
https://dev.classmethod.jp/articles/amazon-lightsail-ssh-key-options/ <br>
https://aws.amazon.com/jp/premiumsupport/knowledge-center/lightsail-troubleshoot-lost-ssh-keypair/<br>
https://qiita.com/kentarosasaki/items/aa319e735a0b9660f1f0
NodeでDESしてみる

codesandbox.ioにSign up
dashboard>Create>Quick start>Node.js
index.jsに以下を貼り付け、CTRL+Sで保存すると、実行結果が表示される
```
const crypto = require("crypto");
const algorithm = "des-ecb";
const key = Buffer.from("mykeystr", "utf-8"); // 8バイト

const cipher = crypto.createCipheriv(algorithm, key, null);
const encrypted =
  cipher.update("暗号化対象文字列", "utf8", "hex") + cipher.final("hex");
console.log(encrypted);

const decipher = crypto.createDecipheriv(algorithm, key, null);
console.log(decipher.update(encrypted, "hex", "utf8") + decipher.final("utf8"));
```
Perlのインストール、プログラムの実施

## WindowsにPerlをインストールする

### 必要となるアプリケーション

Windows版のPerlは幾つかありますが、今回は以下をインストールします。

* Strawberry Perl for Windows

Strawberry Perl を以下からダウンロードしてインストールします。

https://strawberryperl.com/

## Rocky Linux に Perlをインストールする

### Perlがインストールされているか確認する

以下のコマンドを実行してPerlがインストールされているか確認します。

```
# perl -v
```

### Perlをインストールする

Perlがインストールされていない場合、以下のコマンドを実行して、Perlをインストールします。

```
# yum install perl
```

## Perlのプログラムを実行する

### 直接、コマンドラインから実行する

```
# perl e 1行のプログラム
```
Rocky Linux では、

```
# perl -e 'print "Hello World"'
```

又は、

```
# perl -e "print 'Hello World'"
```

Windowsの Strawberry Perl for Windows では、

```
> perl -e "print 'Hello World'"
```

### プログラムファイルを指定して実行する

```
perl プログラムファイル名
```

```
> perl HelloWorld.pl
```

### プログラムファイルに実行権限を与えて実行する。(Linuxを始めとする Unix系のOSのみ)

プログラムファイルの1行目にperlのパスを記述します。

```
#!/usr/bin/perl
print 'Hello World'
```

プログラムファイルに実行権限を与えて実行します。

```
# chmod +x HelloWorld.pl
# ./HelloWorld.pl
```

## 参考情報
https://eng-entrance.com/linux-perl
https://perlzemi.com/blog/20180813153411.html
薄いコントローラ、分厚いコントローラとは何か

MVCモデルを用いて開発をしている際、「薄いコントローラ」や「分厚いコントローラ」という言葉をよく聞くかと思います。
薄いコントローラとはなんでしょうか？分厚いとどうなるのでしょうか？
コントローラの整理をキッチンの棚の整理に例えて説明していきます。


# コントローラってどうやって書いたらいいんだっけ？
Railsの生みの親であるDHHは下記のように言っています。

>コントローラが元々持っているRESTアクションやデフォルトの5つの機能にはないメソッドを付け加えたいと思ったら、いつだって新しいコントローラを作る。それだけでいいのです。

https://postd.cc/how-dhh-organizes-his-rails-controllers/

5つの機能って何？という方は、ぜひ調べてみてくださいね。
7つのアクションと言われていることの方が多いかもしれません。

https://qiita.com/morikuma709/items/5b21e9853c9d6ea70295


7つのアクションを用いたコントローラの作成方法について少しだけ解説すると、、、
ある機能を実現すると言う役割を持ったコントローラの中に、必要に応じてindex, new, create, edit, show, updateという7つのアクションを最大一つまで配置します。

7並べと似ているかもしれません。
同じスートごとに1〜Kまでのカードを並べるのが7並べです。
ハートの列にスペードのカードを並べることはできません。

コントローラも同様で、メンバー管理機能を持つコントローラにメール受信一覧機能を持たせたアクションを含めることはできません。
(できないというより、責務が異なるのでその機能は持たせるべきではない。)
これならコントローラ内のアクションは最大7つまでとなり、いわゆる分厚いコントローラができることはないように感じます。

しかし、そう上手くはいきません。
システムが大きくなればなるほど色々な機能を追加したくなり、それに応じてコントローラに追加したいアクションも増えていくのです。

# コントローラが分厚くなっていく原因
>例えば、 InboxController があって、メールの受信ボックス内にあるものを全部表示する index があるとします。もしかすると、別のアクションも入れるかもしれません。例えば、「未送信メールとかも見られた方がいいな。未送信もindexに表示させるか何かしよう」と思うかもしれませんね。そうしたら pendings というアクションを追加します。

https://postd.cc/how-dhh-organizes-his-rails-controllers/#:~:text=%E3%81%84%E3%81%84%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82-,%E4%BE%8B%E3%81%88%E3%81%B0,-%E3%80%81%20InboxController%20%E3%81%8C

このように、7つのアクションに該当しないアクションを追加してしまいたくなる時があります。
(上記の例で言うとpendingsアクション)

しかし、そこでアクションを追加するのではなく、PendingsControllerを追加すればいいのです。
PendingsController内にpendingsアクションを追加すれば、InboxControllerを太らせることなく未送信メール一覧機能の実装ができます。

実はこの現象は身近な場所でも起きています。

# 整理されないと肥大化するのはコントローラだけじゃない
あなたは友人のキッチンで料理を振る舞うことになりました。
友人宅にある材料がわからなかったので、一旦食材の確認をすることになりました。
カレーを作ろうかななどと考えながらキッチンの棚を開けてみると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/7ae00e63-4d24-4257-fa6a-bca5069a0600.png)
そこには整理されておらず、どこに何があるのかわからないギチギチの棚が存在していました。
一応ざっくりと食べ物とそれ以外で分かれているようです。

友人曰く、「食べ物だけ分けておけば大丈夫っしょ」とのことです。
そんなわけありません。
調味料や保存食品たちに埋もれた野菜が腐っていく様が目に浮かびます。

こんな無秩序な棚だとどんどん汚れていってしまうことが容易に想像できますよね？
このような現象は割れ窓理論と呼ばれ、ひとつの無秩序を放置すると全体が無秩序になっていってしまうのです。

たった一つのpendingsアクションを許容してしまうと、そこからどんどんとアクションが増えて大きなコントローラになってしまうかもしれません。

>「割れ窓理論」とは、アメリカの犯罪学者ジョージ・ケリング博士により提唱されたもので、1枚の割れた窓ガラスを放置すると、割られる窓ガラスが増え、その建物全体が荒廃し、いずれ街全体が荒れてしまうという理論です。

https://www.pref.yamanashi.jp/police/p_anzen/anzenansin/jishubouhan_waremado.html



# 散らかったコントローラを整理しよう
先程登場した無秩序な棚を整理してみました。
食べ物は「保存食系」「調味料」「野菜」「お菓子」に分け、その他は「調理器具」「お皿」「カトラリー」に分けました。
このように目的ごとに分類して収納することで、料理や盛り付けをするときに最短時間でものを探して手に取ることができます。

また、調理を開始する前に調味料棚を確認することで、足りない調味料がある場合はそのことにすぐに気付くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/6f2c0737-cc51-fb7c-3226-7c830b79d2a0.png)

コントローラも目的ごとに細かく分類することで、より使いやすくなります。
どのコントローラがどの責務を担っているのかが明確になり、コントローラに手を加えて分厚くしてしまう事故を減らせます。
また、自分が作ったコントローラを他の誰かが保守を行う時にも、キッチンと同様に整理されていた方が作業時間を短縮することができます。



# まとめ
分厚いコントローラとは、本来は負うべきでない責務を負ってアクションの数が増えすぎてしまったコントローラのこと。
整理されていない他人のキッチンで料理をするような大変さが、分厚いコントローラの保守を行う際に生じてしまう。

何でもかんでも詰め込んでしまうと良くないのは、キッチンの棚もコントローラも一緒だと言うことですね。
Playwright 1.29の新機能 Backend API Mockingは request.fetchでは効かないよ。

API Mockingという機能がPlaywright 1.29でリリースされました。

ブラウザでアクセスしたページが、裏でJSON APIを（Ajaxだったりfetch APIだったりで)叩く際に、そのコンテンツを差し替える、というもの。

公式ドキュメントにある以下のサンプル

```python
def handle(route):
    response = route.fetch()
    json = response.json()
    json["message"]["big_red_dog"] = []
    # Fullfill using the original response, while patching the response body
    # with the given JSON object.
    route.fulfill(response=response, json=json)

page.route("https://dog.ceo/api/breeds/list/all", handle)
```

### APIモックが効くもの

* `page.goto("https://dog.ceo/api/breeds/list/all")`
* `page.evaluate('() => fetch("https://dog.ceo/api/breeds/list/all")')`


### APIモックが効かないもの

* `page.request.get("https://dog.ceo/api/breeds/list/all")`


あくまで、ブラウザでページアクセスする際ののバックエンドAPIをモックするための仕組みであり、PlaywrightのAPI testing (request.fetch)は対象外のようだ。

Route.fetch が内部的に request.fetchを使っており、そう簡単にrequest.fetchをモックできないという事情がありそう。

https://github.com/microsoft/playwright/pull/19184/files#diff-a649a45cc7f499fa047e8c8fb00bff4019b921ba834a6d124e8c7fa3e7324f14R313