OmniAICreator/Qiita-1.07M huggingface dataset:
ROS for WindowsでChocolateyがインストールできない問題

### 発生したエラー
ROSの[公式](http://wiki.ros.org/Installation/Windows)通りインストールしていると，chocolateyのインストール時に

```
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

警告: An existing Chocolatey installation was detected. Installation will not continue.
For security reasons, this script will not overwrite existing installations.

Please use choco upgrade chocolatey to handle upgrades of Chocolatey itself.
```

こんな警告が出てくる．

### 解決策
すでにchocolateygが存在していると言ってくるので，
C:\ProgramData\chocolateyフォルダを削除して実行するとインストールできた．

### 原因
以前chocolateyをインストールしかけたときに残っていたフォルダが悪さしたみたい．
PowerAutomateでSPOサイトページを更新し公開する

Office365（Microsoft365）で、ユーザーオペやスケジュールをトリガーに自動起動する連携処理を実装するのに便利なPowerAutomateですが、実際に業務の中で使おうとするといろいろな制約があります。
そのような制約を克服するため思いついたり調べたりした内容をご紹介していこうと考えています。

# Background

SPOサイトのページは内部的にSPOリストの項目として管理されているようです。
これは特に調べたわけでもなく、作業中の手違いで気が付きました。調べてもそのようなことを説明してくれている記事は見つかりませんでした。

それはそれとして。

私の職場ではSPOサイトの1つであるTeamsチームサイトをポータルサイトとして活用しています。
そのサイトで公開しているページやニュースたちも、SPOリストの項目としてPowerAutomateからいろいろ操作できれば、サイト管理業務の改善ができそうです。

# Problem

しかしPower AutomateでSPOリストを参照更新するアクション（ステップ）を使う時、アクセス可能なリストの一覧を示すプルダウンに、サイトのページを管理するリストは登場しません。

さあ、早くも雲行きが怪しくなってきました。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/295bf8a8-ea1b-2c0e-4041-d50c0a3b9d86.png)

# Solution

あれこれ調べた結果はこうです。

まず項目を取得する場合、「複数の項目の取得」アクションの「リスト名」で「カスタム値の入力」を選び「サイトのページ」と記載します。ちょっと違和感がありますが、ちゃんと動きます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/a89e8d3b-ab05-f742-060a-06142456392e.png)

取得した項目を更新するには、RESTfulAPIを利用しましょう。予め準備された「項目の更新」よりもシンプルに、更新が必要な項目だけ指定できます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/dc7ba2bb-cd4a-8194-b99f-7f583ca096a7.png)

「URL」欄には以下の要領で入力をします。リスト項目ID以外は固定です：

```
_api/web/lists/GetByTitle('サイトのページ')/items(<リスト項目ID>)
```

「ヘッダー」欄の内容は固定です：

| キー | 値 |
|:-:|:-:|
| Content-Type  |  application/json;odata=verbose |
| X-HTTP-Method  |  MERGE |
|  IF-MATCH | *  |

「ボディ」欄には以下の要領でJSON文字列を指定します：

```js
{
    "__metadata": {
        "type": "SP.Data.SitePagesItem"
    },
    // ここに更新したいプロパティと値のペアを列挙
}
```

SPOでページやニュースを作成された方ならご存知かと思いますが、サイトのページは更新して保存（下書き保存）しただけでは、他のユーザーも見るページの見栄えに変更が反映されません。

そこで「公開」（Publish）します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/bc1f6fe7-fb15-d308-8db6-636b6eacf3c1.png)

「URL」欄には以下の要領で入力をします。リスト項目ID以外は固定です：

```
_api/sitepages/pages(<リスト項目ID>)/publish
```

「ヘッダー」欄の内容は固定です。X-HTTP-Methodの値が「POST」であることに注意をしてください：

| キー | 値 |
|:-:|:-:|
| Content-Type  |  application/json;odata=verbose |
| X-HTTP-Method  |  POST|
|  IF-MATCH | *  |

「ボディ」欄には以下の要領でJSON文字列を指定します。ここでもJSONの内容、とくに"__metadata" の値が変化していることに注意をしてください：

```js
{"__metadata":{"type":"SP.Publishing.SitePage"}}
```

以上でサイトのページを更新し、公開することができます。

おめでとうございます。

これでSPOサイトのページをいろいろなトリガーでもって自動更新できるようになりますね。
PythonでPhotoshopのアクション自動化ツールを作ってみた

普段趣味で写真撮影をしているエンジニアです。
大量の写真を色味調整などをすると結構時間かかりますので自動化のツールを作ってみました。

今回はPhotoshopのアクション機能を自動的に実行、保存のツールを作ってみます。

![XCJ3RlVgiNI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451854/0c020431-7a50-7f14-02fb-7ce162e1d643.png)
という簡単の構造です。

今回はphotoshop-python-apiというオープンソースライブラリを使います。

https://github.com/loonghao/photoshop-python-api

![スクリーンショット 2021-06-10 122253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451854/e7abcd44-d2d7-81bc-f92b-a86f19c1700b.png)
Photoshop内作ったアクション（例）


```python:main.py
import os
import photoshop.api as ps
import glob

def main():
    
    # APIインスタンス
    instance = ps.Application()
    # 画像のパス(今回は.pyファイル下のimageフォルダ内のJPGファイル)
    filespath = './image/*.jpg'
    # フォルダ内のファイル名を取り出す
    files = glob.glob(filespath)

    # メインループ
    for f in files:
        # パスを絶対パスに変更
        abspath = os.path.abspath(f)
        # 画像をロード
        img = instance.load(abspath)
        # アクションを実行(アクション名,アクショングループ名)
        instance.doAction('P3', 'Skin')
        # 画像を保存(パス,保存のファイル形式,ファイルを置き換える)
        img.saveAs(abspath, ps.JPEGSaveOptions(), asCopy=False)
        # 画像を閉じる
        img.close()

if __name__ == '__main__':
    main()
```
Ubuntu server 20.04.2 をリモートデスクトップ専用機としてセットアップする。

# はじめに
Ubuntuに限らず、パソコン関連のやり方類はWebサイトをいくつか見る必要があり、場合によっては数十ものサイトを見比べて取捨選択する必要があります。 この記事はそうしたやり方類をまとめて書いていきます。 今回はUbuntu serverをリモートデスクトップ接続専用機としてセットアップする方法をまとめます。
#### この記事でできること
Ubuntu server をインストールしてすぐの状態から、リモートデスクトップ専用機としてセットアップしてアクセスできるようにします。 追加でそのサーバーを使ってMinecraft Spigotサーバーを構築します。
#### 対象読者

* コマンド操作がわかる人
* コマンド操作がわからない人
* Ubuntu server 単機でリモートデスクトップを構築したい人

# 目次

1. Ubuntu Desktop のインストール
1. Xrdp をインストールして立ち上げる
1. ファイアウォールの設定
1. rootログインの無効化
1. 再起動して接続確認

# 1. Ubuntu Desktop のインストール
リモートデスクトップ環境を整えるにはUbuntu Desktopが必要なのでインストールします。ダウンロードおよびインストールには時間がかかるので気長に待ちましょう。

* パッケージのインストール

```
sudo apt-get -y install ubuntu-desktop
```

* 無効化

Ubuntu Desktop がインストールできたら、念のためにCUIベースで起動するように再設定します。

CLIで起動

```
sudo systemctl set-default multi-user.target
```

メモ：GUIで起動
`$ sudo systemctl set-default graphical.target`

# 2. Xrdp をインストールして立ち上げる
リモートデスクトップで接続できるようにサーバーを立ち上げます。
#### インストール

```
sudo apt -y install xrdp
```

#### 有効化

```
sudo systemctl enable xrdp
```

メモ：無効化
`$ sudo systemctl disable xrdp`
#### 確認
Active : active (rinnning)と表示されれば成功です。
"Q"キーを押して終了しましょう。

```
sudo systemctl status xrdp
```

# 3. ファイアウォールの設定
そのままサーバーを使うのは危険なので、ポートを使うものだけ開きます。
#### 有効化
ファイアウォールを有効化します。

```
sudo ufw enable
```

メモ：無効化
`$ sudo ufw disable`
#### 全体の閉鎖
全てのポートを閉じます。

```
sudo ufw default deny
```

メモ：すべて開放
`$ sudo ufw default allow`
#### ポート開放
xrdp では 3389 番のポートを使うのでそれを開放します。
別途必要なポートがあれば都度開放します。

xrdp 用ポート開放

```
sudo ufw allow from any to any port 3389 proto tcp
```

メモ：ポート開放
`$ sudo ufw allow [ポート番号]`
`$ sudo ufw deny [ポート番号]`

#### リロード
ポート開放の設定が終わったらリロードします。

```
sudo ufw reload
```

#### 確認
設定したポートが ALLOW になっている確認します。

```
sudo ufw status
```

# 4. rootログインの無効化
リモートデスクトップ専用なので一応rootログインを無効化しておきます。
### 無効化

```
sudo passwd -l root
```

