OmniAICreator/Qiita-1.07M huggingface dataset:
Lightsailで仮想コンソールが開けなくなった

以下の記事の転載です。

　　Lightsailで仮想コンソールが開けない｜kinneko｜pixivFANBOX
　　https://kinneko.fanbox.cc/posts/3628713
　　(支援者向け専用記事になっているので、支援者以外は読めません。)

---
　LightsailでUbuntuのインスタンスを作って、スタティックアドレスを振り、ブラウザでアクセスできる仮想コンソールを起動する。
　右上のオレンジの四角のアイコンで、ブラウザのウインドウが新しく開いて、まるでsshしたかのようなコンソール操作ができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/144dd757-4b98-9243-b4e5-b6c63466fe4b.png)
　ブラウザで開いたコンソールで、sudo apt-get update && sudo apt updateを実行した。途中、「sshdをメンテナバージョンに差し替えるか？」的なダイアログが出てきたけど、素直に入れ替えた。
　すると、Lightsailの仮想コンソールからサインインできなくなった。めんどくさいことだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/531d6428-1711-111b-fc53-6b377e986a6b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/b6097cae-64ab-7dc0-21ee-3dea96b4ae27.png)
『Log in failed. If this instance has just started up, try again in a minute or two.
CLIENT_UNAUTHORIZED [769]』

　復旧するには、sshで接続する必要がある。もちろん、インスタンス作成時に鍵を払い出しておく必要がある。
　事前に作成していなかった場合は、画面右上にあるAccountから設定できる... と思ったけど、後から作ってあるインスタンスに流し込むとかできるのだろうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/5cb9d37d-2084-dc49-ccbd-fee2d8acdd62.png)
　ここでは、そこには突っ込まずに、鍵は"LightsailKey.pem"として作ってあった前提で進める。

```
$ chmod 700 LightsailKey.pem
$ ssh -i "LightsailKey.pem" ubuntu@xxx.xxx.xxx.xxx
```
　Lightsailの独自CA設定をsshdの設定の末尾に追記する。
```
ubuntu@ip-xxx-xxx-xxx-xxx:~$ sudo vi /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/lightsail_instance_ca.pub
CASignatureAlgorithms +ssh-rsa
```
　sshdを再起動する。
```
ubuntu@ip-xxx-xxx-xxx-xxx:~$ sudo /etc/init.d/ssh restart
Restarting ssh (via systemctl): ssh.service.
```
　LightsailのGUIから、仮想コンソールに入れることを確認した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/1f908bcc-a3de-b149-3dcd-b776a847dfca.png)
EclipseとIntelliJでよく使うショートカットキー

## EclipseとIntelliJでよく使うショートカットキー
最近IntelliJを使うようになったので、
Eclipseでよく使っていたショートカットキーを記載。

|操作|Eclipse|IntelliJ
|----|----|----|
|ファイル名検索|[Ctrl] + [Shift] + r|[Ctrl] + [Shift] + n|
|Grep検索|検索タブ⇒ファイル検索|[Ctrl] + [Shift] + f|
|定義に移動|F3|[Ctrl] + b|
|移動前の場所に戻る|[Alt] + ← or →|[Ctrl] + [Alt] + ← or →|
|エディタのタブを閉じる|[Ctrl] + w|[Ctrl] + F4|
|次のブレークポイントまで実行|F8|F9|
|インデント処理|[Ctrl] + i|[Ctrl] + [Alt] + i|
|指定の行へジャンプ|[Ctrl] + l|[Ctrl] + [Alt] + g|
|対応する括弧にジャンプ|[Ctrl] + [Shift] + p|[Ctrl] + [Shift] + m|
CloudWatchカスタムメトリクスのデータをboto3で取得

こちらの記事を参考に、boto3を使用してCloudWatchメトリクスデータを取得しようとしました。

https://qiita.com/K-Nomu3/items/ae7b043c6a75a774edc7

標準メトリクスデータは問題なく取得できたのですが、EC2のメモリ使用率等のカスタムメトリクスデータを同じように取得しようとしてもデータ件数0件でレスポンスが返されてしまったので、原因を調査しました。

# 原因

メトリクスが複数のディメンションで作成されている場合、取得時に全てのディメンションを指定する必要がありました。
ディメンションとは、メトリクスの一意の識別子として機能するものです。
先の記事では標準メトリクスを取得するにあたりディメンションは「InstanceId」のみの指定で十分でしたが、カスタムメトリクスでは不十分でした。

# 解決方法

今回は名前空間「CWAgent」の「mem_used_percent」データを取得します。

### ディメンションを調べる

コンソールで下記を実行します。
```
$ aws cloudwatch list-metrics --namespace CWAgent
```

メトリクス一覧が表示されるので、お目当てのメトリクスのDimentionsを確認します。
```
{
    "Metrics": [
        {
            "Namespace": "CWAgent",
            "MetricName": "mem_used_percent",
            "Dimensions": [
                {
                    "Name": "InstanceId",
                    "Value": "i-*******"
                },
                {
                    "Name": "ImageId",
                    "Value": "ami-***********"
                },
                {
                    "Name": "InstanceType",
                    "Value": "t2.micro"
                }
            ]
        },
        ：
        省略
```

mem_ussed_percentのディメンションは`InstanceId`、`ImageId`、`InstanceType`で作成されています。

### カスタムメトリクスデータを取得

boto3でデータを取得する際のディメンションの指定箇所を変更すればOKです。

```python
import json
from datetime import datetime
import boto3

# cloudwatchのクライアント取得
client = boto3.client('cloudwatch')
response = client.get_metric_statistics(
          Namespace = "CWAgent",
          MetricName = "mem_used_percent",
          Dimensions=[{'Name': 'InstanceId', 'Value': 'i-*******'},{'Name': 'ImageId', 'Value': 'ami-***********'}, {'Name': 'InstanceType', 'Value': 't2.micro'}],
          StartTime = datetime(2022, 3, 7, 9, 0),
          EndTime = datetime(2022, 3, 10, 23, 55),
          Period = 300,
          Statistics = ['Maximum'],
      )
```

# 参考

https://cloud5.jp/cli-cloudwatch-metric/#--3
VSCodeでSpringboot＋Thymeleafアプリを１から作成（環境構築編）

# 概要
- 本題の通り。SEをやっていながら直近はShellやサーバ構築などに携わり、Javaなどの開発案件に久しく関わっていなかった。かつ新規開発案件はほぼ初。
- 頑張ったね私、という自分への鼓舞が主な目的

# 環境
- JDK17.0.2
- Springboot 2.6.6
- Gradle

# VSCodeでSpringboot環境を構築
- 先人の知恵を参考に、一部手順を変更して構築しました
参考：https://tech-lab.sios.jp/archives/19941

## VSCodeインストール
- もともと私はインストールしてたので特に何もやってないが、以下からダウンロードしましょう。
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

## 拡張機能ダウンロード
- VSCodeくんにまずは必要最低限の拡張機能をダウンロードしてあげましょう。
- これによりVSCodeが「Javaいけます」「Springboot使えます」といった優秀な部下に大変身します。
  - Java Extension Pack
  - Spring Boot Extension Pack
  - Lombok Annotations Support for VS Code

## プロジェクト作成
- コマンドパレットに「Spring」を入力
- Spring Initializr: Generate a Gradle Projectを選択
- バージョンを選択（最新がいい場合は公式サイトhttps://spring.io/projects/spring-boot をみてバージョン確認するといいです）
- Javaを選択
- パッケージ名を入力
- プロジェクト名を入力
- 依存関係の選択
  - Spring Web
  - Thymeleaf
  - Lombok
- プロジェクト保存先の指定
VSCodeの右下に「Successfully generated」と表示されていれば作成完了です！やったあ！

## Hello Worldを表示
### ディレクトリ、ファイルの作成
- 作成したプロジェクト配下にcontrollerディレクトリを作成します
- controllerディレクトリ内に「HelloController.java」を作成します
- 以下のように内容を修正してみましょう。

```HelloController.java
// パッケージ名は作成したときのものに合わせてね
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
    @RequestMapping("/hello")
	public String index() {
		return "hello";
	}
}
```

- src/main/resources/templates/内にhello.htmlを作成します。

```hello.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello!!!</title>
</head>
<body>
    <h1>HelloWorld</h1>
</body>
</html>
```

### いざ実行
- 実行→デバッグなしで実行
- 「http://localhost:8080/hello」にアクセスしてみると、Hello Worldが表示されます！これで完成！やったね！！

# まとめ
- とりあえず、環境構築→プロジェクト作成→Hello World表示までの導入部分を今回は記事にしてみました。
- 現在進行系で開発を進めているので、空いた時間で次の段階についてまとめていきたいと思います。
- 今回Thymeleafは全くと言っていいほど登場していませんが、今後大活躍するから・・・・してるから・・・
aws_datasync_taskでTransfer and verification completed. Verification detected mismatches. Files with mismatches are listed in Cloud Watch Logs

## 事象
- terraformで`aws_datasync_task`でタスクを作成して実行したところ以下のエラーが発生しました。

