OmniAICreator/Qiita-1.07M huggingface dataset:
【ReactHooks】useStateについて

# useStateとは
関数コンポーネントで`state`を保持・更新するために使用されます。

## propsとの違い
`props`は読み取り専用のデータであり、コンポーネント内で**変更できません**。親コンポーネントから子コンポーネントに値を渡すために使用されます。`props`を使用することで、Reactコンポーネントが再利用可能になります。

対して`state`は、コンポーネント内で**変更できる**可変のデータです。また、コンポーネント内でのみ使用されるため、他のコンポーネントへ渡せないです。コンポーネント内で状態を管理するために使用されます。Reactコンポーネントは状態が変化すると再レンダリングされるため、`steta`にてコンポーネントの再描画を行います。

例えば、以下のコードは`props`にて親コンポーネントから値を受け取り、表示しています。
```javascript
function ChildComponent(props) {
  return <p>{props.message}</p>;
}

function ParentComponent() {
  return <ChildComponent message="Hello World!" />;
}
```
<br>

一方、以下は、`useState`を使用してコンポーネント内で状態を管理しています。

```javascript
function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

## useStateの記述

まず、`useState`をインポートします
```javascript
import React, { useState } from 'react';
```
<br>

次に、`useState`を使用して、コンポーネント内で状態を宣言します。最初の引数には、状態の**初期値**を指定します。２つ目の引数に、**状態を更新する**ための関数を返します。この場合、`count`という状態を宣言して、その初期値を0に設定しています。また、`setCount`という関数を使用して、`count`の値を更新することができます。

```javascript
const [count, setCount] = useState(0);
```
<br>

以下の例だと`count`の値を参照し、ボタンがクリックされたときに`count`の値を1つ増やすように設定しています。`setCount`関数を使用して`count`の値を更新しています。
```javascript
const Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

## クラスコンポーネントで記述した場合

```javascript
import React, { Component } from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

export default Counter;
```

コンストラクター内で`count`という状態を定義し、`setState`メソッドを使用して状態を変更することができます。

また、クラスコンポーネントはReactのライフサイクルメソッド（componentDidMount / componentDidUpdate / componentWillUnmountなど）を使用しますが、関数コンポーネントもReact Hooksを使用することで、同じような機能を実現することができます。なのでコードの可読性が高まります。
G空間情報センターでCKAN APIを使ってみる（入門編）

# はじめに