メモ：有効化
`$ sudo passwd -u root`

# 5. 再起動して接続確認
再起動したら接続したいPCに移動して作業します。今回はWindowsを使います。

```
reboot
```
### リモートデスクトップ接続を起動
検索欄にリモートデスクトップと入力すると”リモートデスクトップ接続”が表示されるので起動し、Ubuntu serverに割り当てられたローカルIPアドレスを入力して接続します。 xrdpのログイン画面が出てくるので、Ubuntuのユーザー名とパスワードを入力して入ります。 左上にウィンドウが表示された場合はユーザー名かパスワードが間違っている可能性があるのでもう一度入力します。
# 以上
リモートデスクトップ専用機としてのセットアップはこれで終了です。
# 参考サイト一覧
https://tadaoyamaoka.hatenablog.com/entry/2018/01/10/233519
https://minokamo.tokyo/2020/08/16/2687/
https://lifework-blog.com/ubuntu-server-firewall/
PowerAutomateで正規表現マッチ

Office365（Microsoft365）で、ユーザーオペやスケジュールをトリガーに自動起動する連携処理を実装するのに便利なPowerAutomateですが、実際に業務の中で使おうとするといろいろな制約があります。
そのような制約を克服するため思いついたり調べたりした内容をご紹介していこうと考えています。

# Problem

PowerAutomateの性質上、ユーザーから送られてきたメールやTeamsメッセージを解析して、その結果次第で何かしらのアクションを実行するというシナリオは、大いに有り得るものだと思います。
しかし、PowerAutomateには正規表現マッチを行うための組み込みの方法が存在しません。
サードパーティの提供するアクションで正規表現による処理を提供してくれるものもあるのですが、組織のポリシーなどの関係で、それを利用できないということもしばしばあります。

# Solution

[以前ご紹介](https://qiita.com/mizukyf/items/d0bbbf834a28538ef58c)した方法で対処します。
「きれいな方法」とは言い難いですが、比較的シンプルで、PowerAutomateの他の制約の克服も含めた一般的な課題解決にも応用可能という意味で、気に入っているものです。
対策検討にあたり[こちらの記事](https://mofumofupower.hatenablog.com/entry/2020/05/11/084927)を参考にさせていただきました。こちらのブログではPowerAutomate活用のヒントがたくさん紹介されています。

## 1. O365上でExcelファイルを用意

まずはO365上にExcelファイルを用意します。
PowerAutomateから（PowerAutomateのフローを実行するユーザーから）参照可能なところであればどこでも結構です。

## 2. OfficeScriptでソートを実装

先程作成したExcelファイルを開くとメニューに「自動化」というタブが表示されます（ファイルを開いてから数秒待たないと表示されないことがあります）：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/b05f3e8e-792a-a987-f845-8c2699dd9e07.png)

ここから「自動化」→「すべてのスクリプト」→「＋新しいスクリプト」と進み、表示されたコードエディターで関数を定義します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/685cdcaa-ed80-f5aa-3a8e-166e63bb665c.png)

```ts
function main(
  workbook: ExcelScript.Workbook,
  searchString: string,
  regexPattern: string,
  regexFlags: string
) : Array<string> {
  return searchString.match(new RegExp(regexPattern, regexFlags)) ?? [];
}
```

配列ソートの例では、スクリプトが `Array<object>` を戻り値とすることができないという問題がちょっとした障碍になりましたが、 `Array<string>` ならば問題ありません。

他のユーザーのフローからも実行する可能性がある場合は、「すべてのスクリプト」の一覧で「...」→「共有」をクリックしておきましょう：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/4200f5cd-5614-a425-8830-5fcb718f1c83.png)

## 3. 「スクリプトの実行」アクションをセットアップ

PowerAutomateのフロー側で「スクリプトの実行」アクションをセットアップします：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/b7474bc3-4305-c1f5-2167-db1e1768f362.png)

ちなみにこの画面キャプチャにあるアクションを実行すると結果は以下のようなJSONになります：

```js
{
  "result": [
    "foo",
    "bar",
    "baz",
    "123"
  ],
  "logs": []
}
```

以上で、任意の文字列に対して、任意の正規表現パターンを使ったテストができるようになりました。
「px」と「em」と「rem」の違い

<h2>「px」</h2>
→絶対単位。
親要素の影響を受けずに、どんな状況でも指定したpxになる。
ユーザー操作による文字サイズの拡大／縮小に対応できなかったり、タブレットやスマートフォンなどの高解像度のディスプレイで表示をした場合、端末ごとに見た目の文字サイズが異なって表示されたりする場合がある。
<h2>「em」</h2>
→相対単位。
親要素のフォントサイズを基準とする。

```
<div class="box">
    <p class="text">テキストテキストテキスト</p>
</div>
```
```
html {
    font-size: 16px;  /* 1em = 16pxとなる。 */
}
.box {
    font-size: 2em;  /* 16px × 2 = 32px */
}
.text {
    font-size: 1.5em;  /* 32px × 1.5 = 48px */
}
```
入れ子構造が深くなるとフォントサイズ指定がし辛くなる。

<h2>「rem」</h2>
→相対単位。
ルート要素（html）のフォントサイズを基準とする。

```
<div class="box">
    <p class="text">テキストテキストテキスト</p>
</div>
```

```
html {
    font-size: 16px;  /* 1rem = 16pxとなる。 */
}
.box {
    font-size: 2rem;  /* 16px × 2 = 32px */
}
.text {
    font-size: 1.5rem;  /* 16px × 1.5 = 24px */
}
```

<h2>font-size: 62.5%;って何？</h2>
フォントサイズの単位にremを使いたい場合、htmlのフォントサイズが16pxのままだと分かりづらい。

```
html {
	font-size: 62.5%;
}
```

16px（ブラウザの基本のフォントサイズ） × 0.625 = 10px

htmlのフォントサイズが10pxになるので、
1rem = 10pxに設定することがきる。
こうすることによって計算がしやすくなる。

例）
10pxにしたい場合 = 1.0rem
16pxにしたい場合 = 1.6rem
36pxにしたい場合 = 3.6rem


<h2>補足</h2>
アクセシビリティ的にフォントサイズのpx指定はNGらしい
PowerAutomateでHTTP要求するためSPOリスト項目の型名を調べる

Office365（Microsoft365）で、ユーザーオペやスケジュールをトリガーに自動起動する連携処理を実装するのに便利なPowerAutomateですが、実際に業務の中で使おうとするといろいろな制約があります。
そのような制約を克服するため思いついたり調べたりした内容をご紹介していこうと考えています。

# Problem

[前回のTIPS](https://qiita.com/mizukyf/items/3a923cbde7462db7b540)では、SharePointが公開するRESTfulAPIを利用してリスト項目を更新する例を示しましたが、そこでは以下のようにHTTP要求本文に項目の型名を指定する必要がありました：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/da0a7c6f-d468-aa11-a928-12c2a9bd1d20.png)

ところで、この型名はいつでも簡単に調べられるものとは限りません。

予め決まった名前であったり、予め決まったルールに基づいて付与されているものであっても、そもそもSharePointのRESTfulAPIやそれに関連する仕様の詳細を示す資料が見つからないので困ってしまいます。。

# Solution

あれこれ調べ回って見つけた調査方法はRESTfulAPIそのものを使って調べる方法でした（参考にしたWebページは[こちら](https://nishantrana.me/2013/10/03/a-type-named-sp-data-listitem-could-not-be-resolved-by-the-model-when-a-model-is-available-each-type-name-must-resolve-to-a-valid-type-error-in-sharepoint-2013/)）。

Webブラウザのロケーションバーに以下のようなURLを入力してEnterを押下します：

```
https://<site-domain>/<site-path>/_api/web/lists/<list-name>?$select=ListItemEntityTypeFullName
```

Teamsチームサイトの「サイトのページ」のように内部名と表示名（タイトル）が異なっているリストの場合は、以下のようにします：

```
https://<site-domain>/<site-path>/_api/web/lists/getbytitle(<list-title>)?$select=ListItemEntityTypeFullName
```

すると、以下のような応答が得られます。このXMLの d:ListItemEntityTypeFullName 要素で囲われた値が型名です：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/6af6815a-d1d0-e078-9b65-44ce1fe60540.png)
PowerAutomateでSPOリストのハイパーリンク代替テキストを設定

Office365（Microsoft365）で、ユーザーオペやスケジュールをトリガーに自動起動する連携処理を実装するのに便利なPowerAutomateですが、実際に業務の中で使おうとするといろいろな制約があります。
そのような制約を克服するため思いついたり調べたりした内容をご紹介していこうと考えています。

# Background

Power AutomateはO365に統合されているので、SharePoint Online（SPO）のリストに対して、項目（要素）の参照＆更新を行うことができます。

SPOリストの列のデータ型には「一行テキスト」や「数値」などとともに「ハイパーリンク」というものもあります。当該型のカラムに設定したテキストは、SPOの画面表示上、文字通りハイパーリンクとして表示され、クリックすると画面遷移が発生します。

ハイパーリンクはデータの内部表現としては `Url` と `Description` という2つのプロパティを持っており、リストの項目を追加したり更新したりする際に表示されるフォームでは「URL」と「代替テキスト」という名前で表されています：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/4cde4d46-862d-03f9-3bfc-1b84ac4553a6.png)