```
Transfer and verification completed. Verification detected mismatches. 
Files with mismatches are listed in Cloud Watch Logs
```

CloudWatchLogを見ても以下のエラーが出ていてよくわかりませんでした。
```
[NOTICE] Verification failed < /zqvchszsCnDVlOLMEywArJHhGhNvxhDs.png
```

## 原因
- DataSyncのタスク実行中に、Sync元にファイルが生成されてしまった為、タスク内のチェックでエラーが発生した。
- `aws_datasync_task`だとデータ検証オプション（`verify_mode`）のデフォルトが`Verify all data in the destination(POINT_IN_TIME_CONSISTENT)`となっていた為。

## 対応
- 以下のように`verify_mode`を`ONLY_FILES_TRANSFERRED`にした。

```terraform
resource "aws_datasync_task" "default" {
  name                     = "something_name"
  source_location_arn      = aws_datasync_location_s3.source.arn
  destination_location_arn = aws_datasync_location_s3.destination.arn
  cloudwatch_log_group_arn = aws_cloudwatch_log_group.default.arn

  options {
    gid               = "NONE"
    posix_permissions = "NONE"
    uid               = "NONE"
    log_level         = "BASIC"
    verify_mode       = "ONLY_FILES_TRANSFERRED"
  }
}

```



## See
- https://docs.aws.amazon.com/ja_jp/datasync/latest/userguide/create-task.html#configure-data-verification-options
プログラミングノート（TypeScript③　高度な型）