[G空間情報センター](https://front.geospatial.jp)には地理空間情報に関するオープンデータが色々と登録されています。通常はブラウザからデータを検索してダウンロードすることが多いのですが、Project PLATEAUの３Ｄ都市モデルや登記所備付地図データなど、全国各地のデータが大量に登録されているようなデータを手動で一つずつダウンロードするのは大変です。その場合スクリプト／プログラムを使って検索＆ダウンロードする方法を使うことができます。ここではAPIの呼び出し方の基本を説明します。

# API利用マニュアルについて　
G空間情報センターには[API利用マニュアル](https://s3-ap-northeast-1.amazonaws.com/gic-manual/gic-api.pdf)が用意されていますが、内容が少し古くなっています。現在（2023年3月）、「2. API キーおよび ID の確認」の部分は変更されているのでご注意ください。

# APIの呼び出し方　

G空間情報センターのAPI呼び出しに使われるエンドポイントURLは
` https://www.geospatial.jp/ckan/api/3/action/ `
です。このURLにコマンドとパラメータを付加してAPIを呼び出します。レスポンスはJSON形式で返されます。

レスポンスのJSONには **help**, **success**, **result**というキーが含まれています。**success** には呼び出しの成功／失敗が true / false で格納されます。**result** の内容はコマンドによって様々な値が格納されます。

## ブラウザでAPIを呼び出してみる
例えば、FirefoxブラウザでAPIを呼び出すと、レスポンスのJSONをデコードして表示することが出来ます。

- JSONの表示機能についてはアドレスフィールドから about:configを開き、**devtools.jsonview.enabled** の設定で変更することができます。

G空間情報センターに格納されているデータセットには「タグ」が付加されています。まずは[**tag_list**](https://www.geospatial.jp/ckan/api/3/action/tag_list)コマンドで、タグの一覧を取得してみます。次の[URL](https://www.geospatial.jp/ckan/api/3/action/tag_list)をブラウザで開きます。

`https://www.geospatial.jp/ckan/api/3/action/tag_list`

FirefoxブラウザはレスポンスのJSONをデコードし下記のように表示します。「生データ」タブを選択するとデコードする前のJSONデータをそのまま表示することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291613/52754254-5a0e-d1ec-4e52-ca24bd6d7573.png)

他には、登録されている組織の一覧を取得する[**organization_list**](https://www.geospatial.jp/ckan/api/3/action/organization_list)コマンド、パッケージ（データセット）の一覧を取得する[**package_list**](https://www.geospatial.jp/ckan/api/3/action/organization_list)コマンドなどがあるので試してみてください。

## データセットを検索する

データセットの検索には **package_search**コマンドを使います。

例えば、キーワードを'PLATEAU'として最大5件までデータセットを検索するには下記のようなURLを使います。
`https://www.geospatial.jp/ckan/api/3/action/package_search?q=PLATEAU&rows=5`

Firefoxでは下記の様にJSONが表示されます。result要素の下にあるcountはデータセットが全部で72あることを示しています。resultsには検索されたデータセットの情報（メタデータ）が配列で格納されています。メタデータには様々な情報が格納されていますが、ここでは割愛します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291613/05ac4a23-e155-5b36-6d03-a975eaced835.png)

## コマンドラインでAPIを呼び出してみる
**curl**コマンドでAPIを呼び出し、**jq**コマンドでJSONを整形して表示してみます。先ほどブラウザで表示されたJSONのデータを取り出すことが出来ました。

```shell
% curl -s "https://www.geospatial.jp/ckan/api/3/action/tag_list"| jq .

{
  "help": "https://www.geospatial.jp/ckan/api/3/action/help_show?name=tag_list",
  "success": true,
  "result": [
    "ごみ",
    "クマ",
    "ダム",
    "バス",
    "ＯＤ",
    "くらし",
    "これで",
    "さくら",
    "たなか",
    "たばこ",
    "だいち",
    ...
    ]
}
```

# 終わりに
簡単なレスポンスを返すAPIコマンドをFirefoxブラウザで呼び出して、JSONを表示する方法を説明しました。またデータセットを検索するコマンドを、curlコマンドで呼び出し、jqコマンドでJSONをデコードしてみました。

入門編はここまで
安全にブランチを削除できる「gh poi」

<!-- wp:heading -->
<h2>はじめに</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>弊社ではさまざまなシステムの開発が行われており、Gitのブランチ戦略などは各プロジェクトに委ねられています。<br>私が担当しているプロジェクトでは、GitHubFlow + Squash-Mergeによる運用を行っています。<br>理由としては、それぞれのコミットの粒度・メッセージの統一を図るのが大変という点があります。<br>デメリットとしては、コミットが圧縮されてしまう点があるのですが、プルリクエストの粒度によって調整しています。<br><br>さて、Squash-Mergeのデメリットのもう一つがgit branch -dで削除できず、強制オプションを付ける必要があります。<br>今回ご紹介する「gh poi」を利用すると安全に不要なブランチを一括削除することができます。<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>インストール</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>GitHub CLIのインストール</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>gh poiは、GitHub CLIの拡張機能として実装されています。<br>まずはGitHub CLIが必要なので、インストールしましょう。</p>
<!-- /wp:paragraph -->

<!-- wp:loos-hcb/code-block -->
<div class="hcb_wrap"><pre class="prism undefined-numbers lang-plain"><code>winget install GitHub.Cli</code></pre></div>
<!-- /wp:loos-hcb/code-block -->

<!-- wp:paragraph -->
<p>インストール後、ghコマンドが利用できるようになります。<br>まずは認証を行う必要がありますので、下記コマンドを実行し認証を行いましょう。</p>
<!-- /wp:paragraph -->

<!-- wp:loos-hcb/code-block -->
<div class="hcb_wrap"><pre class="prism undefined-numbers lang-plain"><code>gh auth login</code></pre></div>
<!-- /wp:loos-hcb/code-block -->

<!-- wp:heading {"level":3} -->
<h3>gh poiのインストール</h3>
<!-- /wp:heading -->

<!-- wp:loos-hcb/code-block -->
<div class="hcb_wrap"><pre class="prism undefined-numbers lang-plain"><code>gh extension install seachicken/gh-poi</code></pre></div>
<!-- /wp:loos-hcb/code-block -->

<!-- wp:heading -->
<h2>使い方</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>使い方は簡単です。下記コマンドを実行します。</p>
<!-- /wp:paragraph -->

<!-- wp:loos-hcb/code-block -->
<div class="hcb_wrap"><pre class="prism undefined-numbers lang-plain"><code>gh poi</code></pre></div>
<!-- /wp:loos-hcb/code-block -->

<!-- wp:image {"sizeSlug":"large"} -->
<figure class="wp-block-image size-large"><img src="https://user-images.githubusercontent.com/5178598/140624593-bf38ded3-388b-4a4b-a5c0-4053f8de51ad.gif" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2>参考文献</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>リポジトリ</strong><br><a href="https://github.com/seachicken/gh-poi" target="_blank" rel="noreferrer noopener">https://github.com/seachicken/gh-poi</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>GitHubで“Squash and merge”したブランチを安全に削除するツールを作ってみた</strong><br><a href="https://zenn.dev/oishiseachicken/articles/2cf634fc2e21d3" target="_blank" rel="noreferrer noopener">https://zenn.dev/oishiseachicken/articles/2cf634fc2e21d3</a></p>
<!-- /wp:paragraph -->
【随時更新中！】Go言語で標準入力から値の受け取り方

# 文字列を一行受け取る。
```go
package main

// データの読み込みに必要なパッケージをインポートしている
import (
    "fmt"
    "bufio"
    "os"
)
func main() {
    // データを読み込んでいる
    // scは読み込み機能を割り当てる変数
    sc := bufio.NewScanner(os.Stdin)
    
    sc.Scan()
    // 受け取ったデータを変数sayに代入している。
	say := sc.Text()
	fmt.Println("Hello " + say)
}
```
<b>標準入力</b>
world
<b>実行結果</b>
Hello world

# 調べたこと
<b>Go言語の標準ライブラリ（なんかパッケージって呼ばれてる。）</b>
・fmt（パッケージ）
フォーマットされた入出力をサポートする関数を提供します。
例えば、Println関数は文字列をコンソールに表示するために使用されます。
・bufio（パッケージ）
高速な入出力機能を提供します。
Scanner型は、ファイルや標準入力からテキストを読み取るために使用されます。
・os（パッケージ）
OSの機能を利用するための関数を提供します。
Stdin変数は、標準入力を表すファイルオブジェクトです。
Stdout変数は、標準出力を表すファイルオブジェクトです。


<b>パッケージの中に関数とメソッドがあるらしい</b>
```
- fmt（パッケージ）
    - 関数
        - Println
- bufio（パッケージ）
    - 関数
        - Scan
            - Scanner型のオブジェクトから1行のテキストを読み取り、そのテキストを文字列として返します
        - NewScanner
    - メソッド
        - Text
- os（パッケージ）
    - 
``` 
<b>Go言語のパッケージの種類</b>

・標準パッケージ: Go言語の開発者によって提供される公式のパッケージであり、Go言語のインストールに含まれています。

・サードパーティのパッケージ: Go言語の開発者以外が提供するパッケージであり、"go get" コマンドを使用してダウンロードすることができます。

・プロジェクト固有のパッケージ: 特定のプロジェクトで使用するために作成されたパッケージであり、開発者が独自に作成することができます。

・ローカルパッケージ: 開発者が作成したパッケージであり、プロジェクト内で使用するためにローカルに保存されます。

・外部パッケージ: Go言語のプログラムから使用する外部のライブラリやAPIなどのパッケージです。

# 整数を一行受け取る。
```go
package main

import (
    "fmt"
    "bufio"
    "os"
    "strconv"
)

func main() {
    sc := bufio.NewScanner(os.Stdin)
    
    sc.Scan()
    number, _ := strconv.Atoi(sc.Text())
    fmt.Println(number)
    fmt.Println(number * 100)
}
```
<b>標準入力</b>
10
<b>実行結果</b>
10
1000
【Swift】ミリ秒を含んだISO8601形式のデコード

# はじめに
現在、Zennの記事をウィジェットに一覧表示するアプリを作っています。
`dateDecodingStrategy`を使用してデコードしたかったのですが、ZennのDateはミリ秒まで表示されており、標準のISO8601ではデコードできませんでした。
ミリ秒を含んだISO8601形式でもデコードできるようにカスタムのiso8601Formatterを作成しました。

# 実装
```swift
// MARK: DateFormatter
private static let iso8601Formatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
    return formatter
}()

// MARK: JSONDecoder
private static let decoder: JSONDecoder = {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    decoder.dateDecodingStrategy = .formatted(iso8601Formatter)
    return decoder
}()
```

# おわり
`ISO8601DateFormatter`を使用するときはオプションがあり、簡単にミリ秒にも対応ができました。

https://developer.apple.com/documentation/foundation/iso8601dateformatter/options

しかし、`JSONDecoder`では`ISO8601DateFormatter`が使えないようです。
IDL

## 初めに
IDLでインターフェースを生成するという事を今はしていませんが、
便利だと思うので、簡単にまとめました。

## IDLとは
インターフェース定義言語

IDLは、特定のプログラミング言語に依存しない形式でインターフェイスを定義することができます。

Javaプログラミング言語で書かれているか、またはC、C++、COBOLなどの言語で書かれているかに関係なく、オブジェクトは相互に作用することができます。

## CORBA
CORBAとは、
Common Object Request Broker Architecture の略。「コーバ」とも呼ばれる。さまざまなプラットフォームでの分散処理の連携を実現するための基本仕様のこと。

ORBAの重要な特長はIDLにあります。
IDLは言語に中立なインタフェース定義言語です。

## 参考
ありがとうございます🙇‍♂️
https://mypage.otsuka-shokai.co.jp/contents/business-oyakudachi/words/corba.html
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/idl/GShome.html
【Docker】docker-compose up -dを行うと「tar: command not found」と表示されてしまった場合の対処法

# 概要
* `docker-compose up -d`を行うと「tar: command not found」「failed to solve: executor failed running...」というエラーが出て正常にビルドが完了しませんでした。今回はその解決方法を記します。

# エラー内容
* `docker-compose up -d`を行うと以下のエラがー表示されました。pyenvがPython-3.7.6をダウンロードしている途中で失敗してしまいました。

```bash
# (省略)
#0 7.239 /usr/local/pyenv/plugins/python-build/bin/python-build: line 456: tar: command not found
------
failed to solve: executor failed running [/bin/bash -c pyenv install -v 3.7.6 && pyenv global 3.7.6 && pip install awscli]: exit code: 1
```

# 解決手順
* pyenv指定でインストールしてみたり、bashrcをいじってみたり試行錯誤しましたが、結論、Dockerfileに以下を追加したら解決しました。

```
RUN yum install -y tar
```

* そもそも「tar: command not found」と出ていた理由は何かというと、Dockerfileに以下のように記載があったためです。

```
RUN yum install -y gcc bzip2 bzip2-devel openssl openssl-devel readline
readline-devel git libffi-devel wget gcc-c++ unixODBC-devel tar.x86_64
```

* このtar.x86_64がうまくインストールされなかった理由は、自分のローカルマシンがM1チップを搭載しているためです。M1チップは、Intelベースのアプリケーションと互換性がないため、x86_64アーキテクチャのパッケージをインストールすることができなかったのです。
* ということで、DockerイメージのベースイメージがIntelまたはARMアーキテクチャに基づいているかどうか、とても大事であることを感じたエラー体験でした。
Unityのスクリプトで頂点計算してポリゴンを描く

# はじめに
Unity上で、数式をベースに３Dオブジェクトを作っていくためのサンプル。
ただの四角形１つではなく、256x256のメッシュを作る。
法線計算は頂点座標から自動でやってくれるので助かる。

基本的には、頂点バッファ＆インデックスバッファをセットして描画なので、頂点の変更がないなら、高速。

頂点を毎フレーム更新するような使い方の場合は、書き換えの時間と、法線の再計算が発生するので、少し遅くなる。


# 環境
Unity 2021.3.17

# 手順
Create Emptyで空のオブジェクトを作る
Add ComponentからMesh Filterを追加する。
Add ComponentからMesh Rendererを追加する。
以下の新規スクリプトを作成し、追加する

```c#:DrawQuad.cs
using UnityEngine;

public class DrawQuad : MonoBehaviour
{
    Mesh mesh;
    Vector3[] v3s = new Vector3[256*256];//グリッドのサイズ
    int[] tri = new int[255*255*2 *3];//ポリゴン数*3頂点

    void Start()
    {
        mesh = new Mesh();

        //頂点座標計算
        for (int z = 0; z < 256; z ++)
        {
            for (int x = 0; x < 256; x ++)
            {
                float y; //適当な波で高さ
                y = Mathf.Sin(x * 0.1f);
                y *= Mathf.Sin(z * 0.2f);
                y *= 10;
                // 頂点座標
                v3s[z*256+x].Set(x, y, z);
            }
        }
        mesh.SetVertices(v3s);//頂点座標セット

        //インデックス計算
        for (int z = 0; z < 255; z++)
        {
            for (int x = 0; x < 255; x++)
            {
                // 三角形２個で一つの四角ポリゴン
                // １つ目の三角形
                tri[(z * 255 + x) * 6 + 0] = z * 256 + x;
                tri[(z * 255 + x) * 6 + 1] = z * 256 + x + 256;
                tri[(z * 255 + x) * 6 + 2] = z * 256 + x + 1;
                // ２つ目の三角形
                tri[(z * 255 + x) * 6 + 3] = z * 256 + x + 1;
                tri[(z * 255 + x) * 6 + 4] = z * 256 + x + 256;
                tri[(z * 255 + x) * 6 + 5] = z * 256 + x + 257;
            }
        }
        mesh.SetTriangles(tri, 0);//インデックスセット

        // 法線の計算
        mesh.RecalculateNormals();

        // 表示
        MeshFilter meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = mesh;

        MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
        meshRenderer.material = new Material(Shader.Find("Standard"));
        meshRenderer.material.color = Color.gray;
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/3e200ae9-2a80-98ac-d171-ce6d5d696c3b.png)

カメラ位置は、適宜、移動回転してください。

# 参考

グリッドのポリゴンメッシュの頂点番号をどのように計算式で表せばよいか、図説で参考になるはず。
床井先生のサイト
http://web.wakayama-u.ac.jp/~tokoi/unity_mesh.pdf
Azure Administrator(AZ-104)：Azure でのストレージの実装と管理「Shared Access Signature」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「Shared Access Signature」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure でのストレージの実装と管理](https://learn.microsoft.com/ja-jp/training/paths/az-104-manage-storage/)
◇対応するモジュール
[Shared Access Signature を作成する](https://learn.microsoft.com/ja-jp/training/modules/configure-storage-security/3-create-shared-access-signatures)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure でのストレージの実装と管理「Azure Storageのセキュリティ戦略」](https://qiita.com/fsd-jume/items/8411095ac53ddcdfc5b3)

## Shared Access Signature
### Shared Access Signature(SAS)の特徴
・Azure Storageリソースへの制限付きアクセス権を付与するURI
※URI：Uniform Resource Identifier
・クライアントにSAS URIを配布して、リソースへのアクセスを許可
⇒指定したアクセス許可セットで指定した期間のみ

**◆SASの使用シナリオ例**
・特定のストレージアカウントリソースへのアクセスが必要なクライアント
⇒ストレージアカウントキーで信頼されるべきでない場合に使用

### SASの種類
**◆ユーザ委任SAS**
・Azure AD資格情報でセキュリティ保護されたSAS
・Blob Storageにのみ適用
・セキュリティのベストプラクティスとしてMSが推奨
・事前にユーザ委任キーの要求が必要
⇒要求したユーザ委任キーでSASが作成可能

**◆サービスSAS**
・ストレージアカウントキーでセキュリティ保護
・1つだけのStorageサービスのリソースへのアクセスを委任

**◆アカウントSAS**
・ストレージアカウントキーでセキュリティ保護
・1つ以上のStorageサービスのリソースへのアクセスを委任
・サービスSASで許可されていない下記のアクセス委任も可能
　-読み取り操作
　-書き込み操作
　-削除操作

### SASの形式
**◆アドホックSAS**
・下記をSAS URIで指定
　-開始時刻
　-有効期限
　-アクセス許可
・任意の種類のSASをサポート

**◆保存されているアクセスポリシーによるサービスSAS**
・ポリシーはリソースコンテナで定義
・ポリシーにサービスSASを関連付け
⇒ポリシーに定義されている制約(期間やアクセス許可)を継承
・サービスSASのみサポート

### SASの種類と形式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/a8a79852-c3d3-fe55-8d43-5eb892a998e8.png)

### SAS構成設定のオプション
**◆IPアドレス**
・SASを受け入れるAzure StorageのIPアドレスやその範囲を識別可能
⇒組織の属するIPアドレスの範囲を指定する場合に使用

**◆プロトコル**
・Azure StorageがSASを受け入れるプロトコルを指定可能
⇒HTTPSを使ってクライアントへのアクセスを制限する場合に使用

## 次の学習内容
**◆URIパラメーターとSASパラメーター**

https://qiita.com/fsd-jume/items/423509eafb3f7a661537

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
【Network】IPアドレスとサブネットマスクについて

# IPアドレスについて

ネットワーク上の各機器に割り振られた機器を識別する為の番号です。
通信を行う際に、利用されます。ネットワーク上の住所と例えられたりします。

`IPアドレス`は、32ビット(2進数)で表記されています。
普段よく目にする`192.168.0.1`等の10進数で表記されている`IPアドレス`は、人に分かりやすいように変換されているものです。

```:2進数を10進数に変換
11000000 10101000 00000000 00000001 
                 ↓
     192      168        0        1   
```


`IPアドレス`は、ネットワーク部・ホスト部で構成されています。
ネットワーク部は`IPアドレス`が属しているネットワークを表しており、ホスト部はそのネットワーク内の機器を表しています。

`192.168.0.1/24`の場合は、前半24ビットがネットワーク部/後半8ビットがホスト部となります。
`192.168.0`がネットワーク部で、`1`がホスト部となります。

`192.168.0.1/24`と`192.168.0.2/24`は同じネットワークで通信が可能です。
`192.168.0.1/24`と`192.168.1.1/24`だとネットワークが違うので、通信を行う事が出来ないです。

Packet Tracerで確認してみます。
下記のように、PCを二つ用意しました。`192.168.0.1/24`と`192.168.0.2/24`でIPアドレス/サブネットの設定を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/fab8e0c2-c3f0-f9eb-b644-80d748a4c2d3.png)

```:192.168.0.1/24と192.168.0.2/24
C:\>ping 192.168.0.2

Pinging 192.168.0.2 with 32 bytes of data:

Reply from 192.168.0.2: bytes=32 time<1ms TTL=128
Reply from 192.168.0.2: bytes=32 time<1ms TTL=128
Reply from 192.168.0.2: bytes=32 time<1ms TTL=128
Reply from 192.168.0.2: bytes=32 time<1ms TTL=128

Ping statistics for 192.168.0.2:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
```

通信出来ている事を確認致しました。次に、`192.168.0.1/24`と`192.168.1.1/24`で試してみます。

```:192.168.0.1/24と192.168.1.1/24
C:\>ping 192.168.1.1

Pinging 192.168.1.1 with 32 bytes of data:

Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 192.168.1.1:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
```

ネットワークが違うので、失敗致しました。


# サブネットマスクについて
`サブネットマスク`は、IPアドレスのネットワーク部で使用するビット数を定義するものです。
`サブネットマスク`を指定する事で、ネットワーク部とホスト部がどこで区切られているかが分かります。

サブネットマスクが`255.255.255.0`で設定されている場合を想定します。
`255.255.255.0`を一旦、2進数に変換します。`11111111 11111111 11111111 00000000` となります。
2進数で`1`の部分がネットワーク部となります。`0`はホスト部となります。

ホスト部は10進数に変換すると、`2^8=256`までの値が該当する事がわかりました。
ネットワークアドレス(ホスト部が全て0)とブロードキャストアドレス(ホスト部が全て1)は予約されているIPとなる為、ネットワーク内に`254`個のホストアドレスを設定出来ます。


サブネットマスクを`255.255.254.0`で設定して、pingを飛ばしてみます。
2進数に変換すると、`11111111 11111111 11111110 00000000`です。
なので、ホストアドレスを`2^9-2=510`は作れます。
IPアドレスを`192.168.1.254`で設定します。

```:192.168.0.1/23と192.168.1.254/23
C:\>ping 192.168.1.254

Pinging 192.168.1.254 with 32 bytes of data:

Reply from 192.168.1.254: bytes=32 time<1ms TTL=128
Reply from 192.168.1.254: bytes=32 time<1ms TTL=128
Reply from 192.168.1.254: bytes=32 time<1ms TTL=128
Reply from 192.168.1.254: bytes=32 time<1ms TTL=128

Ping statistics for 192.168.1.254:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
```

通信出来ました。
以上です。
git flowとgithub flow

## はじめに
開発する上で、ブランチの運用方法を意識する事は全くありませんでした。
しかし、開発する環境が変わり、運用方法が違う事に驚いたので調べてみると、
git flow と github flow というものがある事を知りましたのでまとめます。
どちらもメリット・デメリットがあり、各開発現場の特徴に合わせる必要がありますが、
個人的な経験での好みは、github flow　が好きです。

## github flow
使うブランチは2つ
・masterブランチ(本番環境)
・作業ブランチ

masterブランチから作業ブランチを作成する。
↓
作業ブランチへの修正やプルリク・レビュー
↓
masterブランチへマージ(リリースとほぼ同義語)

● 良い点
・スピードある開発が出来る。
・同じ確認を繰り返す必要が無い。

● 注意点
・作業ブランチで修正したものがmasterブランチへマージされる為、
間違いが無いようテストや確認を慎重に行う必要がある。
・間違いが無いように、ドキュメント管理もしっかり行う必要があると思います。

## git flow
複数のブランチを使い分けて、順を追ってマージと確認をする。
ブランチは開発現場によって差異があるかも？

master
本番環境のブランチ

release
リリース準備をするためのブランチ

develop
開発用のブランチ

feature
developから派生し、機能の追加や、優先度の低いバグ修正などの度に発生するブランチ

hotfix
緊急的なバグ修正などのために、masterから派生するブランチ

参考:
ありがとうございます🙇‍♂️
https://www.konosumi.net/entry/2018/04/29/222602

●良い点
段階を分けて確認を慎重に行う事が出来る。

●注意点
github flowと比べると開発スピードが落ちる。
各環境で動作確認を行うので、同じ確認を複数回する。
github flowと比べるとコンフリクトに遭遇する事が多いように思いました。
3/27 Linux コマンド操作part3

# 個人的リマインダー用
標準入出力

## 用語説明
**出力** コマンドやプログラムの実行結果を外に向かって出すこと
**入力** キーボードから入力したコマンドなど、コンピューターにデータを受け渡すことを入力と言う
**標準** 入力元と出力先は指定すると変更することができる。指定しない場合はデフォルトで決められているものが使用されて、そのデフォルトで決まっているもののこと

**標準入力**
・プログラムの標準の入力
・キーボードが通常は使われる

**標準出力**
・プログラムの標準の出力
・ディスプレイが通常は使われる

**標準エラー出力**
・プログラムのエラーメッセージを出力する
・ディスプレイが通常は使われる

Linuxはコマンドの入出力先を抽象化することで、入出力先を柔軟に変更できる

## リダイレクト
### 入力のリダイレクト
・キーボードの代わりにファイルから入力する機能
```
/etc/hostsファイルを入力元にしてcatコマンドを実行

cat < /etc/hosts
```
### 出力のリダイレクト
・コマンドの実行結果を画面に表示するのではなく、ファイルに保存する機能
```
lsコマンドの出力先をls.txtにして保存

ls > output.txt
```
### エラー出力のリダイレクト

**標準入出力の数値**
標準入出力などをOSが識別するために用いる識別子
```
標準入力　0
標準出力　1
標準エラー出力　2
```

**エラー入力のリダイレクト**
エラー結果を画面に表示するのではなくファイルに保存する機能
```
ls /hoge 2> error.txt
```

**出力とエラー出力をまとめる**
アウトプットドットテキストの中に出力とエラー出力の両方をリダイレクトして保存できる
```
ls //hoge > output.txt 2>&1
2ダイレクトアンド1で標準エラー出力を標準出力と一緒にする
```

**リダイレクトで追記する**
「>」でリダイレクト指定するとファイルを上書きする
「>>」でリダイレクト指定するとファイルに追記する
```
echo Hello >> output.txt
```

## /dev/null
入力先を指定しても何も返さず、出力先として指定してもデータは消え何も表示されない、スペシャルファイル

**入力先として指定**
・入力が何もない状態
・コマンドのテストなどで入力を空にしたい時に使用する
```
cat < /dev/null
```

**出力先として指定**
・結果が何も表示されない
・結果が大量にあり、結果を非表示にしたい時に使用する
```
ls / > /dev/null
```

## パイプライン
複数のコマンドを連携させる機能。
コマンドの標準出力を別のコマンドの標準入力につなげる
```
コマンド | コマンド

ls /bin | less → ls /binをless（スクロール）で見れるようになる
ls /bin | grep systemd | less
```
AccessのVBAでコンボボックスの選択肢、列数、列幅を初期化（値リストとテーブルクエリ両方）

# 前提

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d40e0673-afbe-387f-e533-65e479939aef.png)

# やり方（値リスト1列）

```vb
Option Compare Database
Option Explicit

'フォームを開く時のイベント
Private Sub Form_Open(Cancel As Integer)
    
    '値集合タイプ
    Me.cmb_test.RowSourceType = "Value List"

    '選択肢を全て無くしておかないとフォームを開くたびに選択肢がどんどん追加されてしまう
    Me.cmb_test.RowSource = ""
    
    '列数
    Me.cmb_test.ColumnCount = 1
    
    '選択肢
    Me.cmb_test.AddItem "あ"
    Me.cmb_test.AddItem "い"
    Me.cmb_test.AddItem "う"
    Me.cmb_test.AddItem "え"
    
End Sub
```

結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9cdd298a-9805-fcee-c909-31537f46a623.png)

# やり方（値リスト2列）

```vb
Option Compare Database
Option Explicit

'フォームを開く時のイベント
Private Sub Form_Open(Cancel As Integer)
    
    '値集合タイプ
    Me.cmb_test.RowSourceType = "Value List"

    '選択肢を全て無くしておかないとフォームを開くたびに選択肢がどんどん追加されてしまう
    Me.cmb_test.RowSource = ""

    '列数
    Me.cmb_test.ColumnCount = 2
    
    '列幅調整して表示名だけにしたい時は下記を有効に
    'Me.cmb_test.ColumnWidths = "0cm;10cm;"
    
    '選択肢
    Me.cmb_test.AddItem "あ;あです;"
    Me.cmb_test.AddItem "い;いです;"
    Me.cmb_test.AddItem "う;うです;"
    Me.cmb_test.AddItem "え;えです;"
    
End Sub
```

結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7905f2a1-44cf-807f-3c6d-681f7d73b4de.png)

もし列幅調整のコメントアウトを外した場合は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/79335cce-b8f4-5040-e424-16c7500521db.png)

# やり方（テーブルクエリ）

下記のようなテーブルがある前提。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/110f5c29-e607-f502-826e-dc04e6cd9f3f.png)


```vb
Option Compare Database
Option Explicit

'フォームを開く時のイベント
Private Sub Form_Open(Cancel As Integer)
    
    '値集合タイプ
    Me.cmb_test.RowSourceType = "Table/Query"
    
    '値集合ソース
    Me.cmb_test.RowSource = "tester"
    
    '列数
    Me.cmb_test.ColumnCount = 2
    
    '列幅を調整して表示名だけにしたい時は下記を有効に
    'Me.cmb_test.ColumnWidths = "0cm;10cm;"
    
End Sub
```

結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/efa390b8-d52a-46b1-6769-886344e37b20.png)

列数が1の場合や列幅調整については『値リスト』で設定する場合と同様なので
割愛。

# 参考サイトさん

https://ray88.hatenablog.com/entry/2020/11/22/070006

https://learn.microsoft.com/ja-jp/office/vba/api/access.listbox.additem

https://www.feedsoft.net/access/tips/tips143.html

https://qiita.com/t-yama-3/items/db49ede52e1c8a35d679

http://www7b.biglobe.ne.jp/~cbcnet/cnntrol/cbo.html

https://hosopro.blogspot.com/2017/11/access-vba-combobox-table-query.html

https://ray88.hatenablog.com/entry/2021/03/22/135932

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2788
Microsoft Access for Microsoft 365 MSO (バージョン 2302 ビルド 16.0.16130.20298) 32 ビット
OracleDBでNULLを検索する時

# 概要
SQLのIN句に複数カラムを指定する方法とNULLのものも含めて検索することがありました。
具体的には以下のような形
```:sql
SELECT * FROM table
WHERE (column1, column2) IN (hoge,huga);
```
上記の形はうまく実行できますが、以下のようにnullが含まれるとうまく動作しません。

```:sql
SELECT * FROM table
WHERE (column1, column2,column3) IN ('hoge','huga',NULL);

```

実際に私の場合は値が変数でnullが入ってくる可能性もありました。
value3がnullの場合に何もデータが取得できないという状態でした。
```:sql
SELECT * FROM table
WHERE (column1, column2, column3) IN (value1,value2,value3);
```

# 対応方法
この時ORACLEのNVLという関数を使って対応しました。
NVL関数はNULL(空白として戻される)を文字列に置換して問合せの結果に含めることができます。

NVL(value3, 'NULL');

NVL関数を使うと、value3がnullだった時、文字列のNULLが設定されます。

```:sql
SELECT * FROM table
WHERE (NVL(column1, 'NULL'),NVL(column2, 'NULL'), NVL(column3, 'NULL')) IN (NVL(value1, 'NULL'),NVL(value2, 'NULL'),NVL(value3, 'NULL'));
```

これで想定している値が取得できました。
【クエリビルダ】プロンプトフィルターを使いこなす

データを扱うアプリケーションで必ず必要なクエリ、そのクエリの作成を支援するSharperlightアプリケーションが`クエリビルダ`です。
その`クエリビルダ`にはフィルター定義に関するオプション群のなかに**プロンプト専用フィルター**というものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bf1d4c45-c240-47fd-bbec-b391dcbdaaad.png)
今回は、その**プロンプト専用フィルター**を使用してみます。

Sharperlightクエリビルダで作成されたクエリは、Sharperlightエンジンにより動的にSQL文となり実行されます。
定義されるフィルターは、基本的にクエリ対象テーブルに存在する列に対して作成され、それらがSQL文のWHERE句を構成します。
しかしながら、そういった通常のフィルターに対して**プロンプト専用フィルター**オプションをオンにすると、そのフィルターは<font color="Red">**WHERE句から除外**</font>されます。

またクエリ対象テーブルに存在しない列をフィルターに追加し、引数あるいは変数としてクエリの拡張に使用する際、そういった列は強制的に**プロンプト専用フィルター**となり、WHERE句として生成されることはありません。

## プロンプト専用フィルターの動き ##
このようなクエリがあります。フィルターの**Canceled**を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/359f320c-f92e-cd93-171e-59be11665f42.png)
通常では、このクエリのSQL文のWHERE句はこのようになります。Canceledフィルターが使用されていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/117fbebe-247b-0274-6f94-05f25e89baa4.png)
今度は**プロンプト専用フィルター**オプションをオンにしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4aa0f34a-9ea2-ebdf-bc01-30050c80dc10.png)
背景が薄い黄色になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d1ae23f8-69a7-88ad-3fc2-94e390a4ffad.png)
生成されたSQL文では、このようにWHERE句には存在しなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/cc050a99-124a-9c0b-3e82-1eec98f12252.png)

## プロンプト専用フィルターの利用例 ##
### デバッグ時 ###
クエリの作成中は、結果を確認しながら作業をします。その作業中クエリに必要なフィルターなのに、結果確認のため一時的にWHERE句から外したい場合があります。そのような場合にそのフィルターを削除してしまうのではなく、**プロンプト専用フィルター**オプションをオンにして結果を確認し、その後はまたオフにすれば再度フィルターを定義し直す必要はありません。複雑な定義のフィルターであれば尚更のことです。
### 間接的にフィルターとして ###
クエリーへの引数的な使い方です。
**プロンプト専用フィルター**として定義したフィルターにある値を渡します。その値を元に別の通常フィルターの値を決定します。
参照:[【クエリビルダ】プロンプトフィルター：通常フィルター値の決定要因として使う](https://qiita.com/Miki_Yokohata/items/c8d4bcb3caf922df1b86)
### クエリ結果に値を渡す ###
これもクエリーへの引数的な使い方です。
**プロンプト専用フィルター**として定義したフィルターにある値を渡します。その値を出力アイテムとして出力したり、その値を元に他の出力アイテムの値を計算したりします。
参照:[【クエリビルダ】プロンプトフィルター：出力アイテムで使用する](https://qiita.com/Miki_Yokohata/items/ff03800bd5c3fddd9f15)
<br>
<br>
<br>
**プロンプト専用フィルター**を使用することで、かなりクエリ定義の幅が拡がるのではないでしょうか。
では、失礼します。
【UIKit】Cellに直接addSubviewしてはいけない

# CellのcontentViewにaddSubview()をする
UITableViewCellにviewを配置するとき、cellに直接`cell.addSubview(myView)`をすると配置したボタンのタップが反応しないなどの問題が発生する場合がある。
`cell.contentView.addSubview(myView)`とすることで正しく動作する。

[Apple Documentation](https://developer.apple.com/documentation/uikit/uicollectionviewcell#:~:text=Don%E2%80%99t%20directly%20add%20subviews%20to%20the%20cell%20itself.)にも同様のことが書かれている。
>Don’t directly add subviews to the cell itself.
PL-900: Microsoft Power Platform 基礎 受験記

# はじめに
PL-900を受験・無事合格したので、ノウハウをまとめます。

# 受験料無料特典
Microsoft Power Platform Virtual Training Day: Power Platform の基礎
を受講すると、受験料(￥12,500-)が無料になるバウチャーがもらえます。
開催は不定期のようです。

https://www.microsoft.com/ja-jp/events/top/training-days/powerplatform

# 学習法
AZ-900と比べると具体的で類似した用語が多く、ドリル的な学習をしただけでは一体何を学んでいるのかわからなくなります。
なので、可能であれば問題集で書かれている事が何なのか、実際に無料環境を利用して触ってみるのが良さそうです。

ですが、限られた期間で合格ラインを目指すとなるとのんびりしてもいられないので、効率の良い学習法を追求してみます。
個人の感想です。

## 教材
PL-900でWeb検索すると以下2つの学習講座がヒットしますが、クオリティが気になります。

### Udemy

- 有料(セールあり。￥2,000-前後)
- 正解がわかっても、解説のないものは自分で理由を調べる必要があり、そういったものは学習にはなりますが効率が良いとは言えません。  
  しかも正解が誤っていた場合、真実を確証できずモヤモヤします。
- 正解が誤っているものが見られます。

### ExamTopics

- 無料、116問以上は有料
- 正解が間違いだらけです。Discussionという項目でユーザーによる議論があるのですが、多い意見が正解とも限りません。  
  会員登録してもロボット対策のCAPTCHAはなくなりません。5問ごとにページが移動するのでユーザビリティも良くありません。  
  又、成績の記録もできません。有料登録すれば使いやすくなるのかもしれませんが、解答のクオリティの低さから有料登録はためらいました。
- 英語ですが、翻訳機能のあるブラウザーではあまり問題にはならないと思います。

Udemyは見直し機能等が使いやすく効率良く学習できるので良いプラットフォームではありますが、問題の内容には注意が必要です。
個人的には以下の2つが学習及び試験対策としての教材にはとても良かったです。

### Practice Assessment for Exam PL-900: Microsoft Power Platform Fundamentals

https://learn.microsoft.com/ja-jp/certifications/exams/pl-900/

- 上記リンク先の **無料の練習用評価を受ける** から50問ずつ、学習できます。
- 英語ですが、翻訳機能のあるブラウザーではあまり問題にはならないと思います。
- 出題はランダムですが、選択肢の並び方は変わりません。
- 最後にまとめて正解／不正解と理解傾向の分析が表示されますが、**Next** をクリックする前に **Check Your Answer** をクリックすれば1問ごとに確認する事もできます。
- 問題の内容は古いようです。"Common Data Service"が出てきますが、現在では"Microsoft Dataverse"です。
- 現在実際に出題される問題に近い内容はあまり無い印象ですが、解答が正確なので正しく理解する事ができ、  
  全ての問題に解説リンクがあり、リンク先はブラウザの設定が日本語向けになっていれば日本語のサイトにリダイレクトされるようになっています。

### PL-900 : Microsoft Power Platform Fundamentals 試験対策

https://info.microsoft.com/JA-PowerApps-WBNR-FY21-05May-03-MKTOFY21PL900PrepSessionOndemandWebinar-SRDEM73329_LP02OnDemandRegistration-ForminBody.html

- ウェビナー形式の講座です。
- こちらも内容はやや古いようですが、出題意図がわかりにくい問題等について丁寧に解説しているのでお勧めです。  
  UdemyやExamTopicsの問題で解答が怪しい問題については、これで確認すれば間違っているかどうかがほぼわかります。

### 動画
実際に触れなくても、どんな事ができるのか？どのように作るのか？イメージが具現化するのでお勧めです。

#### Power Platform

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

#### モデル駆動型アプリ

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

#### AI Builder

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

#### Power Virtual Agetnts

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

# 本番
65分で37問。試験時間は会場で手続きをしている時間も含まれているので実際に問題を解く時間はもっと短くなりました。
見たことのない問題も結構あり冷や汗をかきましたが、結果850点を超えていたので基礎的な理解をしていれば何とかなりそうです。

# まとめ
正確な情報をインプットして、効率よく学習しましょう！
Microsoft AZ-900: Microsoft Azure の基礎 受験記

# はじめに
AZ-900を受験・無事合格しました。
細かい事は色々な人が紹介していると思うので、自分が体験した事を中心にまとめます。

合格すると得られるMicrosoft Certified: Azure Fundamentalsとは、その名の通りAzureの基礎知識を証明する認定資格といえます。
AzureにおけるITパスポートのようなイメージですが
難易度は比較的やさしく、ひたすらドリル的な学習を繰り返せば合格は難しくありません。

https://learn.microsoft.com/ja-jp/certifications/exams/az-900/

# 受験料無料特典
Microsoft Power Platform Virtual Training Day: Azure の基礎
を受講すると、受験料(￥12,500-)が無料になるバウチャーがもらえます。
開催は不定期のようです。

https://www.microsoft.com/ja-jp/events/top/training-days/azure

# 教材
教材はたくさんあるようですが、職場の人に教えてもらった以下を受講しました。

https://www.udemy.com/course/microsoft-azure-az900-exam/

(6つ目の問題は過去の範囲という事で、混乱を恐れスキップしました)

解説も丁寧で繰り返し学習がしやすくお勧めです。

# 申込み
Udemyの講座でコンスタントに90点以上を獲れるようになったので、試験の申込みをしました。
(一日1～2時間やれば、半月もあれば十分な手応えでした)

冒頭の受験ページの **Pearson VUE でスケジュール** から申込みします。
(Person VUEではなくPearson VUE(ピアソン・ビュー) [CBTを代行する企業らしいです](https://ja.wikipedia.org/wiki/%E3%83%94%E3%82%A2%E3%82%BD%E3%83%B3VUE))
学生・教員の場合はCertiportになるようです。

資格もPearson VUEもグローバルなので、名前や住所は英語で登録しました。
無料特典もここで指定します(アカウントから自動的に候補が現れる)。

試験オプションから受験場所をテストセンターと在宅／職場から選択できます。
在宅で受験する場合 OnVUE というソフトを使って受験する事になりますが、
受験する場所の周りを撮影したり手の届く範囲に文字が読めるものがないようにしなければならなかったり
正面を見ていなかったり独り言をつぶやいていると注意される等、かなりシビアなチェックが入るようです。

OnVUEがうまく起動せず、面倒なのでテストセンターでの受験を選びました。

# 本番
テストセンターへ向かいます。
早目に着いてもすぐに受験できるようになっていました。

身分証明書が必ず必要になります。
免許証が当然日本語ですが、申し込んだ時の名前(ローマ字)が合っていれば大丈夫でした。
顔写真の撮影があるので、ヒゲとかは剃っておくと良いと思いました。
(そういう要件があるわけではありませんし、誰が見るのかわかりませんが...)

ローマ字読みのサインと受験規約に同意するサイン、開始時刻を自筆したら荷物や腕時計等をロッカーに預け
試験会場に入ります。パーティションで遮られたPCがあります。ITパスポート等と同じかな。
持ち物はその場で渡されるシートとペン(メモができる...が使わないな)のみです。

試験時間は65分で35問前後出題されます。
回答中は各問題に見直しのマークを付けたりテーマを変えたり英語に変えたりできるようになっています。
[試験サンドボックス](https://go.microsoft.com/fwlink/?linkid=2226877)があるので事前にユーザビリティを体験できますが、
会場にあったモニタの解像度はSXGAだったので設問は若干見づらいところがありました。

1つのセクションを通過すると前のセクションには戻れない、という説明でしたが
少なくともこの試験ではセクションには分かれていませんでした。

# 合格
問題を解き終わって"完了"をクリックするとすぐに試験結果が表示されました。
そのまま待っていると係の人がやって来て案内してくれましたが、受験者が少なかったからのようです。
入室時に受け取ったシートにあるPearson VUEの説明を読むと、終わったら退室して良いようでした。

最後に理解度がグラフで表示されます。そして、受付で受験結果をもらいました。

**スコアレポート**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116331/8920a7aa-6789-09e2-dd9e-6de4abda23f0.png)
本当は上の赤で囲ったところに青い棒グラフが出るはずなんだけど...ちゃんと印刷されてないよ！
(このスコアレポートはPearson VUEのサイトからあとでダウンロードできるらしい)

又、しばらくするとマイクロソフトから認定資格取得のメールが届きました。
スコアレポートは後程Pearson VUEのサイトからPDFファイルでダウンロードできるようになります。

# 不合格になると、どうなるの？

https://learn.microsoft.com/ja-jp/certifications/exam-retake-policy

- 1 回目で不合格となった場合は、再受験まで 24 時間待つ必要があります。
- その後のすべての再試験の間に 14 日間の待機期間が適用されます (最大 5 回)。

つまり、2回目は1日以上空けて、3回目以降は2周間空けないと受験できないようです。
Virtual Trainingの受講特典で無料で受験できたけど、12,500円かかると言われると急に高く感じますね。
折角の無料受験なので万全の状態で望みましょう。

# 最後に
マイクロソフトが無料で提供しているラーニングが充実しています。
([冒頭のページ](https://learn.microsoft.com/ja-jp/certifications/exams/az-900/)の **準備する2つの方法** から **マイペースで進められる**)
試験対策ではなくしっかりと学習するにはこちらがお勧めです。
すべてのラーニングを探すには以下から。

https://learn.microsoft.com/ja-jp/training/browse/
技術的に Qiita に書くべきじゃないかもしれない Excel ワークシート関数についての話

# Excel の DATE関数
Excel のワークシート関数の`DATE`関数は、とても便利な関数です。
`=DATE([年を示す数値],[月を示す数値],[日を示す数値])`を指定する事で、日付を得る事が出来ます。
例えば
`=DATE(2023,4,2)`
と記載すると、`2023/4/2`の日付を得られます。
## DATE関数は、ココがイケてる！
`DATE`関数がイケてると思うのは、引数に **本来の月数や日数を超える数値や、ゼロや負数を指定できる** ところです。
|関数例|結果|備考|
|:-:|:-:|:-|
|`=DATE(2023,13,1)`|`2024/1/1`|月に12以上の数を指定すると年の繰上げ、月数整えを行う|
|`=DATE(2023,2,30)`|`2023/3/2`|日にその月に無い数を指定すると月の繰上げ、日数整えを行う|
|`=DATE(2023,1,0)`|`2022/12/31`|日に Zero を指定すると前月の末日になる (超便利)|
|`=DATE(2023,-1,0)`|`2022/10/31`|月に負数を指定するとそれらを考慮した日付を返す|

とても便利です。
もう月末が何日か？とか、うるう年って何時？とか、悩まなくても月末が簡単に取得できますね！
日本は年度末決算が多いので、年を超えての計算が多いですが、そういう時にも便利なのです。
## 忍び寄る過去のしがらみ
学生時代、友人と下校時に、私が「もうすぐ初夏だねぇ」と言ったら
**「迫る〜ショッカー」** と歌いだした友人がいました。

さて、便利な`DATE`関数ですが、なぜか前述の **「イケてる機能」** が使えない事があります。
`#NUM`エラーが出るのです。
具体的には **引数の年・月・日の数値に負数やZero、存在しない大きな日付を指定できない** のです。
例えば、`=DATE(2023,2,30)` が `#NUM`エラーになります。
これを解決するには
`オプション`－`詳細設定`－`Lotus との互換性の設定`－`計算方式を変更する` のチェックを外してください。
この設定は **シート毎に設定される** ので注意してください。
### Lotus 1-2-3 を知らない人への補足
昔、まだ Windows が発売される前の MS-DOS (PC-DOS) が PC OS の主流だった頃、DOS 上で動く Lotus 1-2-3 という表計算ソフトがあったんです。
DOS 上で動くアプリとしては高度なマクロ機能があったり、色々凄いソフトで DOS で動く表計算ソフトとして高いシェアを持っていたのも納得のソフトです。
Excel は Windows 上で動く表計算ソフトとしては Lotus 1-2-3 より先行しましたし、表計算ソフトとしての完成度も(Lotus 1-2-3 の Windows 版の出来が悪かった事もあり) Excel の方が高かったのですが、DOS で Lotus 1-2-3 を使っていたユーザを Excel にスムーズに移行できるよう、一部のワークシート関数を Lotus 1-2-3 互換にしたり、キー操作を Lotus 1-2-3 互換にする機能が、私が確認できた範囲で Excel 2019 まで搭載されています。
このような Microsoft の努力により、Windows 上の表計算ソフトで高シェアを獲得できたわけです。

Lotus 1-2-3 については、下記の記事が参考になります。

https://ascii.jp/elem/000/001/473/1473571/

記事の通りメーカーは消えましたが、Excel の設定として`DATE`関数に影響を与える等、ある意味 **傷跡** を残してますね・・・

機能は遠く及びませんし、操作性も(紹介するのはviっぽかったりと)違いますが、画面の雰囲気が似てるという意味では、Linux で動く`SC`というアプリが、近い雰囲気が味わえます。
# 12月決算の会社だと、面倒が少なくて良さそう
日本は
+ 和暦
+ 3月決算(年度)

の2重苦の組織が多いですよね・・・
しらんけど。
スプレッド構文とは何か？

- スプレッド構文とは、配列やオブジェクトの展開を行う構文。
```javascript:単純な例
const arr = ['a', 'b' , 'c'];
console.log(arr); // ['a', 'b', 'c']
console.log(...arr); // a b c
```

#### 使い所（配列編）
```javascript:配列同士を結合する
const arr1 = ['a', 'b' , 'c'];
const arr2 = ['d', 'e'];
const arr3 = [...arr1, ...arr2];
console.log(arr3); // ['a', 'b', 'c', 'd', 'e']
```
```javascript:配列に要素を追加する
const arr1 = ['a', 'b' , 'c'];
const arr2 = [...arr1, 'd', 'e'];
console.log(arr2); // ['a', 'b', 'c', 'd', 'e']
```

```javascript:配列をシャローコピーする
/**
 * 前提
 * Javascriptの代入は単純代入になる
 */
let arr1 = ['a', 'b', 'c'];

// これは単純代入になる
let arr2 = arr1;

// arr1のみに要素を追加
arr1.push('d');
arr1.push('e');

// 配列の中身は同一になる
console.log(arr1); // ['a', 'b', 'c', 'd', 'e']
console.log(arr2); // ['a', 'b', 'c', 'd', 'e']

/**
 * スプレッド構文で代入はシャローコピーになる
 */
let arr3 = ['a', 'b', 'c'];

// これだとシャローコピー！
let arr4 = [...arr3];

// arr3のみに要素を追加
arr3.push('d');
arr3.push('e');

// 配列の中身は独立している
console.log(arr3); // ['a', 'b', 'c', 'd', 'e']
console.log(arr4); // ['a', 'b', 'c']
```

#### 使い所（オブジェクト編）
```javascript:オブジェクト同士を結合する
const obj1 = {
    a: 1,
    b: 2,
    c: 3
};
const obj2 = {
    d: 4,
    e: 5,
};

const obj3 = {...obj1, ...obj2};
console.log(obj3); // {a: 1, b: 2, c: 3, d: 4, e: 5}
```
```javascript:オブジェクト同士を結合する（同一のプロパティ名の場合は上書きされる）
const obj1 = {
    a: 1,
    b: 2,
    c: 3
};
const obj2 = {
    ...obj1,
    b: 4,
    c: 5
};
console.log(obj2); // {a: 1, b: 4, c: 5}
```
```javascript:オブジェクトにプロパティを追加する
const obj1 = {
    a: 1,
    b: 2,
    c: 3
};
const obj2 = {
    ...obj1,
    d: 4,
    e: 5,
};
console.log(obj2); // {a: 1, b: 2, c: 3, d: 4, e: 5}
```
```javascript:オブジェクトをシャローコピーする
/**
 * 前提
 * Javascriptの代入は単純代入になる
 */
let obj1 = {
    a: 1,
    b: 2,
    c: 3
};

// これも単純代入になる
let obj2 = obj1;

// arr1のみにプロパティを追加
obj1.d = 4;
obj1.e = 5;

// オブジェクトの中身は同一になる
console.log(obj1); // {a: 1, b: 2, c: 3, d: 4, e: 5}
console.log(obj2); // {a: 1, b: 2, c: 3, d: 4, e: 5}

/**
 * スプレッド構文で代入を行うとシャローコピーになる
 */
let obj3 = {
    a: 1,
    b: 2,
    c: 3
};

// これだとシャローコピー！
let obj4 = {...obj3};

// obj3のみにプロパティを追加
obj3.d = 4;
obj3.e = 5;

// オブジェクトの中身は独立している
console.log(obj3); // {a: 1, b: 2, c: 3, d: 4, e: 5}
console.log(obj4); // {a: 1, b: 2, c: 3}
```
Maltego Transform 開発メモ setIconURL(url_str)

* アイコンの画像を指定することができる

```python
    output_entity.setIconURL('https://i.insider.com/602ee9ced3ad27001837f2ac')
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/03a7e122-a2a7-b037-7780-584daf10b4c5.png)
[GitHub]2023/03/24からSSHのRSAでGitの通信エラーの対応

## はじめに

gitでpushをしたらエラーになったので対応をメモ。

```
% g push origin main
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s.
Please contact your system administrator.
Add correct host key in /Users/matsumoto/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/matsumoto/.ssh/known_hosts:1
Host key for github.com has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

```

## 原因

RSAのSSHを更新された模様。
これにより2023/03/24からsshでRSAを指定している場合、gitの通信ができなくなっている（push,fetch,pullなど）

https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/

# 対応
ドキュメント記載の通り

まず古いキーを削除する
```
ssh-keygen -R github.com
```

新しいキーを~/.ssh/known_hostsに追加コピーする
```
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
```
Maltego Transform 開発メモ setLink〇〇系

EntityとEntityを結ぶ矢印（Link）の書式を変更することができる。

* `setLinkLabel(str)` リンク上に表示させる文字列
* `setLinkStyle` 線の種類（実線、破線、点線など）
* `setLinkColor` 線の色
* `setLinkThickness` 線の幅

```python
    output_entity1=response.addEntity(Phrase, "テスト1")
    output_entity1.setLinkLabel("リンクのラベル1")
    output_entity1.setLinkStyle(LINK_STYLE_DASHDOT)
    output_entity1.setLinkThickness(1)
    output_entity1.setLinkColor("0xff0000") #Red

    output_entity2=response.addEntity(Phrase, "テスト2")
    output_entity2.setLinkLabel("リンクのラベル2")
    output_entity2.setLinkStyle(LINK_STYLE_DASHED)
    output_entity2.setLinkThickness(2)
    output_entity2.setLinkColor("0x00ff00") #Green
    
    output_entity3=response.addEntity(Phrase, "テスト3")
    output_entity3.setLinkLabel("リンクのラベル3")
    output_entity3.setLinkStyle(LINK_STYLE_DOTTED)
    output_entity3.setLinkThickness(3)
    output_entity3.setLinkColor("0x0000ff") #Blue

    output_entity4=response.addEntity(Phrase, "テスト4")
    output_entity4.setLinkLabel("リンクのラベル4")
    output_entity4.setLinkStyle(LINK_STYLE_NORMAL)
    output_entity4.setLinkThickness(4)
    output_entity4.setLinkColor("0x000000") #Black
```
出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/d14c8026-0b4f-5759-336a-c3e23379c0db.png)
デイトラ「Web制作コース」　受講内容をアウトプット 23日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース中級編」　JavaScript・jQuery学習編
②Web制作初心者のためのJavaScript基礎講座（DOM操作）
　・「DOM」とはHTMLなどのドキュメントにJavaScriptからアクセスするための仕組み
　・document.getElementByIdは、documentの中から指定したIDがついてるHTMLオブジェクトを探して取得できる。
　・alertはポップアップ表示、outreHTMLは取得したオブジェクトのHTML全文を表示する。
　・document.getElementsByClassNameは、documentの中から指定したclassがついてるHTMLオブジェクトを探して取得できる。
　　※idとは違い、配列で返ってくる点に注意
　・document.getElementsByTagNameは、documentの中から指定したタグがついてるHTMLオブジェクトを探して取得できる。
　　※これも配列で返ってくる
　・取得したHTMLデータは、innerTexで文字を書き換えることが可能
　・JavaScriptでHTML要素の追加方法
　・JavaScriptからクリック操作
　　⇒document.getElementById("id名").click()で操作できる
　・イベント処理を追加しよう（onload編）
　　⇒ window.onload() = funciton(){}でDOM（HTMLデータ）が読み込まれた後に実行したい処理を追加できる。
　　　　読み込み後に実行したい処理はfunction() {  }の中に書く。
　・イベント処理を追加しよう（click編）
　　⇒ユーザーによってボタンがクリックされたときの処理を追加の仕方。イベントの処理にはaddEventListener()メソッドを使う。
　　　第一引数に監視したいイベント、第二引数にそのイベントが起きた時の処理を書く。第二引数は必ずfunction する。

③なし
④なし
⑤なし
⑥なし
【学習メモ】ChatGPT4のできること

## できることは一般的には以下の３つ
1:推論
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/9b23f8a0-2ed3-0572-cf0b-9eed9a9ae606.png)
2:画像認識
3:正確な回答（ChatGPT3の時もできていた）

上記以外にもできることがあるが、全ては解明されていない。
作成者であるOpenAIですら把握しきれていないため、使い方を企業や個人が見出していく。
その時にまた新たなChatGPT4、そしてAIの世界が広まる。
![FrHoDs-WIAMYoeX.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/25055c62-5476-714a-fffd-6bb9a6332146.jpeg)

## そもそもChatGPT4とは
大量のインターネット上のテキストデータをを学習することで、自然言語理解（NLU）と自然言語生成（NLG）のタスクを効果的に実行できます。 これにより、文章生成、質問応答、概要作成、翻訳、会話など、さまざまなタスクが可能になります。

## 画像認識で何ができるか
・この画像のどこがおかしいですか？
https://twitter.com/mygw1212/status/1635756378999644160?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1635756378999644160%7Ctwgr%5Ed04dc903e10c8fe37a8e8a1fdad1fa15936d9afa%7Ctwcon%5Es1_c10&ref_url=https%3A%2F%2Fsottyann.com%2Fwhat-can-chatgpt4-do

・手書きのメモを言語として認識可能
手書きの議事録などをデータに落とし込める

・手書きのホームページの構成案の画像を送るとHTMLのコードを作成してくれる

・問題作成
「短文の英語のストーリーと、その内容に対する英語の質問を3つの選択形式で回答する問題を5問作成してください。これは、中学3年生レベルでお願いします。」


## ChatGPT4は学習させることが可能
・何かルールを教えて（しりとり）ゲームをすることができる
・法律と判例を際限なく学ばさせ、弁護士に頼らない活用方法

## プログラムの生成
よりバグが少なく、複雑なコードを生成可能

## 複雑な質問に対しての回答が柔軟に
シンデレラのストーリーをAからZまで並べて作成して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/f8e9ade6-968e-2e41-972a-14f4f9e67941.png)

## マークダウン形式に対応
マークダウン形式で記事を書いてくれます。そのままWordPressにコピペすれば ブログとしてアップできます。
CSVファイルから散布図とグラフを作成し，1枚の図で表示する方法(2軸グラフ)

# プログラムについて
ChatGPTを使って，CSVファイルから散布図とグラフを作成し，1枚の図で表示するプログラムを作りました．

# 環境
- MacBook Air(M1, 2020)
- Python 3.8.8

# プログラム
```python:ScatterPlot3.py
import sys
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# コマンドライン引数からファイル名を取得する
if len(sys.argv) != 4:
    print("Usage: python graph.py file1.csv file2.csv file3.csv")
    sys.exit(1)

file1 = sys.argv[1]
file2 = sys.argv[2]
file3 = sys.argv[3]

# 1つ目のCSVファイルを読み取る
df1 = pd.read_csv(file1)
cols1 = df1.columns.tolist()
x_col1 = cols1[0]  # 1つ目の列をxとする
y_col1 = cols1[1]  # 2つ目の列をyとする
x1 = df1[x_col1]
y1 = df1[y_col1]

# 2つ目のCSVファイルを読み取る
df2 = pd.read_csv(file2)
cols2 = df2.columns.tolist()
x_col2 = cols2[0]  # 1つ目の列をxとする
y_col2 = cols2[1]  # 2つ目の列をyとする
x2 = df2[x_col2]
y2 = df2[y_col2]

# 3つ目のCSVファイルを読み取る
df3 = pd.read_csv(file3)
cols3 = df3.columns.tolist()
x_col3 = cols3[0]  # 1つ目の列をxとする
y_col3_1 = cols3[1]  # 2つ目の列をy1とする
y_col3_2 = cols3[2]  # 3つ目の列をy2とする
x3 = df3[x_col3]
y3_1 = df3[y_col3_1]
y3_2 = df3[y_col3_2]

# グラフを作成する
fig, ax1 = plt.subplots()

# 1つ目のデータをプロットする
color = 'tab:red'
ax1.set_xlabel('time')
ax1.set_ylabel('$log_{10}(r)$', color='black')
ax1.scatter(x1, np.log10(y1), color=color, label='1', s=6)

# 2つ目のデータをプロットする
color = 'tab:blue'
ax1.scatter(x1, np.log10(y2), color=color, label='2', s=6)

# 3つ目のデータをプロットする
ax2 = ax1.twinx()
color = 'tab:green'
ax2.set_ylabel('sine', color='black')
ax2.plot(x3, y3_1, color='black', label='Input')
ax2.plot(x3, y3_2, color='green', label='Output')

# グラフの凡例を表示する
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines1 + lines2, labels1 + labels2, loc='best')

# グラフの設定を調整する
fig.tight_layout()

# PNG形式で保存する
plt.savefig('graph.png')
```

# 実行結果
今回はテストとして，大きさの異なる２つのデータ(test1.csv, test2.csv)，
sin関数のデータ(test3.csv)の合計3つのデータを表示するようにしています．


```:実行例
python3 ScatterPlot3.py test1.csv test2.csv test3.csv
```
作成された図は以下のようになっています．

![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2758310/daafc8ab-9669-0e85-0ea5-3d277c4ca590.png)
Playwrightで始めるテスト自動化（1. 環境構築編）

## はじめに

現在、 Playwright を使用したテスト自動化環境の構築対応をしております。
対応を通して得た知見が溜まってきたので、今回記事にまとめていきたいと思います。


4つの記事に分けてまとめていく予定です。
1. 環境構築編　**← 今回の記事**
2. テスト実装編
3. VisualRegressionTest 導入編
4. Docker 環境構築編

VisualRegressionTest の導入や Docker 環境の構築ではハマることが多かったので、
どのような問題に直面し、どう解決したかを紹介できればと思っております。
## Playwright とは
Playwright とは、Microsoft が中心となって開発をしている OSS のブラウザテスト自動化フレームワークです。
Chromium ( Chrome / Edge )、Firefox、 Webkit ( Safari ) が 1 つの API で実行できるため、クロスブラウザでのテストが容易に行えます。
GoogleChrome for Android や Mobile Safari の デバイスエミュレーションを使用して SP 版のテストを行うことも可能です。

https://playwright.dev/

## バージョン
本記事では以下バージョンでの動作を記載しております。
- Node.js : v18.15.0
- npm : v9.5.0
- Playwright : 1.32

端末はM1 Macを使用しております。
## インストール
前提条件： Node.js と npm を事前にインストールしておいてください。

npm, yarn, pnpm を使用して Playwright をインストールすることができます。
本記事では npm を使用してインストールを行なっていきます。
``` shell
 $ npm init playwright@latest
```

インストールコマンドを実行すると以下の選択肢が表示されます。
こちらは使用される環境に併せて選択すれば OK です。
本記事では以下のように設定しております。
```shell
 # TypeScript か JavaScript のどちらかを選択する
 ✔ Do you want to use TypeScript or JavaScript? · TypeScript

 # e2e テストファイルが格納されるフォルダの名前
 ✔ Where to put your end-to-end tests? · tests

 # GitHub Actions のワークフローを追加するか
 ✔ Add a GitHub Actions workflow? (y/N) · false

 # Playwright で使用するブラウザをインストールするか
 ✔ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true 
```


```Happy hacking! 🎭``` がターミナルに出力されたらインストール完了となります。

インストールが完了すると以下のようなディレクトリ構成になります。
```
 │── node_modules
 │── tests
 │   └── example.spec.ts       # 基本的なサンプルテスト
 │── tests-examples
 │   └── demo-todo-app.spec.ts # ToDoアプリをテストするための詳細なサンプルテスト
 │── .gitignore
 │── package-lock.json
 │── package.json
 └── playwright.config.ts      # 実行するブラウザの変更など Playwright の設定を追加するファイル
```
## サンプルテストの実行
tests ディレクトリ配下にあるサンプルテスト example.spec.ts を実行してみましょう。
以下のコマンドでテストを実行することができます。
```shell
 $ npx playwright test
```
デフォルトでは、Chromium, Firefox, Webkit のブラウザすべてでテストが実行されます。
この設定は playwright.config.ts で変更することができます。

https://playwright.dev/docs/api/class-testconfig#test-config-projects

また、実行時のオプションでブラウザを指定することも可能です。
```shell
 # chromium ブラウザのみでテストが実行されます。
 $ npx playwright test --project=chromium
```
テストはヘッドレスモードで実行されるためブラウザは開きません。
実行時のオプション追加でブラウザが開かれた状態でテストを実行することができます。
```shell
 $ npx playwright test --headed
```

## テストレポート
テストの実行が完了すると HTML レポートが作成されます。
playwright-report / index.html

以下のコマンドを実行することで HTML レポートを確認することができます。
```shell
 $ npx playwright show-report
```

デフォルトのレポーター設定が html になっているため、 HTML レポートが出力されます。
この設定は playwright.config.ts で変更することができます。

https://playwright.dev/docs/test-reporters

また、実行時のオプションでレポーターを指定することも可能です。
```shell
 # ターミナルに結果が出力される
 $ npx playwright test --reporter=list
```

## 次回予告： 2. テスト実装編
Playwright の環境構築ができたので、次回はテストの実装について記載していきたいと思います。
様々な Locators や Assertions を使用したサンプルテストを実装しようと考えております。