ここまではなんてことのない話だと思います。

# Problem

ところで、現時点（2021年5月頃）では、Power Automateでリスト項目を追加したり更新したりするときに使用するアクションは、ハイパーリンク型の列の `Url` と `Description` の個別指定はサポートされておらず、 `Url` と同じ値が `Description` にも設定されてしまいます。 [^1]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/7fedcd14-79b7-0fc7-6ef4-d103f74397f7.png)

実際に「項目の作成」や「項目の更新」でリスト項目のハイパーリンク型の列に値を設定するとこんなかんじです：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/04373c66-65cb-0706-5ef9-6ea90f2ecc88.png)

# Solution

幸いにも（驚くべきことに？）PowerAutomateにはSPOのRESTfulAPIに直接リクエストを送りつけるためのアクションが用意されています。今回はこのアクションを使います。

簡便のため次のようなステップを踏んで、ハイパーリンクの `Description` を設定してみましょう：

1. 「項目の作成」アクションで項目を追加（この時点ではハイパーリンクのUrlのみ設定される）
2. 「SharePointにHTTP要求を送信します」アクションで項目を更新（この時点でハイパーリンクのDescriptionも設定される）　[^2]

まずは「項目の作成」アクションで、目的のリストに項目を追加します。この時点ではご覧の通り、Urlしか指定しません（指定できません）：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/103b1bdf-2ba3-16f4-fa26-c74609ef7225.png)

続いて「SharePointにHTTP要求を送信します」アクションで項目を更新します。ここでDescriptionを指定します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/63e4eb23-92fc-3931-54b7-2b12c66cc92a.png)

「URL」欄には以下の要領で入力をします：

```
_api/web/lists/GetByTitle('<リスト表示名>')/items(<リスト項目ID>)
```

リスト表示名とリスト項目ID以外は固定です。リスト表示名はSPOサイト画面上で表示されているリスト名です。

SPOではリスト表示名とは別にリスト名（内部名とも呼ばれる）を持っており、2つは区別されています。リストを作成するとき、数字で始まる名称やアルファベット以外の文字を含む名称を指定すると、リスト表示名とリスト名（内部名）は乖離します。リスト名（内部名）を確認する方法は後述します。

「ヘッダー」欄の内容は固定です：

| キー | 値 |
|:-:|:-:|
|  Content-Type |  application/json;odata=verbose |
| X-HTTP-Method  |  MERGE |
| IF-MATCH  |  * |

「ボディ」欄には以下の要領でJSON文字列を指定します：

```js
{
    "__metadata": {
        "type": "SP.Data.<リスト名>ListItem"
    },
    "Link":{
        "Description": "<代替テキスト>",
        "Url": "<URL>"
    }
}
```

先程「URL」に記載したのはリスト表示名でしたが、今度「ボディ」に記載したのはリスト名（内部名）であることに注意をしてください。

リスト名（内部名）はSPOでリストを表示した時、ロケーションバーに表示されるURLで判断できます：

```
https://＜ドメイン名＞/＜中間パス＞/Lists/＜リスト名＞/AllItems.aspx
```

このフローを動かしたあと、SPO画面で項目を確認すると、ご覧のように「代替テキスト」が設定されたことを確認できます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/a0b5a00a-072a-e47e-3762-482639f9e3d5.png)

「ローコード開発」の現実を見る思いですが、Power Automateに精通するに従ってこうした知識が増えていくのかもしれません。。

[^1]: まったく調べていないので憶測でしかありませんが、ハイパーリンク型のように複数のプロパティを持つデータ型は、その多くが、リスト項目の追加・更新アクションのサポート対象外（不完全なサポート状態）となっているのではないかと考えています。

[^2]: 「SharePointにHTTP要求を送信します」アクションで項目の追加を行えば1アクションで済むのですが、手書きのコードをなるべく減らしたいためこのようにしています。
AndroidStudioのMainActivityクラスについて

今回はAndroidStudioのMainActivityクラスについてまとめていきます。

##サンプルコード

```MainActivity.kt
package com.websarva.wings.android.hellosample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
```

プロジェクトを作成すると、上記のコードが自動で入力されます。
それぞれにどんな意味があるのかを噛み砕いれいきます。

##解説

####``class MainActivity : AppCompatActivity()``
　∟MainActivityと言う子クラスに、AppCompatActivityと言う親クラスの継承を定義している。
　　∟つまり、MainActivityクラスは、AppCompatActivityクラスの要素を引き継ぐことができる。

``AppCompatActivity``
　∟AppCompatActivityクラスは、Activityクラスの子クラスです。かつては、Activityクラスを継承して、アクティビティクラスを作成していましたが、通常は、AppCompatActivityクラスを継承してアクティビティクラスを作成します。

つまり、
Activityクラス
　∟AppCompatActivityクラス
　　∟``MainActivityクラス``
という構造になっている。

AppCompatActivityクラスの``onCreate()``メソッドは、androidアプリが起動すると、実行されるメソッドです。
　∟画面作成やデータの用意など、初期処理として必要なものを記述する。

##onCreate()メソッドの中身
####``super.onCreate(savedInstanceState)``
　∟親クラスのonCreateメソッドを呼び出している（AppCompatActivity）
　∟アクティビティクラスはActivityクラスをを継承して作る必要があります。
　∟onCreateメソッドを、Activityクラスから、オーバーライドする必要があるため、この記述が必要があります。

####``setContentView(R.layout.activity_main)``
　∟このアプリで表示する画面の設定をしています。
　∟今回は activity_main.xmlに記述したものを画面として使うので、引数を　「R.layout.activity_main」としています。



##リソースを管理してくれるRクラス
``setContentView(R.layout.activity_main)``で使用されている「R...」について見ていきます。

android開発では、resフォルダ内のファイルや「@+id」の値などのリソースを、Kotlinクラスから効率よく利用できるように、Androidではそのファイルや値を識別する為のJavaのint型定数を指定することになっています。
このint定数をまとめて記述するクラスとして、``Rクラス``を用意し、そこにAndroidStudioの方で自動追記してくれる仕組みになっています。
これにより、``Rクラス中の定数（R値と呼ぶ）``を使ってリソースをやり取りできる。

ちなみに、　``「R.layout.activity_main」``は、``「res/layout/activity_main」``と同じ意味。
tailwindcssでヘッダー、フッダーの固定