# はじめに
Udemyの[【世界で7万人が受講】Understanding TypeScript 日本語版](https://www.udemy.com/course/understanding-typescript-jp)を参考にTypeScriptを学習したので、プログラミングノート（カンペ用ノート）をします。

# 交差型
複数の型を結合する
```ts
type Admin = {
  name: string;
  privileges: string[];
};

type Employee = {
  name: string;
  startDate: Date;
};
// 交差型
type ElevatedEmployee = Admin & Employee;
```

# 型ガード
## 型によって挙動を変える
```ts
function add(a: Combinable, b: Combinable) {
  if (typeof a === "string" || typeof b === "string") {
    return a.toString() + b.toString();
  }
  return a + b;
}
```
## オブジェクトのプロパティによって挙動を変える
```ts
type UnknownEmployee = Employee | Admin;
function printEmployeeInformation(emp: UnknownEmployee) {
  console.log(emp.name);
  if ("privileges" in emp) {
    console.log("Privileges: " + emp.privileges);
  }
  if ("startDate" in emp) {
    console.log("Start Date: " + emp.startDate);
  }
}
```

## オブジェクトによって挙動を変える
```ts
function useVehicle(vehicle: Vehicle) {
  vehicle.drive();
  if (vehicle instanceof Truck) {
    vehicle.loadCargo(1000);
  }
}
```



# 判別可能なUnion型
共通なプロパティを持っている場合に、そのプロパティによってどのオブジェクトかを判別可能
interfaceやクラスを使うことでミスを防ぐことができる。

```ts
interface Bird {
  type: "bird"; // birdという文字列のみを許可するリテラル型
  flyingSpeed: number;
}

interface Horse {
  type: "horse";
  runningSpeed: number;
}

type Animal = Bird | Horse;

function moveAnimal(animal: Animal) {
  let speed;
  // typeというプロパティによってオブジェクトを判別する。 
  switch (animal.type) {
    case "bird":
      speed = animal.flyingSpeed;
      break;
    case "horse":
      speed = animal.runningSpeed;
  }
}
```

# 型キャスト
TypeScriptが型を推論できない場合に使う。
!はnullでないことを伝える
as HTMLInputElement でinputの要素であることを伝える。
```ts
const userInputElement = document.getElementById(
"user-input"
)! as HTMLInputElement;
```

# index型
プロパティと値の型を指定する。

```ts
interface ErrorContainer {
  [prop: string]: string; // index型。このinterfaceプロパティはstring 値もstringでないといけない。
}

const errorBag: ErrorContainer = {
  email: "正しいメールアドレスではありません", // プロパティも値もstringと解釈できる
  username: "ユーザ名に記号を含めることはできません。",
};
```

# 関数オーバーロード
どのような引数をサポートし、何を返すのかを定義する。
```ts
unction add(a: number, b: number): number; // 引数が両方numberなら戻り値もnumber
function add(a: string, b: string): string; // 引数が両方stringなら戻り値もstring
function add(a: string, b: number): string;
function add(a: number, b: string): string;
function add(a: Combinable, b: Combinable) {
  // 型によって動作を変える（型ガード）
  if (typeof a === "string" || typeof b === "string") {
    return a.toString() + b.toString();
  }
  return a + b;
}

const result = add("Hello", "TypeScript");
result.split("");
```

# オプショナルチェーン
プロパティが存在しているか確証が持てない場合に使う。
存在している場合にのみアクセスする。
```ts
const fetchedUserData = {
  id: "u1",
  name: "user1",
  job: {
    title: "Developer",
    description: "TypeScript",
  },
};
console.log(fetchedUserData?.job?.title);
```

# null合体演算子
nullかundefinedの場合は後続の文字列を使用する。
```ts
const userInput = null;
const storedData = userInput ??  "DEFAULT";

console.log(storedData);
```
lightsail amazonlinux2 で cron

# さぁ、cronを動かそう。


といっても最初から動いているので、テスト設定するだけ。


```cron.txt
MAILTO=your@email.com
#SHELL=/bin/sh
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin


# cron
* * * * * cd / >> /dev/null 2>&1
```


デバッグなので適当に。

2,3分経過したら cron が動いているか確認



`tail /var/log/cron`

```
Apr 21 14:45:01 ip-172-26-5-92 CROND[18641]: (root) CMD (cd />> /dev/null 2>&1)
Apr 21 14:46:01 ip-172-26-5-92 CROND[18720]: (root) CMD (cd />> /dev/null 2>&1)
```

`OK`
LinkStation(LS-WVL)にDebian Bullseyeをインストール

# 経緯
　以前より、以下URLのサイト様の手順の通りにDebianサーバ化し、nfsやiSCSI、sambaでのSMB3でファイルサーバとして利用していました。
　ただ、某大学のクレカ特典でGoogle Driveが無制限で利用可能だったのがサービス終了になると**2ヶ月前**に突然通知がありプライベートクラウドを構築してそちらに移行しようと環境を再構築することになりました。。

# 謝意
　手順については、ほぼこちらのサイトと同じですし、画像つきでとてもわかり易く説明されていらっしゃいますので、そちらも合わせて御覧ください。

https://wv4short.com/installing_debian_9_to_linkstation_ls-xhl_ls-vl_part1/

# 変更手順
## インストールイメージ取得
http://ftp.jp.debian.org/debian/dists/bullseye/main/installer-armel/current/images/kirkwood/network-console/buffalo/

上記URLに、機種別でディレクトリが切られてあります。該当のディレクトリにアクセスし、
- initrd.buffalo
- uImage.buffalo

をダウンロードします。configについては使用しません。

なお、世代によってCPUが異なるので、``kirkwood``か``orion5x``が変わります。
この手順は``kirkwood``の手順です。``orion5x``についてはやり方が違うと思います。

## NASに搭載するディスクにイメージを配置
私が所有しているLS-WVLはHDDが2台搭載できるモデルです。ソフトウェアRAIDによってデータの冗長性を向上できます。

### HDDのパーティショニングとフォーマット
基本的に手順は自分が参考にしたサイト様と同一です。
ただし、RAIDを構築する場合は**RAIDを構成するHDD全てに``initrd``と``uImage``をコピーしてください。**
個人的にはい以下の手順を踏みました。
- HDDをGPTでラベリング
```
# parted /dev/sdX
(parted) mklabel gpt↩
```
- １GB分のパーティションを切る
```
(parted) mkpart
name? []? ↩
File system type?  [ext2]? ext3↩
start? 0%↩
end? 1GB↩
```
- 確認してpartedを閉じる
```
(parted) p↩
・・・
(parted) q↩
```
- できたパーティションをext3でフォーマット
```
# mkfs.ext3 /dev/sdX1
```
あとは、ダウンロードした``initrd``と``uImage``をコピーするだけです。
以上の手順をすべてのHDDに行ってください。

## HDDをNASに組み込んでインストール開始
RAID構成するすべてのHDDをセットして、電源をいれます。

:::note warn
電源ランプについて
公式イメージでは、インストールが正常完了するまで「準備中」を表す点滅のままになります。
ほかのインストーラとして有名な[``1000001101000``さんの``Debian_on_Buffalo``](https://github.com/1000001101000/Debian_on_Buffalo)の電源ランプの挙動とは異なりますので、注意してください。
:::

Wiresharkや、tcpdumpでDHCPのリースを監視して、NASのDHCPでのIPアドレッシングを見つけて、SSHでアクセスします。

## インストール中のディスクパーティショニング
自分はこのタイミングで、他のパーティションとRAIDボリュームを構成しました。

```plantuml
database "md0（RAID論理ボリューム）" {
  folder "/" {
    [ext4]
  }
}
```


```plantuml
database "/dev/sda" {
  folder "RAID" {
    [RAID 物理ボリューム]
  }
  folder "swap" {
    [swapエリア]
  }
  folder "/boot（元sda1）" {
    [ext3, 内容はそのまま]
  }
}
```

```plantuml
database "/dev/sdb" {
  folder "RAID" {
    [RAID 物理ボリューム]
  }
  folder "/boot（元sdb1）" {
    [ext3, 内容はそのまま]
  }
}
```
以上が変更点になります。

# 今後
NextCloudをインストールする予定になります。実際に使ってみてどうなるのか楽しみです。
Visual Studio Codeでimport React from "react"が消えるときはこれが原因かも

## この記事の対象者
- Visual Studio Codeを使用している
- React16以下を使用している

## 結論

この拡張機能がインストールされている場合は削除する

https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next&ssr=false#overview

## なぜ import React from "react"が消えるのか

- [ナイトリービルド](https://www.sophia-it.com/content/%E3%83%8A%E3%82%A4%E3%83%88%E3%83%AA%E3%83%BC%E3%83%93%E3%83%AB%E3%83%89)であるtypescript@nextに変換する拡張機能を入れると自動的に削除してしまう
- React17からはimport React from "react"をする必要がなくなった
    - 参考:[import React from "react" はもう要らない](https://qiita.com/Yz_4230/items/ce70927d36f7a6cf619d)
CPUの高速化技術

復習回数1
# CPUの高速化
前回の記事で見た通り、1つの命令を実行する為には6つのステージを完了する必要がある。
今回はこのステージの実行方式を見ていく。
## 逐次制御方式
6つの段階を<font color = 'blue'>1命令ずつ順番に実行していく方式。</font>効率が悪い
## パイプライン方式
<font color = 'blue'>複数の命令を1ステージずつずらしながら並行処理する</font>
### 問題点
<b>分岐命令が現れると、処理の順序が乱れる</b>。これを<font color = 'blue'>パイプラインハザード</font>という
分岐命令に対処する為に、<b>実行確率の高い方を予測する<font color = 'blue'>分岐予測</font>や予測した分岐先の命令を開始して結果を保持し、分岐先が正しければ、利用する<font color = 'blue'>投機実行</font>などの技術がある。</b>
## スーパーパイプライン方式
<b>パイプライン方式を更に細分化したもの</b>

## スーパースカラ方式
<b>複数のパイプラインを使用して、同時に複数の命令を実行する</b>

## CISCとRISC
### CISC
<b>複雑な命令体系</b>で1回の命令で複雑な処理を行わせることができる。
主に、PCのCPUで採用
### RISC
<b>単純な命令体系</b>でパイプラインで効率よく処理できる

## マルチコアプロセッサ
<b>一つのCPU内に複数のコアを備えたもの</b>
それぞれのコアが同時に別々の処理を実行する。

## GPU
行列演算を用いて、<b>3Dの画像処理を高速に実行する画像処理装置</b>
数千個のコアを用いて、並列処理をする。人工知能の分野で広く普及している。

参考文献：イメージ＆クレバー方式でよくわかる 栢木先生の基本情報技術者教室
parrot-sphinx インストール，利用　その２

# parrot-sphinxインストールなどの備忘録
parrot製のドローンのシミュレーションが利用できる，parrot-sphinxのインストールや利用方法，またROSとの連携についてこれから随時記録していきたいと思っています．(parrot-sphinx ver2.5.1)
※parrot-sphinx インストール，利用　その１の続き

## firmwared サービスへの接続

    sudo systemctl start firmwared.service
この時にfirmwared.serviceがうまく起動できているか，確認したいときは以下の2つで確認します．

    cat /etc/group|grep firmwared
    >>> firmwared:x:135:<パソコンの名前>
うまくできていない時は，一番後ろにパソコンの名前が出力されていないと思います．

    id -nG
    >>> <パソコンの名前> adm cdrom sudo dip plugdev lpadmin lxd sambashare firmwared
firmwaredが一番後ろに出てきていれば成功です．
もし，この２つがうまくできていなかったらパソコンを再起動する必要があります．

次にシミュレーションを立ち上げる時のコマンドは以下になります．

    sphinx "/opt/parrot-sphinx/usr/share/sphinx/drones/anafi_ai.drone"::firmware="ftp://<login>:<pass>@ftp2.parrot.biz/versions/anafi2/pc/%23latest/images/anafi2-pc.ext2.zip"
これは，ftpサーバーに繋げるためwifi環境が必要になります．もし，オフラインでシミュレーションを行いたい場合は，ftpサーバーにあるanafi2-pc.ext.zipをダウンロードして自身のパソコンに入れておいて実行してください．

    sphinx "/opt/parrot-sphinx/usr/share/sphinx/drones/anafi_ai.drone"::firmware="/to/my/local/anafi2-pc.ext2.zip"

最後に次のコマンドを入力してください．

    parrot-ue4-empty

これを実行し，うまく動作していれば次のようなシミュレーション環境が立ち上がります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2581633/e9ba114e-374e-013e-3c3b-7f919a249536.png)

# さいごに
今回はここまでの紹介ですが，続きや細かい内容は少しずつ更新していきます．anafiを使ってROSで操作させたいので，次はROSでの接続についてまとめていけたらなと思います．

# 参考
https://developer.parrot.com/docs/sphinx/
SQLServer で　TEXT型(yyyyMMddHHmmss) を日付型に変換する

SQLServer　のデータをVB.net で select , Delete する際に

create_dtm,update_dtm　がテキスト型だったため、過去日付のデータを狙って削除する、ということにひと手間必要でした。

その覚書き。

```text

delete from 'テーブル名'"                              
where convert(DateTime,stuff(stuff(stuff(update_dtm, 9, 0, ' '), 12, 0, ':'),15, 0, ':'))

```

と、記述することによりテキスト型のdtmを日付型に変換。

仮に1年以上前の場合削除、といった条件をつける場合は、

```delete

delete from 'テーブル名'"                              
where convert(DateTime,stuff(stuff(stuff(update_dtm, 9, 0, ' '), 12, 0, ':'),15, 0, ':')) <= (select DATEADD(month,(-13),　GETDATE()))

```

というイメージになる。
Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

## bad
```
const Input = () => {
  return <input onInput={props.onInput} value={props.onInput} />
}
```

## good

```
const Input = (props) => {
  return <input onChange={props.onChange} value={props.onInput} />
}
```
Power Automate Desktop カスタムフォーム参照 [メモ]

Power Automate Desktopでカスタムフォームを作成。
設定したIDを参照する記述。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563939/b05909a2-a790-b935-5751-f04c8d603015.png)


カスタムフォームで生成された変数 CustomFormDataの場合
ID：TestInput

%CustomFormData.TestInput%

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563939/0801aaaa-9a14-e0c6-0fee-0609f8e9f557.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563939/24c58401-2526-0e0b-cae2-480d41b9b920.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563939/4102216f-4ae8-f3d8-0da0-818d54f3c48a.png)
JavaScriptでのオブジェクト比較をどうするか

## はじめに
オブジェクト同士の比較をするときに、「あ〜普通に等価演算子使えばいいじゃん」と思っていて思うような結果が返って来なかったことがありました。
オブジェクトの比較をどうするか、自分用メモです。


## 比較するオブジェクト
```ts 
interface BaseObject {
  id: number;
  name: string;
  language: string;
  isWoman: boolean | null;
}

const objectA: BaseObject = {
  id: 1,
  name: "hoge",
  language: "jpn",
  isWoman: true,
};

const objectB: BaseObject = {
  id: 1,
  name: "hoge",
  language: "jpn",
  isWoman: true,
};
```
BaseObjectをベースとした二つのオブジェクトobjectAとobjectBを作ります。
この段階で、「はいはい同じオブジェクトね」と考え`objectA === objectBがtrue`であるものとして実装を進めていました。笑

## なぜ同じじゃないのか
objectA === objectBがfalseになることはわかった、でもなんで？
見かけ上一緒じゃん！！と思っていた私。ではそもそもなぜ同じじゃないのか

objectAとobjectBは異なるアドレスを持っているから。
objectAはアメリカで作られているからアメリカの文化を持ってる。
逆にobjectBは日本で作られているから日本の文化を持っているイメージです。

なので、objectAとobjectBは表面上は一緒かもしれないけど、参照は違うって感じかな。と個人的なイメージですが。
[参考サイト](https://ja.javascript.info/object-copy)は図解されていてわかりやすいので、私のイメージ話は捨て去りこちらを参考にすると良いかもしれません。

## 比較演算子が使えない！じゃあどうやって比較する
### JSONを使う
 JSON.stringfy()で文字列にして比較する。
```ts
console.log(JSON.stringify(objectA) === JSON.stringify(objectB)); //true
```
ただ、JSON.stringfy()を使う場合はオブジェクトの中身の順序も同じでなければtrueにならない。
例えばobjectBのプロパティの順番を変えてみます。nameを一番上に、次にid がくるようなオブジェクトにします。

```ts
const objectA: BaseObject = {
  id: 1,
  name: "hoge",
  language: "jpn",
  isWoman: true,
};

const objectB: BaseObject = {
  name: "hoge",
  id: 1,
  language: "jpn",
  isWoman: true,
};
console.log(JSON.stringify(objectA) === JSON.stringify(objectB)); //false
```
> 配列以外のオブジェクトのプロパティでは、特定の順番で文字列化されることは保証されていません。文字列化された同じオブジェクトの中でプロパティの順番に依存しないようにしてください。[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)


同じ名前の同じ値のプロパティを持つオブジェクトであっても、異なる文字列に変換され得るということです。順番が異なっていたら、変換される文字列も異なります。


### lodashのisEqualを使う
JSON.stringfy()で順番考えるのは手間ですし、機能的なバグも起こりやすくなるかと思います。
そこでlodashのisEqualを使う方法があります。

lodashはJavaScriptで使用されるユーテリティライブラリです。
> ユーティリティライブラリとは「配列操作」「オブジェクト操作」「数値操作」といった様々な機能をまとめて提供しているライブラリのことです。

簡潔に言うとlodashには便利な関数がたくさんあるよってことです。
isEqualはオブジェクトのキー内の順序を考慮せずにオブジェクトが等いかどうかをチェックします。

```ts 
_.isEqual(objectA, objectB);
// => true
 
objectA === objectB;
// => false
```
記述が少なくて済みますし、もっと安全かなと思います。実務ではこの方法を採用しました
使い方や導入方法は公式に記載されています。[lodash](https://lodash.com/docs/4.17.15)
fnm(Fast Node Manager)のインストールとGit Bash for Windows連携

# 目的
* Git for Windows 付属の Git Bash を開発環境でのデフォルトターミナルとして活用する。
* 後々、Node.js のパッケージをグローバルにインストールした際、正しく動作する様、Windows 上で Git Bash を設定する。

# 手順
## 1. Git for Windows のインストール
Git for Windows を事前にインストールしておく。

https://qiita.com/ryo2020/items/335f07d169fb91480e0f


## 2. Chocolatey のインストール
Windows 環境の場合、fnmのインストールには　Chocolatey （[公式ページ](https://docs.chocolatey.org/en-us/choco/setup)） が必要。

https://qiita.com/ryo2020/items/6ada06cdcf655438d3f5

## 3. Chocolatey コマンドで fnm のインストール
Windows PowerShell で、以下コマンドの実行。
```powershell:Windows PowerShell
choco install fnm
```

## 4. Git for Windows 付属の GitBash セットアップ
Windows PowerShell、コマンドプロンプトのセットアップは公式を参照。他の情報は多分ググれば出てきます。

### 4.1. `.bashrc` を編集する

ユーザーのホームディレクトリ(`%HOMEPATH%`)にある`.bashrc`に、テキストエディタ等で以下を追記する。(Windows環境の場合 PATH を Linux 形式にする必要あり[^1]）

:::note info
`.barshrc`が無い場合、次のコマンドで、`%HOMEPATH%`にテキストファイルとして`.barshrc`として作成。

```bash:gitbash
$ cd ~
$ touch .bashrc
```
:::

`.barshrc`を次の様に変更する。

```diff_shell:.bashrc
+ # fnm setup
+ # @see https://github.com/Schniz/fnm#shell-setup
+ eval "$(fnm env --use-on-cd)"
+ 
+ # 環境変数の設定 LINUX書式のPATHに変換
+ export PATH=`cygpath -u $PATH`
```

[^1]:fnm でNotes.jsのバージョンを切り替えた場合、グローバルパッケージが期待値通りに動作しなくなる為。（[参考リンク](https://qiita.com/ryo2020/items/4cdc2953926a3bbf220f#%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E3%83%A1%E3%83%A2)）

### 4.2. Git Bash を起動
:::note info
`.bashrc`があり`.bash_profile`[^2]が無い場合、gitbashを起動した直後に`WARNING:`[^3]が出力されますが正常です。
[^2]:`.bashrc`があり`.bash_profile`が無い場合、`.bash_profile`は Git for Windows によって自動で生成されます。
[^3]:2回め以降の起動では表示されなくなります。

```shell:gitbash
WARNING: Found ~/.bashrc but no ~/.bash_profile, ~/.bash_login or ~/.profile.

This looks like an incorrect setup.
A ~/.bash_profile that loads ~/.bashrc will be created for you.
```
:::

### 4.3. fnm にPATHが通っているか確認
`fnm --version`コマンドを実行して、バージョンが表示されればOK。
```shell:gitbash
$ fnm --version
fnm 1.31.0
```

### 4.4 `.bash_profile`を編集する
winpty 経由で bash コマンドが実行される様に設定します。[^4]

```diff_shell:.bash_profile
# add winpty
# @see https://github.com/rprichard/winpty/
+ exec winpty bash

# generated by Git for Windows
test -f ~/.profile && . ~/.profile
test -f ~/.bashrc && . ~/.bashrc
```
[^4]:Linux 用にビルドされたモジュール等を Windows 環境で実行する際に`winpty ***.exe`の様に実行するらしいのですが、都度 prefix の様に入力する必要があるので、gitbash 自体をwinpty経由で起動してしまえということらしい。ではなぜ Git for Windows がデフォルトで使っていないのかというと、多分、おそらく、微妙にセキュリティリスクがあるのだと思われます。

了

# 参考

https://github.com/Schniz/fnm

https://qiita.com/ryo2020/items/335f07d169fb91480e0f

https://qiita.com/ryo2020/items/6ada06cdcf655438d3f5

https://mseeeen.msen.jp/what-does-winpty-command-do/#:~:text=winpty%20%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AF%E3%80%81%20Windows%20%E3%81%AE,%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%20%E3%81%A7%E3%81%99%E3%80%82
CPUの動作原理

復習回数1
## レジスタ
<b>CPUに内蔵されている高速な記憶装置のこと</b><br>レジスタの種類
<font color = 'blue'>命令レジスタ</font> - 実行する命令を格納する
<font color = 'blue'>命令アドレスレジスタ（プログラムカウンタ）</font> - 次に実行する命令のアドレスを格納する
<font color = 'blue'>指標レジスタ</font> - 基準となるアドレスを格納する。指標アドレス方式で使用
<font color = 'blue'>基底レジスタ</font> - 基準となるアドレスを格納する。基底アドレス方式で使用
<font color = 'blue'>アキュムレータ(累算器)</font> - 演算対象や演算結果を格納する。
<font color = 'blue'>汎用レジスタ</font> - 演算対象や演算結果を格納する。その他各種の目的に使用

## 命令語
プログラム言語で記述された命令は最終的に、1と0の機械語(<font color = 'blue'>命令語</font>)
に変換される。
機械語の命令語は<font color = 'blue'>命令部</font>と<font color = 'blue'>アドレス部(オペランド部)</font>で構成されている。
アドレス部が無いものや、アドレス部が複数あるものもある。

## 命令実行サイクル
一つの命令を実行する時の段階の説明<br>
➀<font color = 'blue'>命令の取り出し</font> - 命令アドレスレジスタ(プログラムカウンタ)を参照し、命令が格納されている主記憶上のアドレスを取得する。アドレスから命令を取り出し(<font color = 'blue'>命令フェッチ</font>)、命令レジスタに格納。この時、命令アドレスレジスタ(プログラムカウンタ)には次の命令のアドレスを格納。

➁<font color = 'blue'>命令の解読</font> - 命令レジスタの命令部は<font color = 'blue'>デコーダ(解読器)</font> で解読され、演算装置に指示を出す。

➂<font color = 'blue'>実行アドレス計算</font> - 命令レジスタのアドレス部は、アドレスレジスタに送られ、処理対象のデータが格納されているアドレス(<font color = 'blue'>実行アドレス</font>)を計算する(<font color = 'blue'>アドレス指定方式</font>)

➃<font color = 'blue'>オペランドの取り出し</font> - 処理対象のデータを取り出し、演算装置に送る。

➄<font color = 'blue'>命令の実行</font> - 演算装置で演算を実行する

➅<font color = 'blue'>演算結果の格納</font> - 演算結果を格納する

## アドレス指定方式(アドレス修飾)
<b>命令のアドレス部の値から処理対象のデータが格納されている実効アドレスを求める方式</b>

### <font color = 'blue'>即値アドレス指定方式
<b>命令のアドレス部にデータ自体を格納している</b>
### <font color = 'blue'>直接アドレス指定方式
<b>命令のアドレス部の値を、実行アドレスとする方式</b>
### <font color = 'blue'>間接アドレス方式
<b>命令のアドレス部の値が示す、主記憶上のアドレスに格納されている値を、実行アドレスとする方式</b>
### <font color = 'blue'>相対アドレス指定方式</font>
<b>命令のアドレス部の値と命令アドレスレジスタ(プログラムカウンタ)の値の和を、実効アドレスとする</b>
### <font color = 'blue'>指標アドレス指定方式（インデックスアドレス指定方式）</font>
<b>命令のアドレス部の値と指標レジスタの値の和を、実効アドレスとする</b>

### <font color = 'blue'>基底アドレス方式（ベースアドレス指定方式）</font>
<b>命令のアドレス部の値と基底レジスタの値の和を、実効アドレスとする</b>

参考文献：イメージ＆クレバー方式でよくわかる 栢木先生の基本情報技術者教室
Material Design IconsがMaterial Symbolsに進化していた

## この記事の概要

Google FontsのTwitterアカウントにて、何やら気になる告知がありました。
どうやらMaterial Designにおけるアイコングラフィーがアップデートされたようです。

https://twitter.com/googlefonts/status/1516934123700383744

変更点について簡単にまとめてみました。

追記：現実的な導入方法はこちらの記事でまとめています。

https://qiita.com/xrxoxcxox/items/f80d6f8bbdf4cf785c5f

## Material SymbolsとMaterial Design Iconsの違い

https://fonts.google.com/icons

既にGoogle Fontsのサイトはアップデートされています。
過去のページは見れませんが、Figmaのコミュニティファイルとプラグインを並べて見ると比較ができそうです。

### Material Symbols

Figmaのプラグインが公開されています。

https://www.figma.com/community/plugin/1088610476491668236/Material-Symbols

起動するとこのような見た目。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fcd4d72a-f225-f197-9586-ab4261079733.png)

変更できるプロパティは以下の5つです。

- Style
    - Outlined
    - Rounded
    - Sharp
- Weight
    - 100
    - 200
    - 300
    - 400
    - 500
    - 600
    - 700
- Fill
    - On
    - Off
- Grade
    - -25 (Dark theme)
    - 0 (Normal)
    - 200 (Emphasis)
- Optical size
    - 20dp
    - 24dp
    - 40dp
    - 48dp

### Material Design Icons

こちらはプラグインではなくファイルです。
ライブラリとして使う用途です。

https://www.figma.com/community/file/1014241558898418245/Material-Design-Icons

変更できるプロパティは1つのみです。

- Style
    - filled
    - outlined
    - rounded
    - sharp
    - two-tone

### Material Symbolsで新たに追加されたプロパティ

#### Weight

font-weightと同じようなイメージです。
数字が小さくなれば細く、大きくなれば太くなります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fc32fd8f-6fa6-2ce7-3ccd-7f5e753187f2.png)


#### Fill

Offなら線だけ、Onなら塗りあり、のイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8bc6a18c-81a3-ef2c-52dc-03fbd88e7035.png)

#### Grade

Weightに似ていますが、Weightよりももう少し小さな変更用のプロパティだと思われます。
ダークモードで使用すると少し見え方が強すぎるため、`-25`を用いてほんの少しだけサイズや線幅を控えめにする……というイメージです。

ダークモードのカラーパレットを作る際、ライトモードよりも少し彩度を低くするのが定石なのと似ている気がします。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fe991a8b-d18c-0572-ab9d-d5788b72e31a.png)

Figmaのプラグインでは`Dark theme`, `Normal`, `Emphasis`と記載されていますが、サイトでは`-25`, `0`, `200`と記載されています。
表記揺れでしょうか。


#### Optical size

同一のアイコンを単に拡大縮小をすると印象が変わってしまうため、それぞれのサイズにあわせた太さのバリエーションがあります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/b2cadaf1-4d0a-09df-469f-e8b1385fba98.png)

### Material Symbolsで削除されたプロパティ

styleのうち、`filled`と`two-tone`がなくなっていました。

`filled`に関しては`Fill`プロパティで別個に切り出されたので、名前が変わっただけと言えるでしょう。
`two-tone`は……あまり使われていなかったのでしょうか？
個人的には`two-tone`を使いたい場面がなかったため、なくなったことに問題は感じていません。
もし多用していた人はFillなどに置き換える必要がありそうです。

## まとめ

- 新しくMaterial Symbolsになったことで、細かい調整がしやすくなった
    - Weight, Grade, Optical size
- 基本的に進化した項目ばかりだけど、`two-tone`だけは削除されている

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox
[Wordpress] Simply Staticで静的ページ作成エラー

Wordpressサイトを静的HTMLに変換してくれる [simply static](https://ja.wordpress.org/plugins/simply-static/) を使ってみました。

すると・・・

<strong>Uncaught RuntimeException: Not valid HTML fragment!</strong>

というエラー。

# エラー

CSSの内容がズラーっと出力されました。

![ss-e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2614477/bfda50ca-e8f6-7015-3202-5b4d73e61b3b.jpeg)

おぅ・・・（;￣□￣)

# 環境

[Wordpress]
Ver. 5.9.3

[プラグイン]
[Simply Static](https://ja.wordpress.org/plugins/simply-static/)　：　Ver. 2.1.5.7

[テーマ]
[SWELL](https://swell-theme.com/)　：　Ver. 2.6.1.3

# 今回出たエラー

アクティビティ・ログではPHPやサーバーエラーなどが出力されますが、今回はCSSの内容が入っているので、どうもCSSの記述に問題がある様です。

simply static は [simple html dom](https://simplehtmldom.sourceforge.io/docs/1.9/index.html) を使って HTML を解析している様で、無効なHTMLがあったり、タイポなどあったらエラーとなる様ですね。

# 調査

- とりあえず、エラーのあったファイルを確認。

```
~/wp-content/plugins/simply-static/vendor/voku/simple_html_dom/src/voku/helper/SimpleHtmlDom.php on line 199
```

- 199行目〜

```php
    190     protected function replaceChildWithString(string $string, bool $putBrokenReplacedBack = true): SimpleHtmlDomInterface
    191     {
    192         if (!empty($string)) {
    193             $newDocument = new HtmlDomParser($string);
    194
    195             $tmpDomString = $this->normalizeStringForComparison($newDocument);
    196             $tmpStr = $this->normalizeStringForComparison($string);
    197
    198             if ($tmpDomString !== $tmpStr) {
    199                 throw new \RuntimeException(
    200                     'Not valid HTML fragment!' . "\n" .
    201                     $tmpDomString . "\n" .
    202                     $tmpStr
    203                 );
    204             }
    205         }
```

`$tmpDomString` と `$tmpStr` の不一致で問題が発生してる。

格納された値を見てみないとね〜、という事で早速、確認。

<strong><font color=RED>とんでもない量のコードが改行もなく1行で入ってる・・・</font></strong>

`diff` コマンドでチェックしても1行だから全体が表示されちゃうし、1行のコードの中で差分があるところだけをピックアップしてくれるオプションとかないの？あったら教えて　＞＜；

というわけでターミナルを分割させて、それぞれの値を地味に比較してみましたよ、、っと。

地道な努力も実って原因が分かりました。

# 原因

```
$newDocument = new HtmlDomParser($string);
```

ここで、CSSの中で使われていたSVGの `path` の閉じタグが補完されてました。

元々、HTMLに不備がないか、というチェックを行う為、オリジナルのコードと補完されたコードを作成して、それらを比較してるっぽい。んじゃないかなと思います。

本来、SVGでは`path` の閉じタグは省略しても問題ないのですが、simple hthml domでは閉じタグが無いとダメ！って判断したみたいです。

# 対策

結果的にテーマ Swell がCSSをインラインで読み込んでいる事が原因じゃないか、と仮説を立てました。

いろいろ探してるうちに、<strong>WP管理画面 > SWEEL管理画面</strong>で以下の設定を見つけました。

![スクリーンショット 2022-04-20 20.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2614477/a4d7581b-da0d-18f2-d072-bcab25ecd275.png)

「SWELLのCSSをインラインで読み込む」にチェックが入ってますね。

このチェック外せばいけるんじゃ・・・、という事で、

<strong>「SWELLのCSSをインラインで読み込む」のチェックを外したら解決しました！</strong>



今回は、simply static と Swellテーマ(と設定)の組み合わせでエラー出ました、というお話でした。

# まとめ

かなり特殊なケースなので、解決まで苦労しました。(^▽^;)
大量の1行データで差分を見つける方法も模索しないとな、、、と課題。

これを解決する為に、色々調べましたが、特殊な組み合わせゆえにあまり情報がなかったので、どこかの誰かが同じ様なエラーで悩んでいたら参考にして頂けたら幸いです。
【OBGノウハウ】動画でわかるイラストの描き方

みてみて！
FireAlpacaを使ってイラストを描きました！:writing_hand:
[▼ツイートはこちら▼](https://twitter.com/OBG_koho/status/1508246857977593860)
![オブチャン反応ツイート用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2105577/cf1cd0d6-c887-3837-4ef6-2ab0ce0646a3.png)
OBGの広報担当でもあるオブちゃんがホワイトデーのお返しをいただく（という設定で）、その時の反応 __「素直」、「ツンデレ」、「シャイ」__ の３つをご紹介！
みなさまのお好みはどのタイプでしょうか？？:relaxed:
## 「どうやって描いてるの？」

パソコンで描いてます！
今回使ったお絵描きソフトは「[FireAlpaca]」というフリーペイントツールです！
Mac、Windows両方対応していますのでオススメです！
FireAlpacaはフリーソフトですので、「デジジタルイラストに興味はあるけどIllustratorはちょっとハードル高いな……」という方の参考にもなれば嬉しいです。

あとはペンタブや液タブがあれば絵を描く環境はバッチリ！:v:
## メイキング動画もあるよ
[▼動画はこちら▼](https://www.youtube.com/watch?v=7a07PQiw9UA)
![スクリーンショット 2022-03-31 10.07.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2105577/c7ad75d0-87fc-f8e5-da6b-bb5c47250dfe.png)
どんな感じで描いているのか、それぞれのポイントなど字幕で解説もついております！
タイムスタンプがついているので見たい箇所に一発で飛べますよ！

それでは楽しいお絵描きライフを！:raised_hand:

[FireAlpaca]:https://firealpaca.com/ja/
ローカルブランチとリモートブランチが紐づいているか確認する(git branch -vv)

## 前提条件
- GitHubのアカウントを作成済み
- GitHubにリポジトリ（プロジェクト）が存在する
- SSH認証済み:[参考](https://qiita.com/kitutune/items/dd8e145b064a88c3f6c5)
- プロジェクト（リポジトリ）を[クローン](https://qiita.com/kitutune/items/dff6f2f14b9fb1fad187)ないし作成したディレクトリにいる（中に.gitディレクトリがある）

今回使ったコマンド
- [cd:ディレクトリ移動コマンド](https://wa3.i-3-i.info/word11159.html)
- [pwd：現在いるディレクトリのパス](https://wa3.i-3-i.info/word11161.html)


##  現在地確認(無視していい)
<img width="643" alt="スクリーンショット 2022-04-21 11 42 00" src="https://user-images.githubusercontent.com/79749395/164361067-c6d5b7f1-5166-4ca2-b95f-d2e0a2e76dd3.png">

## 1. branch オプション -vvを使う　
ローカルブランチとリモートブランチが紐づいているかは
~~~
git branch -vv
~~~
でわかる
<img width="646" alt="スクリーンショット 2022-04-21 11 44 12" src="https://user-images.githubusercontent.com/79749395/164361297-4736c2ef-3bbf-47a5-a01a-2e8e6445f426.png">
↑の説明をすると
現在ローカルブランチとして
- main
- sample1
  
という２つのブランチが存在している
mainはリモートブランチのorigin/mainと紐づいていることがわかり

sample1は何にも紐づいていないことがわかる

以上です

## 余談　「サンプルページ追加」と「適当を更新しました」は何？
それぞれのローカルブランチで最後にコミットしたメッセージが表示される
コミットメッセージとは：作業した内容を１言でまとめたもの
[コミットとは？](https://wa3.i-3-i.info/search.html?q=%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88&ln=)
いろいろな自動化についての思い

はい、どうもパニック障害怠惰エンジニアです。
今回は技術的なこと、というよりは自分の考え方という感じの雑記になります。
（マークダウン式の書き方の練習もしたいので）
# もっと楽がしたい
自動化をやりたいエンジニアは、たぶんこれが第一に来ると思います。
自分はそうでした。
自分の場合は特に単体テストですね、テストしてスクショして、エクセルに張り付ける。
本当に面倒だと思いました。
「もうワンクリックで全部やってほしいわ」
何度思ったことか、そしてタスクが重くなってくる（多重）ほどに目視確認のミス、必要パラメータ情報が含まれていないなどの見落としが多くなってくることに罪悪感が募る一方でした。
## 万能な自動化は存在しない
いろいろ調べて、やはりこれが一番ショックではありましたね。
まぁ、当たり前といわれるとそうなんですけどね。
しかし、「問題（ケース）に合わせて自動化作成することはできる」
問題は工数や時間の確保。

## アジャイル開発でのテスト自動化は、ほぼ無理かも
正直、納期詰め詰め期日3日、実装して単体テストしてー、での自動化は、ほとんど不可能に近い（凄腕エンジニアとかはできそう）、次のタスクがーとか、よほどの余裕がないと無理ー。
### テスト自動化の必要性
しかし、なぜテストの自動化が必要なのかについて考えてみた。
それはデグレのABテスト時、実装者以外テスト方法がわからないということがある。
つまり継続性だと思う。
機能実装者じゃないとわからんという単体テスト表の手順が多い、多い。
実装担当者が、もういませんなど言われた日には、どうしろと。。。
個人的に実装者じゃなきゃ理解できない工数を削った単体テスト表の手順書を作成する工数をテストコード記入する工数にあてたほうが、長期間の継続性でみるといいと思えるのだが、まぁ自分が口出せることじゃないので黙っておくしかない。
ということがあるので、できればテストは自動化しておくと動きがスクショと文言ではなく視覚的に動作確認できるので便利だよ。
あとABテスト時にスクショの差を比較してくれる機能もあったりと便利になってきてる。
納期にケツが決まっていて、とりあえず納品できればいいのはわかるのだが、もし長期の保守運用も担当するのであれば運用面では必要になってくるし、やらないとエンジニアの入れ替わりで簡単な機能追加後の単体テストやらせてもソース調べますなどの無駄な工数が積みあがること必至。

## 万能に見えて実は難しいGUI設定自動化
自動化で一番簡単ではあるけど、思わぬミスがでる。
それがGUIでの座標をしていした自動化。
環境によってブラウザの大きさ、読み込み速度などの違いによるタイミングのミスが本当に難しい。
エラーハンドリングができれば回避できそうだが、どうやるんだろうなど。
### 画像解析からの処理読み込み後のタイミング
機械学習などを使った画像解析からの対象へのタイミング修正ができるようになってきてはいるようだけれど、ある程度マシンスペックが必要な気がする。（学習中なのでまだわかってない）

## 座標よりも要素指定の自動化
Cypressを使い始めて思うのは、要素指定の自動化は画面の読み込みのタイミングくらいが問題。
あとは慣れかなーという感じに今は思える。
ソース自体も、そこまで複雑でなければすぐできる。
まぁテスト自動化ツールなので目的とは違うけれども、使えるのであれば使うが心情です。


# 自動化の勉強段階なので
執筆はつづくし、修正もします。
Excelでフローチャート書くの辞めてmermaid.jsで書きます。

# エクセルで図を書くのが嫌い
業務の整理や頭の中の整理目的でフローチャートとかをExcelで作ってたんですが、
もっと脳死して図を作成できるmermaid.jsを使ってみました。

# mermaidって
mermaidはマークダウンで図を書けるようにしてくれるjsのライブラリです。

```markdown
  ```mermaid
   flowchart TD;
   hoge-->huga;
　```
```

```mermaid
flowchart TD;
hoge-->huga;
```

https://qiita.com/caesar_cat/items/e8a116a585863633d15a

https://qiita.com/uzuki_aoba/items/a01f8b0b52ced69c8092

VsCodeなどのエディタ上でも使用可能、下記のリンク内の記述は古いので、書き方は公式を見ましょう。あくまで紹介です。

[使ってみよう！VSCode+mermaid](https://www.agent-grow.com/self20percent/2020/03/05/%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%81vscodemermaid/)

<!-- 各チャプター -->
<a id="#使ってみて感じたメリット"></a>
# 使ってみて感じたメリット
- 処理の追加が楽
- 書く消費カロリーが少ない
- 脳死で書ける
- レイアウト調整がいらない
- GitLabで(ちゃんと)管理すれば仕様変更の差分も分かる
- 誰が作っても同じようになるから見やすいから統一性がある

<a id="#目指せMarkDownで仕様書を管理"></a>
# 目指せMarkDownで仕様書を管理
https://techceed-inc.com/engineer_blog/3286/

弊社は成果物(ソースコード)をGitLabで管理していますが
仕様に関しての資料は割となーなーなです。
システム概要の資料をmermaidで書いてリポジトリに入れておけば、プロジェクトにアサインした人や引き継いだ人が把握しやすいかと思います。

クラス図やシーケンス図など色んな図が作れるので、機能ごとに何かしらの図を残しておくのも良いかなと思います。

下に人が付いた時とかのレビューも楽になる気もするのでMarkDownで資料を残す文化を築いていきたいですね。

# 余談
``A5:SQL Mk-2``というDBツールもテーブル定義書をMarkDownで吐けるようになったので、何でもMarkDownの流行りがきつつあるのでしょうか。
テーブル定義書もMarkDownで吐いてプロジェクト（リポジトリ）にぶち込んでおこうと思います。
誰かが作った成果物を閲覧する際も、そういった資料(MarkDown形式のテーブル定義書,mermaidで書いた仕様)があれば理解の速度も上がると思うので効率が良さそうです。
[React Native] 持病の母のためにトイレのログをとれるごくシンプルなアプリを作った

### きっかけ
利尿剤を服用しているのでトイレの記録と利尿剤を服用した時間の記録が取れるアプリが欲しいと言われた
既に似たようなアプリがあったが、利尿剤を服用した記録も欲しい母にとっては編集が必須だった
だったら、母専用のログアプリを作ろうと思った

### 私のスペック
・仕事ではPHP（FuelPHP）を担当
・JSは既存の画面をもとに少しいじる程度しか使わない（JQuery）
・MDNのTodoアプリ（React）を作るチュートリアルをTypeScriptに変換しながら作った程度
そんなもんでフロントに関してはど素人なので勉強がてら作ってみた

### 使用したもの
・React Native
・NativeBase
・TypeScript
・Expo（実機確認）

### ボタンを押せば押した時間とテキストを表示させるとってもシンプルなアプリ

実際の画面(Web)
もちろん、テキストの編集もできる
![logscreen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442028/7112f6d3-5db3-eb9d-9687-d7fa555fe955.png)

### 構成
https://github.com/monji05/log-app/blob/master/README.md


### 作ってみて
Expoを使ってiphoneから確認できる手軽さはハマる
新しいものに触れるのはいろんな意味で楽しい
Macbookを買ったらリリースしたい

作るにあたって参考にしたもの
公式: https://reactnative.dev/
動画: [How to build a smoothly animated ToDo app with React Native, Expo, Reanimated, NativeBase, and Moti](https://www.youtube.com/watch?v=k2h7usLLBhY&t=4748s)
MySQL暗号化メモ

# MySQL暗号化方式の取得クエリ
`show variables like 'block%';`

取得結果
<img width="380" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116515/36dc7aa6-db94-faf1-12f0-46783f3cc59c.png">

# 暗号化モード設定について
block_encryption_modeはグローバルとセッション変数スコープが存在する。
DBクライアントでOK、アプリケーション側でNGの場合、セッションの方のみ設定されている。
アプリケーション上でも対応させたい場合、
グローバルのblock_encryption_mode変数への設定が必要になる。

### 暗号化モード設定クエリ(セッション)
`SET block_encryption_mode = 'aes-128-ecb';`

結果
`Query 1 OK: 0 rows affected`

### 暗号化モード設定クエリ(グローバル)
`SET @@GLOBAL.block_encryption_mode = 'aes-128-ecb';`

結果
`Query 1 OK: 0 rows affected`


# MySQL block_encryption_mode　設定について
https://dev.mysql.com/doc/refman/5.6/ja/server-system-variables.html#sysvar_block_encryption_mode

# 暗号化方式 aes-256-cbc について
ivの長さは16文字　16進数に変換後、ivHexにすると32byteになる。

# ivをそれぞれのパラメータごとに設定する理由
https://note.com/ockeghem/n/n221476285007
Laravel Livewire model:clickの前にJS comfirmしたい

Laravel Livewireでwire:clickを使うと、clickイベントが起きると即座にfunctionが実行されてしまう
ので、onclickでJSを呼び出してemitでfunctionを呼び出す・・ってやらなきゃいけないかと思ってたけど
ぐぐったら以下の記事を発見

https://davidhallin.com/blog/confirming-actions-with-laravel-livewire/

どうもonclickの後にwire:clickが呼び出される順番になっているようですね。
で、event.stopImmediatePropagation()と組み合わせることで、それ以上のイベントを抑制することが
できるということですごく便利です。

```
<button onclick="confirm('削除を実行しますか?') || event.stopImmediatePropagation()" 
		wire:click="delete_object">削除!</button>
```
TopCoder Mararhon Match でビジュアライザを動かす

# 0．はじめに
TopCoderのMarathon Matchに参加した際に、配布されているビジュアライザを使用するのにとても苦労しました。僕のように自力でビジュアライザを組めない方にとっては、かなりのストレスになると思うので、ビジュアライザをダウンロードしてから使用するまでの流れをここで説明します。
下記の記事の内容をかなり参考にしたので、先に紹介させていただきます。
[Topcoder Marathon Matchの始め方（最新版）](https://qiita.com/phocom/items/da0f8123f7a8d5201cbf)
## 想定環境
・WSL
・vscode
・VcXsrv

下の記事を見ながら競プロをやるための環境を構築しました。
[【VScode＋WSLで始める】競プロ用C++デバッグ環境構築](https://qiita.com/2019Shun/items/5ab290a4117a00e373b6)

また、VcXsrvをダウンロードしないとビジュアライザが動きません。「これが何なのか」は僕もちょっとよくわかってないですが、とにかくないと動きません。下の記事を見ながらぽちぽちダウンロードしました。
[WSL上にXサーバをインストールしてGUIを実現する（VcXsrv編）](https://atmarkit.itmedia.co.jp/ait/articles/1812/06/news040.html)

**ビジュアライザを動かす前に必ずVcXsrvが起動されているかを確認して下さい。** 
起動されていない場合は「スタートメニュー」→「XLaunchと検索」→「XLaunchを開く」から起動できます。

# 1．ビジュアライザをダウンロード
これは簡単です。赤線で囲っている2つをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570491/1ff624f6-a4b6-2547-3d11-c15abf9925ea.png)

zipフォルダーは展開して、「tester.jar」と「自分で作ったプログラムの実行ファイル」と同じフォルダー内にまとめておいておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570491/b5eb8d2e-c840-9c99-39b2-71e489508391.png)

# 2．ビジュアライザを実行
tester.jarのあるフォルダーまで移動して
```
$ export DISPLAY=:0.0
$ java -jar tester.jar -exec "＜実行コマンド＞" -seed ＜シード値＞
```
を順に実行します。
export(以下略)のほうは最初の1回だけで大丈夫だと思いますが、エラーがでるようでしたら毎回打ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570491/93ec7a3f-9611-ff5b-d62c-1bdebed0cc26.png)

これで無事に実行できた方はお疲れさまでした。

# 3．自分が直面したエラー1(何かが足りない)
「java -jar(以下略)」を実行した際に、「○○がないよ！でも以下のコマンドを打てばインストールできるよ！」みたいなエラーメッセージが英文で表示されました(スクショ取り忘れました…すみません)。
**エラーメッセージに書いてあるコマンド(3つくらい)を順番に実行すると無事解決します。**

# 4．自分が直面したエラー2(java関係？)
「java -jar(以下略)」を実行した際に、以下のようなエラーメッセージが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570491/61d91fd0-6e99-5545-8896-cd4bac896954.png)
これがほんとによくわからなくて大変でした。結論から言うと、以下のコマンドを打つと解決します。
```
$ sudo sed -i -e '/^assistive_technologies=/s/^/#/' /etc/java-*-openjdk/accessibility.properties
```
wslの中にある/etc/java-*-openjdk/accessibility.propertiesというファイルを編集しているっぽいです(一番最後の文をコメントアウトしている？)。
以下のサイトを参考にしました。
[Assistive technology not found AWTError](https://askubuntu.com/questions/695560/assistive-technology-not-found-awterror)

# おわりに
僕自身PCに強いわけではないので、表現や内容に誤りがある可能性があります。何か気づいたことがあれば、コメント等で気軽にお知らせ頂けると嬉しいです。
## 参考記事

[Topcoder Marathon Matchの始め方（最新版）](https://qiita.com/phocom/items/da0f8123f7a8d5201cbf)
[【VScode＋WSLで始める】競プロ用C++デバッグ環境構築](https://qiita.com/2019Shun/items/5ab290a4117a00e373b6)
[WSL上にXサーバをインストールしてGUIを実現する（VcXsrv編）](https://atmarkit.itmedia.co.jp/ait/articles/1812/06/news040.html)
[Assistive technology not found AWTError](https://askubuntu.com/questions/695560/assistive-technology-not-found-awterror)
メールチェック面倒だから自動化しちゃえ

はい、どうもパニック障害怠惰エンジニアです。
ということで、作成途中なのですが今回はCypressとTypeScriptを使って、なんちゃってメールチェック自動化していきます。
いやー、いちいちログインを手動でして、アドレスとか目視確認したくないですわ。
でも、ほっておくとフォルダに貯まって後で仕分け面倒、でも自動振り分けするまでもないアドレスからだし・・・。
というのが面倒だった。

# 起動用バッチ（タスクスケジューラーにでも登録してね）
```bat:EmailCheck.bat
@echo off
chcp 65001

echo "メールの最新状態をチェックします"
REM ほかの関係のないメールのみの場合は削除します、対象のアドレスが付いたメールがある場合は削除せずに残します

REM cypress起動してGUIテストの間のみ表示
cd "ファイルパス"
npx cypress run --headed --spec "テストファイルパス"

msg %username% /W "メールボックス内のチェック作業終了しました。"
pause
```
# メールチェック用のロジック
```ts:mailChecker.ts
describe("mail checker", () => {
  //定数呼び出し
  before(function () {
    cy.fixture('test').then(function (testdata) {
        this.testdata = testdata
    })
  })
  // テストケース：メール件名で検索
  it("mail check", function() {
    // ログイン処理
    cy.visit(this.testdata.url,'utf8');
    cy.get('email要素').type(this.testdata.mail,'utf8');
    cy.get("password要素").type(this.testdata.pass,'utf8');
    cy.get("input").contains("ログインする").click();
    //ログ出力
    cy.log('Login successful')
    //遷移後読み込み待機
    cy.wait(8000);
    //メールの件名を確認
    cy.get("メールの受信欄要素").then(($p) => {
    //var よりもletを使おう
      let name , time = "";
      // 対象の件名にあった場合 true false返る
      cy.wait(8000);
      if ($p.text().includes("メールアドレス名（部分一致）") === true) {
        cy.log('True')
        // 部分的に一致するが、削除してもいいアドレス用の処理（例えば会社の全体メールを指定）
        if($p.text().includes("メールアドレス名（削除してもいい文字列があるアドレス名）") === true){
          cy.log('削除していいよ')
          // メール削除
          cy.get('すべてのメール選択にチェック要素').click({ multiple: true })
          cy.get('削除ボタン要素').click()
          // 処理終了するために返す
          return
        }
        // 通常処理（確認したい人のメールアドレス）
        cy.log('確認したいメールあるよ')
        cy.get('要素').should(($div) => {
          time = $div.text()
          //差出人の名前と時間をローカルフォルダのjsonに記載しておく
        cy.writeFile("ローカルパス/jsonファイル",  { name:name,time:time }, 'utf8')
         })
        
      } else if($p.text().includes("アドレス") === false) {
        cy.log('ないよ')
        // 対象のメールがない場合
        // メール削除
        cy.get('すべてのメール選択にチェック要素').click({ multiple: true })
        cy.get('削除ボタン要素').click()

      } else {
        // 何か後で作るかも
      }
      return
    });
  });
});

```
Atcoder初心者学習③　数列要素の組み合わせによる差の最小化　【競プロ典型90問　014】

# 問題
https://atcoder.jp/contests/typical90/tasks/typical90_n

# 数列要素の組み合わせによる差の最小化
本問題の場合、入力を受けた長さが等しく$N$である2数列のそれぞれの要素の差を、重複なしでN個とってきたときの差の合計値の最小化をいかにして求めるか、について以下の原理を導くことが難しい。

**原理**
長さが等しく$N$である2数列のそれぞれの要素の差を重複なしでN個とってきたときの差の合計値minは
2数列をそれぞれソートしたものを
$[x_1, x_2, \dots, x_N] 　　
 s.t. x_{i-1}<=x_i(i=1,...,N)$
$[y_1, y_2, \dots, y_N]    　　  
 s.t. y_{i-1}<=y_i(i=1,...,N)$
とすれば
$min = |x_1-y_1|+|x_2-y_2|+ \cdots + |x_N-y_N|$
が成り立つ。

**簡易的な証明**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392111/e557608f-5849-2d88-edad-0dfb4949ae53.png)

仮に上のような大小関係の時、$|x_1-y_1|+|x_2-y_2| < |x_2-y_1|+|x_1-y_2|$です。

他の考えうる大小関係すべてにおいて考えれば2点間においてこの$|x_1-y_1|+|x_2-y_2| < |x_2-y_1|+|x_1-y_2|$が成り立ちます。

これを拡張してnについても成り立つことを確認すれば数学的帰納法より原理が証明されます。
独学とプログラミングスクールの違い

少し、自分がやってきたことについて、独学とプログラミングスクールの違いについて書きたいと思います。
# 独学について
動画サイト（プロゲートなど）を使って勉強をしていました。
## 勉強できること
プログラミングの基礎（コードの書き方・文法など）。書き方や文法は分かるようになりますが、自分でコードを書くよりコピーする形になります。
## 出来るようにならないこと
オリジナルコードの記述。ポートフォリオ作成のためのサービス作成など。
## 違うサービスもある
UdemyやTechpitなどの一部サービスは基礎というよりはサービスを作りながらプログラミングを勉強するので、どっちかと言うとプログラミングスクール寄りになります。

# プログラミングスクールについて
TechboostのスクールでPHPを受講しています。
## 勉強できること
実戦向け（基礎ではなく、就転職や副業・フリーランス）に焦点を向けたカリキュラムでサービスを作る。
## 出来るようにならないこと
特にないと思います。
## その他の違い
メンター（講師の人）に質問できる。理解度のすり合わせが出来る。※UdemyやTechpitも質問は出来ます。

# その他
UdemyやTechpitはサービスを作ることは出来ますが、主にコピーです。オリジナルサービスを作る行程はありません。講座の内容を生かして、自分でサービスを作っていかないといけませんし、その点の質問も出来ません。

# 結論
自分でオリジナルのサービスを作るスキルを身に付けたいのなら、プログラミングスクールに通うのが一番でしょう。それが出来れば初心者向けの学習サービスを卒業し、MENTAや月額制のプログラミングスクールを受講し、スキルの上乗せをしたほうがいいでしょうね。

以上が二つの違いです。
C#のGenericMathを使ってみた（Preview版）

# はじめに

いままでのC#のジェネリックでは、オペレーター（+や-）を使用できないため、int型float型など型ごとに関数を実装する必要がありましたが、INumberを使うと1つの関数を実装するだけで済ます。
個人的になんでこういうこと出来ないのか昔から疑問でしたが、ついに実装されるときが来て嬉しいです。
ただ、2022/04/26時点でまだ正式な機能ではなくプレビュー機能としての提供となります。

# 環境設定

## Visual Studio 2022を起動しプロジェクトの作成

* プロジェクト名：ココでは「INumberTest」とします。
* プロジェクトテンプレート：コンソール無印(.NET Frameworkじゃない方)
* フレームワーク：.NET 6.0

## プレビュー機能を有効化

INumberTest.csprojをテキストエディタで編集し、PropertyGroupタグ内に以下を追記する。

    <EnablePreviewFeatures>true</EnablePreviewFeatures>
    <LangVersion>preview</LangVersion>

追記後の例

    <PropertyGroup>
      <EnablePreviewFeatures>true</EnablePreviewFeatures>
      <LangVersion>preview</LangVersion>
    
      <OutputType>Exe</OutputType>
      <TargetFramework>net6.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
    </PropertyGroup>

## System.Runtime.Experimentalをインストール

NuGetからインストールします。

# コード記述

## 合計を計算する関数の例

~~~cs:Program.cs
var values = new double[5] { 1, 2, 3, 4, 5 };
var sum = Sum(values);
Console.WriteLine(sum);

static T Sum<T>(IEnumerable<T> values) where T : INumber<T>
{
    T sum = T.Zero;
    foreach (var value in values)
    {
        sum += value;
    }
    return sum;
}
~~~

出力結果

~~~
15
~~~

## マチンの公式の例

~~~cs:Program.cs

MachinsFormulaTest();

/// <summary>
/// マチンの公式
/// </summary>
/// <param name="count">計算回数。1未満を設定すると0を返す。</param>
/// <returns>PI/4(円周率の4分の1)</returns>
static T MachinsFormula<T>(int count) where T : INumber<T>
{
    var _4 = T.Create(4);
    var _5 = T.Create(5);
    var _239 = T.Create(239);

    T sum = T.Zero;
    for (int k = 1; k <= count; k++)
    {
        int odd = (2 * k - 1);// 奇数(int型)
        var _odd = T.Create(odd);// 奇数(T型)
        sum +=
            _4 *
            (Pow(-T.One, k + 1) / _odd) *
            Pow(T.One / _5, odd) +
            (Pow(-T.One, k) / _odd) *
            Pow(T.One / _239, odd);
    }
    return sum;
}

static void MachinsFormulaTest()
{
    Console.WriteLine($"MachinsFormulaTest()");
    Console.WriteLine($"float");
    {
        var pi = MachinsFormula<float>(17) * 4;
        Console.WriteLine($"{pi}");
    }
    Console.WriteLine($"double");
    {
        var pi = MachinsFormula<double>(17) * 4;
        Console.WriteLine($"{pi}");
    }
    Console.WriteLine($"decimal");
    {
        var pi = MachinsFormula<decimal>(20) * 4;
        Console.WriteLine($"{pi}");
    }
}
~~~
出力結果
~~~
MachinsFormulaTest()
float
3.1415925
double
3.1415926535897944
decimal
3.1415926535897932384626433820
~~~

# Create系関数の動作


| 関数 | 説明 |
|------|------------|
| CreateChecked    | 値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲から外れる値に対しては，オーバーフロー例外を投げます． |
| CreateSaturating |  値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲の外側にあるすべての値を飽和させます。 |
| CreateTruncating | 値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲から外れる値は切り捨てられます。 | 


## 参考にしたサイト

https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-11#static-abstract-members-in-interfaces

https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/
SalesforceプラットフォームAPIバージョン7.0から20.0の廃止

現在使っているバージョンの確認が先かな。

技術的には、Rest、SOAP、およびバルクのみが廃止されます。 

[SalesforceプラットフォームAPIバージョン7.0から20.0の廃止](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GeKAnSAN)
Superbadge Help 記事が表示されないエラーが頻発しているようです

2022年4月20日（日本時間）より投稿が散見されますね。何でだろう？


[Where can I find the link to Security Specialist: Trailhead Challenge Help to complete the quiz?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GfDaTSAV)

[Superbadge Help Article Missing](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GgzH7SAJ)