tailwindcssでヘッダー、フッダーの固定するために検討した事項をまとめた。
# 結論
```
<body class="bg-blue-500">
    <div class="flex flex-col h-screen">
        <div class="bg-blue-500 sticky top-0">header</div>
        <div class="bg-green-500 flex-grow">
            content<br>(省略)
        </div>
        <div class="bg-blue-500 sticky bottom-0">footer</div>
    </div>
</body>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/67cdb384-7dc3-bdde-11c7-6a6962c9e9c6.png)


# ポイント
* flex,flex-colで縦に整列
* h-screen,flex-growでコンテンツの縦幅がウィンドウより小さいときに広げる
* sticky top-0でヘッダーを固定
* sticky bottom-0でフッターを固定（これはお好み。個人的にはコンテンツ縦幅が小さくなるのが嫌なので、要件として求められたときのみ利用する）
* bodyにヘッダーとフッターの同色を指定（スクロールでヘッダーより上、フッターより下がちらっと見えてしまうため。ヘッダーとフッターを同色にする制約が生まれる）

# 補足
ヘッダーとフッターの色を分けたい場合もあるかもしれない。以下2つは検討の余地あり。

* javascriptでスクロール時にBackgroundの色を変更する
https://teratail.com/questions/28440

* linear-gradientを利用してBackgroundを2色にする(Tailwindはこれに対応していない)
https://qiita.com/C-3PHobbit/items/1b53d5dd792111ed5a78
GCPからAzureへの移行後SSH接続できず

## 症状
Linux　VMでは、ASRを介してGCPからAzureに移行した後、SSH接続ができません。

## 原因と解決
原因はGoogleサービスが有効されてるからです。

シリアル コンソールからVMにログインし、以下のサービスが有効されているかを確認してください。

```bash
google-accounts-daemon.service         enabled
google-clock-skew-daemon.service       enabled
google-instance-setup.service          enabled
google-network-daemon.service          enabled
google-osconfig-agent.service          enabled
google-shutdown-scripts.service        enabled
google-startup-scripts.service         enabled
```

上記のGoogle サービスが有効になっている場合は、無効にしてVMを再起動してください。SSHは再起動後にSSHができるはずです。
コード補完が壊れた時の対処法　と　ドキュメント表示が壊れた時の対処法 (Android Studio)

#####「コード補完」＝予測変換してくれる
ex)Futu→Futureのように。
#####「ドキュメント表示」＝カーソル合わせると使い方、定義を表示してくれる
![スクリーンショット 2021-06-10 11.09.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007371/810eddcc-3a6c-0271-9044-ca49e12aab97.png)



コード補完が壊れた時の対処法↓
Macなら、メニューバーからAndroidStudio > Preferences を選択します。 Editor > General > Code Completion を選んで、"Show suggestions as you type" にチェックが入っていればOK。
または、File > Power Save Modeのチェックを外す。

ドキュメント表示が壊れた時の対処法↓
File > Settings > Editor　
"Show quick doc on mouse move"にチェックを入れる。

<参考>
https://dtpscriptin.com/android-studio-completion/#:~:text=%E7%92%B0%E5%A2%83%E8%A8%AD%E5%AE%9A%E3[…]%E3%81%A6%E3%81%84%E3%82%8C%E3%81%B0OK%E3%80%82

https://www.deviantdev.com/journal/android-studio-quick-documentation-javadoc-tooltip-not-shown-on-hover#:~:text=This%20shows%20that%20the%20quick,quick%20doc%20on%20mouse%20move%22%20
HerokuでMinecraft1.17を始めようと思ったけど無理だった話

# 結論
```
Heroku無料版のmemoryは512MBしかなく、Minecraftを動かすのはしんどい。
```

あまりこの点を気にせずに色々試してみたのですが、結局ここにぶち当たりました笑

同じ目にあう人が出ないようにメモを残しておこうと思います。
同じくMinecraftサーバにHerokuを使ってみたい人や、1.17へのバージョンアップに詰まっている人の参考になれば幸いです。

※6年ぶりにMinecraftを再開したので、内容に不備があるかもしれません。

# Minecraft1.17リリース
Minecraft1.17が2021/6/9にリリースされました！

https://minecraft.fandom.com/ja/wiki/Java_Edition_1.17

僕自身は6/8にマイクラに復帰し、マルチプレイ用にMinecraftサーバを立てるべく、Herokuを使ってみようとしました。

# サーバ構築手順
基本的には以下のページの通りに進めるだけです。

https://github.com/Brucewastaken/minecraft-server-on-heroku-template

動画版もあったので、上記ページがわかりづらい方はこちらも参考にしてみるといいかもしれません。

https://www.youtube.com/watch?v=EBzkSDBmaoU

# 注意点
上記の手順で進めていたのですが、2点注意点がありました。

- 上記手順はバージョン1.16.5にしか対応しておらず、自分で1.17に上げる必要がある
- 1.17はJava16をベースにしているが、HerokuのデフォルトはJava8である

それぞれの対処法を説明します。

# 対処
## 1.17にバージョンアップ
0. 以下のページから1.17のjarファイルをダウンロード
    0. https://www.minecraft.net/ja-jp/download/server
0. 手順に従ってzipファイルを解凍すると、そのルートディレクトリに`server.jar`というファイルがあるので、1.でダウンロードしたものと差し替える
    0. 差し替え後のファイル名も`server.jar`にすること
0. commit&push

## Java16にバージョンアップ
0. 解凍したルートディレクトリに、`system.properties`ファイルを作成
0. そこへ以下のように記述

```:system.properties
java.runtime.version=16
```

'3. commit&push

【参考】
https://devcenter.heroku.com/articles/java-support#specifying-a-java-version

# 対処後
上記対処を行ってデプロイしてみたら、メモリが足りなくて死にました笑
1.16.5のデプロイも最初に試しており、そちらはギリギリ起動に至ったのですが、1.17は10回くらいデプロイ試してもダメでした。。
Java16になったからでしょうか。（適当）
後は構築手順のアップデートを待つしかなさそうです。

ちなみに、こんな感じで死にました。

```
2021-06-10T01:13:25.767348+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-06-10T01:13:45.212174+00:00 heroku[web.1]: Process running mem=1009M(197.2%)
2021-06-10T01:13:45.223948+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-06-10T01:14:05.224578+00:00 heroku[web.1]: Process running mem=1077M(210.5%)
2021-06-10T01:14:05.226889+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-06-10T01:14:05.230830+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-06-10T01:14:05.286559+00:00 app[web.1]: Error waiting for process to terminate: No child processes
2021-06-10T01:14:05.480845+00:00 heroku[web.1]: Process exited with status 22
2021-06-10T01:14:05.601589+00:00 heroku[web.1]: State changed from up to crashed
```

# 感想
Heroku無料版だとmemoryが512MBしかなく、dyno立ち上げ時にcrashするので実用的ではないですね。。
おとなしく、Conaha VPSを契約した方が良さそうです。
（6/9時点だとConohaがマイクラメジャーアップデートに対応中で利用できず、迂回策でHeroku使ってみたけどダメだった笑）

それかAWSもありかもしれない。
コスパがConahaと比べてどうか次第ではありますが。

# さいごに
Twitterの方でも、エンジニアに関することを発信しているので良かったらチェックしてみてください！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">HerokuでMinecraftサーバを立てようとした話をQiitaにまとめました😇<br><br>⬇️HerokuでMinecraft1.17を始めようと思ったけど無理だった話<a href="https://t.co/czcz7vuetV">https://t.co/czcz7vuetV</a><br><br>6年ぶりくらいにMinecraftに復帰して、サーバを立てようとしたのですが、ちょうどメジャーアップデートがあって色々苦労しました😭</p>&mdash; やぎぬ😇QOL追求エンジニア (@yagi_eng) <a href="https://twitter.com/yagi_eng/status/1402818550725816320?ref_src=twsrc%5Etfw">June 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
PowerAutomateで配列をソートする

Office365（Microsoft365）で、ユーザーオペやスケジュールをトリガーに自動起動する連携処理を実装するのに便利なPowerAutomateですが、実際に業務の中で使おうとするといろいろな制約があります。
そのような制約を克服するため思いついたり調べたりした内容をご紹介していこうと考えています。

# Problem

PowerAutomateには配列ソートを行うための組み込みの方法が存在しません。
おそらく、そもそもPowerAutomateの目的は、ユーザーオペ単位で発生するとても小さなトランザクションをこなすことであり、バルク処理を行うことではないとか、まあそういうことなのだろうと推測しています。

そうはいっても、実際問題としてある程度の数（数件～数十件）の要素からなる配列をソートせざるをえない（したくてしかたない）ときがあります。
しかも組織のポリシーなどの関係で、O365からサードパーティの提供するアクションを利用できないということもしばしばあります。

# Solution

今回ご紹介する方法は「きれいな方法」とは言い難いですが、比較的シンプルで、ソート問題以外の制約の克服も含めた一般的な課題解決にも応用可能という意味で、気に入っているものです。

## 1. O365上でExcelファイルを用意

まずはO365上にExcelファイルを用意します。
PowerAutomateから（PowerAutomateのフローを実行するユーザーから）参照可能なところであればどこでも結構です。

## 2. OfficeScriptでソートを実装

先程作成したExcelファイルを開くとメニューに「自動化」というタブが表示されます（ファイルを開いてから数秒待たないと表示されないことがあります）：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/6ec99057-8fe3-a984-6004-abaf0467f379.png)

ここから「自動化」→「すべてのスクリプト」→「＋新しいスクリプト」と進み、表示されたコードエディターで関数を定義します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/ad86afc1-195a-8e35-e80b-f4a888e0d420.png)

```ts:
function main(
  workbook: ExcelScript.Workbook,
  array: Array<object>,
  key: string,
  ascending?: boolean
) : string {
  let compare = (a :object, b :object) => {
    if (typeof(a) === "number" && typeof(b) === "number") {
      return a - b;
    }
    let a2 = String(a);
    let b2 = String(b);
    return a2 > b2 ? 1 : (a2 < b2 ? -1 : 0);
  };
  return JSON.stringify(array.sort((a, b) => (ascending ? 1 : -1) * compare(a[key], b[key])));
}
```

スクリプト名を「arraySort」ではなく「arraySortThenStringify」としている点に注意してください。
スクリプトは引数で `Array<object>` を受け取ることはできますが、戻り値で `Array<object>` を返すことができません。これはOfficeScriptの仕様です。幸い、 `string` を返すことはできます。
しかたなく、ソート結果を `JSON.stringify()` でJSON文字列で返しています。
そういうわけで、この例ではスクリプト名を「...ThenStringify」としていますが、スクリプト名の命名は皆さんの好みに合わせてください。

なお、本来 `Array.prototype.sort()` はレシーバーとなる配列オブジェクトそのものを変更する仕様ですが、その変更はPowerAutomate側には反映されません。PowerAutomateからOfficeScriptを呼び出す段階で、引数のオブジェクトのクローンが行われているのでしょう。
したがってやはり戻り値を使う必要があるわけです。

もう1点。他のユーザーのフローからも実行する可能性がある場合は、「すべてのスクリプト」の一覧で「...」→「共有」をクリックしておきましょう：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/bfba3d7c-3813-b68f-8d14-4e9f6297f5ad.png)

## 3. 「スクリプトの実行」アクションをセットアップ

PowerAutomateのフロー側で「スクリプトの実行」アクションをセットアップし、引数としてソート対象の配列やソートに用いるキーを指定します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/cc91415f-d43e-5c7a-5fd0-b61003d55c95.png)

## 4. 実行結果をデシリアライズ

2.でお話した事情があるため、「スクリプトの実行」アクションの出力結果は文字列化されたJSONとなります。これ自体はもうどうしようもないので、受け取った側で工夫をしましょう。つまり、出力結果をデシリアライズします：

```ts
json(outputs('スクリプトの実行_2')?['body/result'])
```

言うまでもないことですが、 `outputs()` 関数の引数には適切な値を設定してあげてください。

以上で、任意の配列を、任意のキーで、ソートできるようになりました。

# Note

Excelファイルは単なるOfficeScriptの保管場所でしかなく、なんとも微妙な使い方になっていますが、そんなことを気にしていてはPowerAutomateを使った業務が楽しくなくなります。
「ちょっとしたことなのにPowerAutomateの制約があってできない！」ということがあったら、こんな解決策もあることを頭の片隅に置いておくと良いかもしれません。
【CloudShell】AWS CLIコマンドを並列で実行した際に`Error when retrieving credentials from container-role`と出力されるときの対処法

## はじめに

以下のようにCloudShellでAWS CLIコマンドを並列実行する際、同時実行数が20を超えてくると`Error when retrieving credentials from container-role`というエラーが発生するようになる。

こちらの対処方法について調べても見つからなかったので、AWSに問い合わせてみた。

```sh
# このくらいであればエラー無し
$  for i in {1..5}; do (aws ec2 describe-regions > /dev/null && echo $i) & done
~略~
3
2
4
1
5
```

```sh
# 20件を超えると発生しやすくなる
$  for i in {1..30}; do (aws ec2 describe-regions > /dev/null && echo $i) & done
~略~
27
2
~略~
28

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>
Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>
Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>
~略~
```

## 回答

Cloud Shell の内部仕様により、一定回数以上のAWS CLIコマンドを実行すると、実行に必要な認証情報の取得に失敗するとのこと。
また、こちらの緩和申請もできないとのこと。
そのため、Cloud Shellで並列実行する際は、`xargs`の`P`オプション等で実行回数を制限した方が良い。

```sh
# 同時実行回数を実行回数と同等(=30回)にする (-P 30)
seq 30 | xargs -P 30 aws ec2 describe-regions --query "Regions[0].RegionName" ;
~略~
Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>
~略~


# 同時実行回数を10回に制限する (-P 10)
seq 30 | xargs -P 10 aws ec2 describe-regions --query "Regions[0].RegionName" ;
# エラーなし
```


## `get-user` の例

`list-users`で取得した全ユーザーで`get-user`を行う場合。

```sh
# for文だと、ユーザー数によってはエラーになる
$ for u in `aws iam list-users --query 'Users[*].UserName' --output text`; do aws iam get-user --user-name $u & done
~
Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>


# xargs
## -P 100 だとエラー
$ aws iam list-users --query 'Users[*].UserName' | jq -r '.[]' |  xargs -I NAME -P 100 aws iam get-user --user-name NAME
~
Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (503) from ECS metadata: <html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>


## -P 20 だとエラーなし
$ aws iam list-users --query 'Users[*].UserName' | jq -r '.[]' |  xargs -I NAME -P 20 aws iam get-user --user-name NAME
```
UiPathでトリガーを使用する

# トリガー
トリガーを使用するにはトリガースコープを設置する必要がある。![トリガースコープ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009750/8ffc4cc9-6294-3fa9-ae9d-d0a099a21627.jpeg)
xfce-terminalのメニューアクセスをMeta(Alt)キーで行わないようにする

# 環境
Linux Mint 20.1 xfce

# はじめに
tmuxのショートカットにmetaキーを多様している。しかし、xfce-terminalのmetaキーにはメニューへのアクセスキーとなっている。メニューアクセスは不要なので、これを無効化する。

# 方法

Edit -> Prefences -> Advanced, and in the section "Shortcuts", check the button for "Disable all menu access keys (such as Alt+f)"

https://unix.stackexchange.com/questions/562903/how-do-i-disable-the-menu-access-shortcuts-in-xfce4-terminal
RedHat7系でUWSGIインストール

2021/6に投稿
python36 + flask + uwsgiの環境を構築するのに以前のやり方が通用しなかった。
pipでは入りませんでしたのでyumで入れました。
以下の内容はec2のredhat7で作業した場合。


```
# epel-release
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# install uwsgi
sudo yum install python36 uwsgi uwsgi-plugin-python36
# run
sudo uwsgi --plugin=python36 --http-socket=0.0.0.0:80
```


pip経由でuwsgiをインストールした場合はpython36との関係を自動で上手くやってくれるみたいですが、
yum経由の場合はpythonプラグインをインストール、設定しないといけないみたいです。
Web Share APIの実装

#書いてあること
Javascriptを使って、web share APIを実装します。

#実装に至っての背景
普段webARの実装をすることが多くて、いろんなプラットフォームでSNSにシェアをしてもらわないといけないという制約のもと、どの方法が一番いいんだろうと思って探していたら
ここに落ち着いた感があります。

#完成イメージ
ボタンを押したらこれが出てきます。（OSのバージョンによって若干UIは異なると思います。）
![スクリーンショット 2021-06-10 10.23.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/564a2bd8-1e25-a86d-f34f-b14beb7cc8ca.png)



#Can I use で対応状況を見てみる
https://caniuse.com/?search=web%20share

こんな感じ。
![スクリーンショット 2021-06-10 10.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/a54253e6-2cd5-4d7e-a379-cdea5b022a25.png)

#さあ、実装を始めよう。
シェアボタンなるものは実装してある前提で話を進めます。
もしくは気が向いたら一番下の方にボタンの実装方法も書いておきます。


```javascript:main.js
    //HTMLからボタンを読み込みます。
    const shareButton = document.getElementById("share_button")
    // web share APIの実装
    const shareAPI = () => {
      navigator
        .share({
          // シェアAPIを呼び出した時に出てくる文言。実装してみればわかります。
          title: 'シェアAPI',
          // twitterとかでシェアするときにこの文章が挿入されます
          text: 'じゃんけんWebARをプレイしました！こちらのリンクから遊べます^^',
　　　　　　　　　　　　　　　　　　　　// URLを指定したい時はこちらで指定する。空にするとこのURLが指定される。
          url: '',
        })
        .then(() => {
　　　　　　　　　　　　　　　　　　　　// シェアし終わった後に表示される
          alert('シェアありがとうございました')
        })
　　　　　　　　　　　　　　　　　　　　// シェアミスった時に表示される。
        .catch(() => {
          alert('もう一度試してください')
        })
    }
    // shareボタンをクリックしたらshareAPI関数がよばれるイベント
    shareButton.addEventListener('click', shareAPI)
```

ボタン作ってもらってこれをコピペすれば動くと思います。

＃以上
raspberry Pi 4のHDMI出力がチラつく件　対応失敗

# 使用ハード
+ モニタ 飯山 ProLite B2875UHSU
+ 切り替え器　[GANA 4Kx2K HDMI 3入力1出力](https://www.amazon.co.jp/dp/B06XN59TJZ)

Raspberry Pi 4→"microHDMI→HDMI変換ケーブル"→ＨDMIケーブル→HDMI切り替え器→HDMIモニタ
と接続した際、モニタ表示が点いたり消えたりするのでcommentだった以下の行をuncommentしてみた。
画面が消える頻度は減ったが、まだ時々消える。どうしたもんかな

```/boot/config.txt
config_hdmi_boost=4
```

現状は、HDMI切り替え器を使わない　という対処をしている。

※この切り替え器とモニタの相性が悪いのかも…。ほかのモニタだと普通に表示されてるし、Win10ノートPC→切り替え器→モニタ　でも映らなかった…
ExcelVBAのSQL：結合した結果で更新(Join & Update)

# １．実行条件

- Excelのバージョン：MS365 64bit
- VBAのExcel参照ライブラリ：Excel 16 Object Library
- DBプロバイダー：Microsoft.ACE.OLEDB.12.0, Excel 12.0

# ２．サンプルデータの構造（同様の構造のシートが２つ存在）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/fed22db5-ec9e-828b-6457-c4e94d64e74b.png)



# ３．２つのシートを結合して、一方のシートの値で別のシートの値を更新（Join & Update)

- 以下、SQLのみ記載。
- Joinする際に対象シートに抽出条件を設定。


```sql
UPDATE 
  (SELECT * FROM [シート1$] WHERE CStr([店舗ID]) <> '' AND [項目タイプ] = 'EX') AS T_1
  LEFT JOIN [シート2$] AS T_2 
  ON T_1.[会社ID] = T_2.[会社ID]   
    AND T_1.[店舗ID] = T_2.[店舗ID]   
    AND T_2.[項目タイプ] = T_2.[項目タイプ] 
SET T_2.[入金] = T_1.[売上] 

```
# ４．エラー対処

- 文字列の条件は、ダブルクオーテーションではなくシングルにしないと以下のエラーメッセージが表示される。(<< X >>エラー箇所数）

```txt
[Microsoft][ODBC Excel Driver]パラメーターが少なすぎます。<< X >>を指定してください。
```
クロージャ (Closure)  is 何

## なぜこの記事を書こうと思ったか
Swiftの勉強をしているときに「クロージャ」という単語が出てきてググっていたのですが，理解するまでに結構時間がかかってしまいました．クロージャを理解しにくい要因は，言葉の定義と具体的な実装の間をつなぐ説明が足りていないところにあると思ったので，この記事ではその間を埋めることを試みたいと思います．

## 具体例
まず一番わかりやすかったクロージャの例を出します．

```swift:example.swift
// func 関数名(外部引数名 引数: 型) -> 返り値の型 {
//    処理内容
// }

func makeIncrementer(amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

let incrementByOne = makeIncrementer(amount: 1)
incrementByOne() // 1
incrementByOne() // 2
```

`makeIncrementer()` は「Int型を返す関数を返す関数」です．そして，その「Int型を返す関数」は `incrementer()` で `makeIncrementer()` の内部で定義されています．`incrementer()` は自身が定義されているスコープにある変数 `runningTotal` を参照してそれに `amount` を加えるという処理を行います．

最後に，実際に`makeIncrementer()`を引数 `amount` を1にして呼び出して，帰ってきた関数を定数 `incrementByOne` に代入します．`incrementByOne` を2度呼び出してみます．すると一度目の実行結果は`1`で二度目の実行結果は`2`が返ってきます．

### なぜインクリメントできるのか
どうして一度目と二度目の実行結果が両方とも `1` にはならないのでしょうか．言い換えると，二回目に呼ばれたときに前回の値がどうして保存されているのでしょう．これは，そもそも`makeIncrementer`の内部にある`incrementer`が**クロージャ**として定義されるからです．

## クロージャとはなにか

クロージャとは関数が自身の定義されているコンテクストに含まれる変数や定数への参照を取り込んで保持しておく機能です．先程の例では，`incrementer()`の定義に含まれている`runningTotal`への参照が保持されています．

クロージャはwikipediaでは次のように説明されています
> クロージャ（クロージャー、英語: closure）、関数閉包はプログラミング言語における関数オブジェクトの一種。いくつかの言語ではラムダ式や無名関数にて利用可能な機能・概念である。引数以外の変数を実行時の環境ではなく、自身が定義された環境（静的スコープ）において解決することを特徴とする。関数とそれを評価する環境のペアであるともいえる

この値を保持しておくこと自体は「キャプチャ（capture）」するといったりします．

## なぜクロージャが理解しにくいか
以上の説明でクロージャの概念は大体掴めたかと思います．ここからはクロージャを理解しにくくなっている原因について，僕の意見を書きたいと思います．

### クロージャ式だけがクロージャではない
Swiftにはクロージャ式（Closure Expression）というものがありクロージャを簡潔に記述できます．他言語でもラムダ式や無名関数を使ったことがあればその便利さがわかるかと思います．Swiftのクロージャ式では関数名を省略できたり，returnを省略したりできます．

```swift:example_of_closure_expression.swift
// {(引数名1: 型, 引数名2: 型...) -> 返り値の型 in
//   処理内容
// }

let incrementByOne = { (x: Int) -> Int in
  x + 1
}
incrementByOne(2) // 3
```

上のようなクロージャ式のことを指して，「これがクロージャです」と説明されていることが稀にあります．下で説明するようにswiftで関数を書いた場合はクロージャの要件を満たしていますから，その説明は間違っていません．間違ってはいませんがミスリードをしていると思います．**クロージャとクロージャ式は別概念**です．関数で書いてもクロージャ式で書いてもクロージャはクロージャです．

### キャプチャする値がなくてもクロージャ
クロージャは言い換えると (1) 関数と (2) 関数の定義に必要だった変数や定数（への参照）の2つの組み合わせです．しかしながら，ややこしいことに，**(2) がない場合もクロージャの特別な場合として説明されます**．例えば以下のようなものがクロージャの例としてswiftの公式ページで説明されています

- グローバル関数は、名前を持ち、値をキャプチャしないクロージャです。
- ネストされた関数は、名前を持ち、包含する関数から値をキャプチャできるクロージャです。
- クロージャ式は、周囲のコンテキストから値をキャプチャできる軽量な構文で記述された名前なしクロージャです。

2つめのネストされた関数は最初に出した例です．値をキャプチャできると言っているだけで，値をキャプチャしていなくてもクロージャの一種であることに注意してください．

## まとめ
「クロージャ」とは関数が自身の定義されているコンテクストに含まれる変数や定数をキャプチャする機能です．しかしクロージャ式で書かれた値をキャプチャしていない関数を例として挙げて説明されることがあります．この定義と具体例の乖離がすべての混乱の原因になっていると思います．

僕も100%理解したわけではないですが，ググって得た情報を組み合わせて，わかったことを書き起こして置きました．なにか不明な点があればコメント等でご指摘いただけると助かります．

## 参考
[What is a 'Closure'? - stackoverflow](https://stackoverflow.com/questions/36636/what-is-a-closure)
https://docs.swift.org/swift-book/LanguageGuide/Closures.html
https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID103
[なぜクロージャ（Closure）と言うのか？](https://qiita.com/mochizukikotaro/items/7403835a0dbb00ea71ae)
[Swiftでクロージャを理解する](https://thinkit.co.jp/article/15629)
[クロージャまとめ（Swift \)](https://qiita.com/Howasuto/items/eba4cb4b6d3e6bde0a17)
大学生がReact.jsとChakra-UIを使ってPortfolioサイトを作ってみた話

<h1>portfolioサイトを作りました！
<p>この記事を見てくれた皆様ありがとうございます。
文系大学生の4年生絶賛就活中のものです！
今まで自分で１から考えて作ったものがなかったので最近学んだReact.jsを使ってPortfolioサイトを作ろうと考えました。
初学者なのでまだまだ理解できていないところもあるとは思いますが、自分自身のアウトプットのためにこの記事を書いているので、至らない点などあればご指摘ください！
<h2>はじめに
<p>作ったものをスクショしたものがこちらになります！
herokuにアップしているのですがどうもものすごく重い。。。
一様linkも貼っておきます。お時間ある方だけのぞいてくれると喜びます！！
heroku↓
<link>https://secret-river-81904.herokuapp.com/
<p>少しでも気になるという方がいましたらGitHubアカウントを覗いてもらえると泣いて喜びます。
<link>https://github.com/soraoka0418/Portfolio
![Portfolio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1627435/9d6cf979-7988-d7e7-2627-d12ac29def7d.png)
<h2>デザインについて
<p>恥ずかしながらデザインの知識が全くありませんでした。
作ってみるかーー！でいきなりコードを書き始めてしまい後から後悔することになりました。。。
もし私と同じようにPortfolioサイト作ってみよう！と思った方がいればはじめにデザインの大まかなものを作ってから始めることを強くお勧めします
（当たり前なのかもしれない。。。）
<h2>ディレクトリ構造について
<P>アトミックデザインなるものを採用しました。
（できているのかはわからないが。）
結果的なディレクトリ構造はこちらのようになりました

```
components
├ atoms ───── img
│         ├── HeaderLink.js
│         └── icon.js
│         
├ organisms──── layout ──── Header.js
│            │          └── SelfDrawer.js
│            ├── Card.js
│            ├── HeaderNav.js
│            ├── HomeButton.js
│            ├── HomeMessage.js
│            ├── Selfintroduction.js
│            └── SelfLink.js
│
└ pages ─── Contact.js
        ├── Home.js
        └── Skill.js
```
<p>これについてもあらかじめ決めていたわけではなく、コードを書いていくうちにコードが長くなってしまった為、component化していたらこうなってしまいました。
（計画性ゼロ）

<h2>使用した技術について
<p>タイトルにも書いている通り、React.jsを使いまいした。今までhtmlやCSS、jQueryでLP制作などをしていたため、React.jsで何かを作るのは初めてでした。
CSSについてはChakra-UIを使用してみました！
個人的にとても便利だと感じた点は、どこにどのスタイルが当たっているか分かりやすい点やもともと用意されているものが豊富で、それをimportするだけで使えるのはとてもありがたかったです！！

```jsx
<Heading as="h3" pb="6" borderBottom="1px" borderColor="teal.500">
    {props.title}
</Heading>
```
<p>これは見出しの部分のコードですがこんな風にして簡単にスタイルをあてることができます！！詳しくはドキュメントを見てください。。。
→<link>https://chakra-ui.com/

<h2>ルーティングについて
<p>

```jsx
export const Router = memo(() => {
  return (
    <Switch>
      <Route exact path="/">
        <Home />
      </Route>
      <Route path="/Contact">
        <Contact />
      </Route>
      <Route path="/Skill">
        <Skill />
      </Route>
    </Switch>
  );
});

```

<p>こんな感じでsrcフォルダ配下にrouterフォルダを作り記述しました。
ルーティング周りはまだ苦手意識があるのでこれから克服していきたいと考えています。

<h2>最後に
<p>もしここまで見てくださった方がいたならとてもうれしい気持ちでいっぱいです。
記事を書いたりするのも初めてのことでいろいろ戸惑いながら書いています
絶賛就活中でエンジニアを志望しているのですがなかなかうまくいかないです
。。。
この記事のご意見ご感想をもらえるととてもモチベーションになりますのでどうか初学者のためだと思って一言よろしくお願いいたします。
（図々しい。。。）
それではここまで読んでくださり本当にありがとうございました。
POWERSHELL　エクセルからデータ取得　空欄が出るまで繰り返す

```powershell
try{
        # Excelオブジェクト作成
        $excel = New-Object -ComObject Excel.Application
        $excel.Visible = $false

        # 既存のExcel
        $book = $excel.Workbooks.Open("\test.xlsx")

        # シート取り出し
        $sheet = $excel.Worksheets.Item("シート名")

        # その他やりたい処理

        $i = 1
        # A列の一番上のセルのテキストを取得
        $text1 = $sheet.Cells.Item($i,1).Text

        # A列が空欄があらわれるまで繰り返し処理
        while ($text1 -ne "")
        {
            #A列のセルをエコーする
            write-host $text1
            
            $i = $i + 1
            #次のA列のセルを取得
            $text1 = $sheet.Cells.Item($i,1).Text

        }


        # 上書き保存
        $book.Save()

        # 閉じる
        $excel.Quit()

} finally {

        # null破棄
        $excel,$book,$sheet | foreach{$_ = $null}

}

```
ECHONET Liteの紹介　その１

## はじめに
ECHONET Liteとは、スマートホームを実現するための標準インタフェースです。
スマートホームを実現するためには、ホームの中にある様々な機器が自分の状態を発信したり、動作指示を受信して自動で動いたりするための通信ができる環境が必要です。
ホーム全体を管理するコントローラと機器間で行う共通の通信規格がECHONET Liteです。
ECHONETは、Energy Conservation and HOmecare NETworkの略称で、社会課題である環境エネルギー問題と高齢化社会の解決のために実現できるネットワークによるサービスを表したものです。
![ECHONET Lite 概要_図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/ce07808c-edce-fb64-a815-ceae2cb4a888.jpeg)
## HEMSにおける公知な標準インタフェース
家電や住宅設備を有効活用するためには、異なるメーカーのすべての機器が同じ通信インタフェースを搭載する必要があります。
政府は、スマートホームを構成するHEMSの公知な標準インタフェースとして、ECHONET Lite(エコーネットライト)を推奨しています。
![ECHONET Lite 概要_図2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/a6ce93a7-79cc-fa54-a4f9-aaecfba44141.jpeg)
HEMSは、Home Energy Management Systemの略称です。
政府では、ホームの省エネルギーに貢献する機器として8機器を定め、HEMS重点8機器としています。
## ECHONET Liteの特徴
ECHONET Liteの特徴には、次のようなものがあります。
**共通仕様によるマルチベンダー環境の実現**
　異なるベンダーの機器を相互接続し、制御することができます。
**各種既存の標準的な伝送メディアの利用が可能**
　有線LAN（Ethernet）、無線LAN（Wi-Fi）等の広く普及している標準的な伝送メディアを用いて、システムの構築が可能です。
**家庭・中小ビル・店舗向け等、広範囲な機器に対応**
　100種類以上の機器のコマンドを定義。新しい機器についても、随時コマンドを追加していきます。
**クラウド上のサービスとの連携が可能**
　インターネット上の様々なシステムと連携し、高度なサービスの実現が可能です。
**ネットワークレディ機器の設計が可能**
　ミドルウェアアダプタインタフェースにより、機器を先に購入し、後からネットワーク機能（アダプタ）を追加して、システムを導入することも可能です。
## ECHONET Liteの規格構成
ECHONET Liteは、IEC、TSO/IEC JTC1で認定された国際標準規格です。
ECHONET Liteは、ECHONET Lite規格書、ECHONET機器オブジェクト詳細規程、アプチケーション通信インタフェース仕様書の3種類の規格で構成されます。
![ECHONET Lite 概要_図3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/23b600d4-8746-567a-3657-1d79ccee2365.jpeg)
 - ECHONET Lite規格書は、プロトコルとして手順や電文構成他の基本的な規格を定めています。
 - ECHONET機器オブジェクト詳細規程は、機器ごとに送受信するコマンドや情報の内容を規定しています。
 - アプリケーション通信インタフェース仕様書は、機器ごとの機能や動作で固有となる部分で通信に関わる仕様を規定することで、ベンダー間の相互接続性を向上させるためのものです。
 - IECとは、国際電気標準会議（International Electrotechnical Commission）になります。
 - ISO/IEC JTC 1とは、国際標準化機構 (ISO) と国際電気標準会議 (IEC) の第一合同技術委員会 (Joint Technical Committee 1) のことです。
## ECHONET機器オブジェクト
ECHONET Liteでは、家庭内のあらゆる機器(110種類以上)の制御コマンドを定義しています。
![ECHONET Lite 概要_図4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/5b16e5ea-3f7d-51bc-2d99-1cc956beef7b.jpeg)
対象となる機器やコマンドの追加・変更を定期的(2回／年)に実施しています。
エコーネットコンソーシアム会員であれば、だれでも提案をすることができます。
## ECHONET Lite規格　第三者認証制度
ECHONET Lite規格に対応した製品のベンダー相互接続性古城のため、以下の2種類の第三者認証制度を実施しています。
 - ECHONET Lite AIF認証制度
 - ECHONET Lite 認証制度
![ECHONET Lite 概要_図5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/4aa22b83-8f22-2c3f-7d43-d24035cc4f34.jpeg)
詳細は[エコーネットコンソーシアムHP 認証制度の紹介](https://echonet.jp/about/certification_system/)をご覧ください。
ECHONET Lite規格およびECHONET Lite AIF仕様に対応した製品の認証を申請するためには、エコーネットコンソーシアム会員になることが必要です。
認証製品の取得件数は下図のようになり、多くの製品が認証を取得しています。
![ECHONET Lite 概要_図6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/a4329ab0-5be1-c019-11d2-05a2e4146714.jpeg)
## ECHONET Liteをもっと知りたい方へ
ECHONET Lite規格書、ECHONET機器オブジェクト詳細規程は一般公開していますので、興味のある方は、だれでも規格のダウンロード、製品試作を行うことができます。
[エコーネットコンソーシアムホームページ](https://echonet.jp/)へアクセスください。
![ECHONET Lite 概要_図7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369926/b52a51ac-1f50-e2d5-7967-c27f3520de6f.jpeg)
正規表現の例文

#正規表現を使いたい！
最近やっと使い始めた。備忘録として使った正規表現を記録していく。

#私的ポイント

* 暗号に見える正規表現の文字列は結合記号無しで一つの文章として表現されている。
* 複数の特定文字（例：A or B）を検索したい場合は[A|B]と記載する。
* .+は1文字以上何かあればOK。偉大。
* .*は0文字以上だからなんでもあり。すごい。

#例文
##javaソースコードのコメントを改行コードごと選択

```
.+\/\/.+[;|{|}].+\r\n
```

##番号指定参照
###例１

これを（komokuNameの前のスペースはtab3つ）

```
　　　komokuName1 - String 文字型1
　　　komokuName2 - String 文字型2
```

こうしたい

```
　　　"komokuName1", // -String 文字型1
　　　"komokuName2", // -String 文字型2
```

番号指定参照を使う。
( )の中を一つの変数としてみなす技らしい。
今回の例では、置換前の文字列は( )が3つあり、頭から\$1, \$2, \$3という名前の変数として扱う。

```
置換前:(\t\t\t)(.+)(\s-\s.+)
置換後:$1"$2" , //$3
```

###例２
これを

```
　"komokuName", // -String 項目名称
```

こうしたい

```
　private String colkomokuName = "komokuName" //項目名称
```

```
置換前:(\t)(")(.+)(")(,)(.+)( -String (.+)
置換後:$1private String col$3 = $2$3$4;$6$8
```

#最後に
正規表現使ったらどんどん追記します。
lazysizes画像遅延読み込みで、ページ内スクロール(スムーススクロール)がずれてしまう問題の対処法

##はじめに
webページに画像が多い場合、lazysizesなど、画像を遅延させて読み込ませる時もあるかと思います。本記事ではlazysisesを用いた際に、ページ内スクロールがずれてしまう問題の対処法を書いておきます。また、ページ内スクロールに使うjsのコードは今回割愛します。

##原因
lazysizesで画像を遅延読み込みさせると、読み込むまで元の画像の高さが取得できないので、href属性でスクロール先を設定しても、画像の高さがない分ずれてしまう。

##解決策
表示させる画像とは別に、imgタグにダミーの画像を設定します。
表示させる画像と同じアスペクト比でダミー画像に高さを設定する。
ダミー画像に高さを設定するにはlazysizesの拡張プラグインdata-aspectratioを使用します。
では、順を追って解説します。

##念のためにpictureタグのおさらい
解説の前に、lazysizesとpictureタグを組み合わせることも多いと思うので、pictureタグの使い方を記載しておきます。

```
<picture>
 <source data-srcset="sample-sp.png" media="(max-width: 500px)">
 <img data-src="./sample-pc.png"　class="lazyload">
</picture>
```
lazysizesを使う場合、「src」と「srcset」にそれぞれ「data-」をつけます。
あとは、imgタグにlazyloadのクラスをつければOKです。

##解決策
①data-aspectratioの読み込み
②ダミー画像の設定
③ダミー画像に高さを設定
###①data-aspectratioの読み込み
lazysizesをダウンロードすると、
/lazysizes/plugins/aspectratio/
の中にls.aspectratio.min.jsがあるので、このファイルを読み込みます。

```
<picture>
 <source data-srcset="sample-sp.png" media="(max-width: 500px)">
 <img data-src="./sample-pc.png"　class="lazyload">
</picture>

========================= 省略 ============================== 

<script src="./js/lazysizes.js" ></script>
<script src="./js/ls.aspectratio.min.js" ></script>
```
これでlazysizesのプラグインファイルの読み込みはOKです。
手順③でダミー画像に高さをつけるので、そのときにこのファイルが必要になります。

###②ダミー画像の設定
ダミー画像はこちらの方の記事を引用しました。
>[1x1の最小GIF・PNGファイル（透過/base64）](https://qiita.com/CloudRemix/items/92e68a048a0da93ed240)

こちらからコードを借りて、imgタグにダミー画像を設定します。
ダミー画像はsrc属性に設定します。

```
<picture>
 <source data-srcset="sample-sp.png" media="(max-width: 500px)">
 <img
   src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7"
   data-src="./sample-pc.png"　
   class="lazyload">
</picture>
```
src属性で先ほどコピーしたコードを貼り付けます。
これでダミー画像の設定は完了です。
###③ダミー画像に高さを設定
では、最後にダミー画像に高さをつけて、表示させたい画像が読み込まれてなくても高さを保てるようにします。
data-aspectratio属性を用いて、ダミー画像に高さを付けます。
data-aspectratio属性には表示したい画像のサイズ(横幅/高さ)を設定します。
例として、表示させたい画像が横幅×高さ=200×100であれば、data-aspectratio="200/100"と記述します。

```
<picture>
 <source data-srcset="sample-sp.png" media="(max-width: 500px)">
 <img
   src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7"
   data-src="./sample-pc.png"
   data-aspectratio="200/100"　
   class="lazyload">
</picture>
```
これで、webページの下の方にある読み込まれていない画像にも高さが設定されるようになります。ページ内スクロールを実行すると、画像の高さが取得できているので、ずれることなく目的の箇所へスクロールできるようになります。

####レスポンシブ対応
pictureタグを使った場合、PC、スマホで表示させたい画像の大きさが変わると思います。
その場合はsourceタグにもdata-aspectratioでスマホ用の画像の大きさを設定すれば大丈夫です。

例として、表示させたいスマホの画像が横幅×高さ=100×50の場合は、

```
<picture>
 <source
   data-srcset="sample-sp.png" 
   data-aspect-ratio="100/50"
   media="(max-width: 500px)">
 <img
   src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7"
   data-src="./sample-pc.png"
   data-aspectratio="200/100"　
   class="lazyload">
</picture>
```
このようにコードを書けば、スマホでもページ内スクロールが問題なく動きます。

##おわりに
画像遅延読み込みさせると、ページ内スクロールがうまくいかず悩んだので、同じ境遇の方はぜひこの方法を試してみてください。
Tomcatサーバ起動できなくてやったこと

## 起こったこと
Eclipseで動的Webプロジェクトをつくる勉強中、Tomcatサーバーを起動しようとすると以下のエラーメッセージがでる。
>1 つ以上のポートが無効なため、サーバーを始動できません。サーバー・エディターを開き、無効なポートを訂正してください。

## 結論
Tomcat管理ポートが"-"になっていたのを"8005"など適当な値をいれたら起動した。
参考
[インストールしたTomcatをeclipseで使用したい。](https://teratail.com/questions/247657)

## 解決するまでにやったこと
なんかよくわからないけど、8080が使用中ということか。。？と思って、
ポートを使用中のプロセス特定してtask killしようとした。

windowsのコマンドプロンプトで以下コマンドを叩いてみた。

```
netstat -ano | find ":8080"
# 8080ポートを使用しているアクティブなプロセスを検索
```

でも結果はなにもでてこない。。
そうですよね。。

とりあえず解決したので過程をメモ。
[2021年]継続的に開発するプロダクトならテストコードを書こう

皆さん！テストコード書いてますかーーー？？

TDD(テスト駆動開発)やCI(継続的インテグレーション)という言葉が広く知られるようになって数年経ちますが、2021年の現在でもテストコードを書いていない現場をちらほら見かけます。

テストコードを書いてテストを自動化している私の感覚では、継続的に開発するプロダクトにおいてテストコードを書いていないのはありえないです！！

よく聞く言い訳として、テストを書く工数がないということが言われます。
ただ、1度でもテストを書いていた経験がある方だとわかると思いますが、テストを書いていない場合は既存コードに手を入れるときに確実に余計に工数がかかります。
テストは未来への投資です。そしてその投資は次に手を入れるタイミングでもう返ってきます。速攻で返ってくるのでやらない手はないです。

※最初に「継続的に開発するプロダクト」と書いた通り、今後絶対に手を入れないようなコードであれば書く必要な無いかもしれません。

# そんなこと言ったってうちの現場はテストコードを書かない方針なんだ

既存コードにテストがない場合、改修したり新規コードを追加した時にもテストを入れずに終わらせることが多いと思います。
私も以前はそうでした。既存コードにないことを言い訳にテストコードを書かずにいました。その分、頑張って手動でテストしていました。

そういう環境にいるとテストを書かないことが普通になってしましますが、可能であれば自分の担当領域だけでもテストを書くようにしてみましょう。
もしチームをリードするポジションの方であれば自分から初めてテストコードを書く文化を徐々に広げていければ素敵だと思います。

ただ、テストがない環境の場合、テストを書くことをよく思わない人がいるかもしれません。（なんでテスト書いてるんだ！工数がもったいない！！)
そう言われてしまい、かつ、立場上どうしようもない場合は諦めることをおすすめします。
(人や文化を変えるより、職場を変えるほうが数倍簡単です)

# とにかく始めてみよう
テストを書いたことがない方はとにかく始めてみましょう。
様々な記事だけ読んでいても実際に手を動かして運用してみないとわからないことは多いです。

始めるといっても最初から分厚い本に手を出して完璧を求める必要はありません。(私の経験上、TDDは形から入ると挫折します)
APIであればエンドポイントで正常1本、フロントであれば画面の初期表示のテストなど簡単なものを1つ作るところからスタートさせましょう。

最近のプログラム言語やフレームワークであればテストライブラリがあると思うので、それを調べてとにかく1つテストを書いてみましょう。
最初から高いカバレッジを求める必要はありません。

テストがない状態であれば、正常のテストが1つあるだけでかなり状況が変わります。
例えば機能AとBで使っている共通コンポーネントを機能Cからも使おうと思って共通コンポーネントを修正したとします。
その時、AやBも含めてリグレッションテストをすればよいのですが、規模が大きく複雑なシステムの場合、手動でテストをしていたら漏れてしまう可能性が高いです。漏れなかったとしても影響範囲の調査や手動テスト工数が膨大になります。

そういうときに各機能に正常系1件だけでもテストがあると、対応が漏れている機能のテストが落ちて気づける可能性があります。
もちろん正常系1本だとテスト部分は問題なく動作して気づけないこともあります(レスポンスは正常だけど一部の項目が壊れている場合など)
ただ、テストがないと確実に気づけないので大きな第一歩です。（宝くじ、買わないと当たる確率は0%です。みたいな感じです。)

手動テストだけやっていると、「テスト＝今回開発したものの動作確認」という意味が強いですが、テストコードを書いて自動化しておくと「テスト＝以降、機能の動作を保証するもの」という意味となり、テストコードを書いた以降に不意に壊れることを防ぐことができるようになります。
この感覚が大事だと思います。この感覚が身につくと、テストコードがないコードを触るときに既存を壊してしまっても気づけない恐怖で手が出せなくなります。

# まとめ
テストコードについての記事は山のようにあります。そしてテストコード(特にTDD)に関しては否定的な記事も多いと感じます。

もちろん開発しているプロダクトの性質や開発現場の状況によってテストコードを導入することの善し悪しは異なると思います。
ただ、少なくともネガティブな記事に影響されて自分で手を動かすことなくテストコードを悪だと思わないでほしいなと思いこの記事を書きました。

近年では様々な言語でテスト用ライブラリが充実してきており、手軽にテストコードが書けるようになってきています。
ぜひ、自分の手でテストコードを書いてみてテストコードがある開発の感覚を掴んでいただければと思います。