OmniAICreator/Qiita-1.07M huggingface dataset:
AZ-104 合格体験記

先日、Microsoft認定試験AZ-104:Microsoft Azure Administratorに合格しました。
これからAZ-104の受験を考えている方に試験対策など参考にしていただければと思います。

## AZ-104
AZ-104はMicrosoft社の認定資格試験で、Microsoft Azureの管理者・技術者をめざす方向けの資格です。
難易度はアソシエイト（中級）でAzureの実装、管理、監視について幅広い知識が求められます。

以下、公式ドキュメントの抜粋です。
> この試験の受験者には、組織の Microsoft Azure 環境の実装、管理、監視に関する専門知識が必要です。
このロールの責任には、クラウド環境での ID、ガバナンス、ストレージ、コンピューティング、および仮想ネットワークの実装、管理、および監視、さらに必要に応じてリソースのプロビジョニング、サイズ、監視、調整が含まれます。

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

## 試験対策
私が行った試験対策は大きく3点です。
1．教科書で学習
2．模擬問題を解く
3．ハンズオン

以下詳細です。

#### 1.教科書で学習
まず導入としてサービスの概要などを掴むきっかけとして以下の本を使用しました。

https://www.amazon.co.jp/dp/B09HT3HX8W?tag=note0e2a-22&linkCode=ogi&th=1&psc=1

この教科書にはサービスを使用する際の実際の手順の記載があるのですが、そこは特に注意して読みました。
実際にテストには「このサービスを使用する際の手順を順番に選択しろ。」といったような問題もいくつか出ました。

#### 2.模擬問題を解く
つぎにオンライン学習プラットフォームであるUdemyを用いて模擬問題を解きました。
AZ-104の模擬問題集はいくつかありましたが私は下記のものを使用しました。

https://www.udemy.com/course/az-104-microsoft-azure-administrator4260/

この問題集は模擬問題が4回分計260問あります。
テストを終えたうえでの振り返りとしてはこの問題集さえ完璧に理解していれば資格合格は出来るかなと思います。

#### 3.ハンズオン
最後にハンズオンです。
今回資格取得にあたり初めてハンズオンをしました。
実際にサービスに触れ手を動かすことで理解が深まり、何より楽しかったです。

模擬問題や教科書での勉強は正直楽しくありません。
したがって、資格勉強が進まない、、、という方にはお勧めです！

## 受験方法
AZ-104をピアソンVUEにて受験しました。

ピアソンVUEとはイギリスのメディア企業ピアソンによって所有されているコンピューターを使用したテスト (Computer Based Testing, CBT) を提供するサービス会社です。
こちらのサービスを利用することで自宅での資格受験が可能となります。

ピアソンVUEで受験する際の注意点を以下にまとめます。

__・ 部屋をきれいにする。__
試験チェックインの際に試験を受ける場所の前後左右の写真を送らなければなりません。
したがって片づけるのは机の上だけでなく手の届く範囲全てです。
私は机の上しか片づけておらず注意されました。。。

__・試験以外のサービスを停止させる。__
試験を行うには不正防止のため試験以外のサービスを停止させる必要があります。
試験以外のウィンドウを閉じるのは当たり前ですが、使用するパソコンによってはバックグラウンドで動くサービスによって試験を開始できない可能性があります。
私の場合はircamsrv.exeというサービスがバックグラウンドで動いていて試験が開始できませんでした。


## 結果
835点で合格しました。（1000点満点の700点が合格ラインです。）
Udemyや教科書に付属の模擬問題で多くの問題に触れていたのですらすら解くことができました。

## 最後に
最後まで読んで頂きましてありがとうございます。
この記事がAZ-104の合格に少しでも役に立っていただければと思います。
次はSC-900の取得を目標にCloudのセキュリティやコンプライアンス、ID ソリューションについて基礎から学んでいけたらと思っています。
Vue3でESLintを使ってみる（eslint-plugin-vue）

# 概要
本記事では、Vue3でESLint（eslint-plugin-vue）を実行する方法を紹介します。
（vue3は既にインストールしている想定で解説いたします。）

# インストール

## ESLint
```
npm install --save-dev eslint
```

## eslint-plugin-vue
```
npm install --save-dev eslint eslint-plugin-vue
```

# 設定
```package.json```と同じ階層に以下の設定ファイルを作成してください。

```.eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "plugin:vue/vue3-recommended"
  ],
  "plugins": [],
  "parserOptions": {},
  "env": {"browser": true},
  "globals": {},
  "rules": {}
}
```

```extends```にはフォーマットのルールを記述します。
- eslint:recommended
ESLint推奨のルールです。
https://eslint.org/docs/latest/rules/

- plugin:vue/recommended
ellint-plugin-vueのルールです。
https://eslint.vuejs.org/rules/
```"plugin:vue/vue3-recommended"```だと優先度A、B、Cのルールが適用されます。
優先度Aだけ適用したい場合は以下のように記述すると良いです。
```"plugin:vue/vue3-essential"```

試しに、ESLintが動作するかチェックしてみましょう。
```package.json```へdry実行するコマンドを追加します。
```package.json
    "scripts": {
        "lint-dry": "eslint 'resources/**/*.{js,vue}'"
    }
```

以下の規約違反があるvueファイルを作成します。
- ①複数の属性をもつ要素は、1 行に 1 要素ずつ、複数の行にわたって書くべきです。
- ②使用していない変数が存在する
```HelloVue.vue
<template>
  <!-- ① -->
  <input type="submit" value="Hello Vue">
</template>

<script>
import { onMounted } from 'vue'
export default ({
  setup() {
    console.log("start vue")
    var hogehoge;  // ②

    onMounted(() => {
      console.log('start mounted !')
    })
  },
})
</script>
```

ターミナルで```npm run lint-dry```を実行すると、以下のエラーが表示されます。
```
  2:24  warning  'value' should be on a new line       vue/max-attributes-per-line
  10:9   error    'hogehoge' is defined but never used  no-unused-vars
```
期待通りの動作を確認出来ました:raised_hands:

# ルールを無効にする方法
## ソースコード内に記述
無効にしたい行の前に以下形式で記述する必要があります。
```eslint-disable-next-line ルール名```

先ほどのエラーが表示されたファイルで試してみます。
```HelloVue.vue
<template>
  <!-- eslint-disable-next-line vue/max-attributes-per-line  -->
  <input type="submit" value="Hello Vue">
</template>

<script>
import { onMounted } from 'vue'
export default ({
  setup() {
    console.log("start vue")
    // eslint-disable-next-line no-unused-vars
    var hogehoge;

    onMounted(() => {
      console.log('start mounted !')
    })
  },
})
</script>
```

ターミナルで```npm run lint-dry```を実行して、エラーが表示されなければ完了です:ok_hand:

## eslint-todo-generatorを導入する
https://www.npmjs.com/package/eslint-todo-generator
これを使うと除外したいルールをファイルで管理することが出来ます。
ソースコードにルールを記述するよりこちらの方が良いかと思いました。

### インストール
```
npm i --save-dev eslint-todo-generator
```

### 設定
- 設定ファイルの作成
```
npx eslint-todo-generator -f json 'src/**/*'
```

- 設定ファイルにルールを記述する
```rules```：無効化したいルール
```files```：該当のファイルパス

```.eslintrc-todo.json
{
  "overrides": [
    {
      "rules": {
        "vue/max-attributes-per-line": "off",
        "no-unused-vars": "off"
      },
      "files": [
        "resources/js/components/HelloVue.vue"
      ]
    }
  ]
}
```

- ```.eslintrc.json```にルールを追加
```.eslintrc.json
{
    "extends": [
      "eslint:recommended",
      "plugin:vue/vue3-recommended",
      ".eslintrc-todo.json" // ここに追加
    ],
    "plugins": [],
    "parserOptions": {},
    "env": {"browser": true},
    "globals": {},
    "rules": {}
}
```

ターミナルで```npm run lint-dry```を実行して、エラーが表示されなければ完了です:ok_hand:
斜めから機械学習！不偏分散は何故、N-1 で割るのか直感的に 

機械学習を勉強していると何故、そうなるのか腑に落ちないことがよくあります。そんな機械学習の暗闇に斜めからスポットライトをあてたい。テーマは「不偏分散は何故、$N$ ではなく $N-1$ で割るのか」。直感的な説明を優先したいので厳密な説明を期待している方は他の記事を参照ください。

次の式を知っている人が本稿の対象です。

標本の分散：
$$ s^2=\frac{1}{N}\sum_{i=1}^{N} \left (x_i - \bar{x} \right) ^2$$

不偏分散：
$$ \hat{\sigma}^2=\frac{1}{N-1}\sum_{i=1}^{N} \left (x_i - \bar{x} \right) ^2$$

ここで $N$ は標本数、$\bar{x}$ は標本の平均


## N-1 で割る理由
不偏分散 $\hat{\sigma}^2$ は、母分散 $\sigma^2$ の点推定です。
標本から母分散（母集団の分散）を推定するときに用います（ここ重要）。

$N-1$ で割る不偏分散は、標本分散 $s^2$ よりも大きな値になります。逆にいうと標本の分散（の期待値）は、<b>母分散より小さくなる</b>（偏りがある）ということですが、なぜ小さくなるのかそれが疑問です。

母集団（母平均 $\mu$、母分散 $\sigma^2$）から標本を無作為抽出します。
![qiita1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/3f29ac7c-fb9a-b752-dbde-5172d8f8e5f3.png)


標本の分散を計算します。
![qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/1b8c63f4-117c-ba54-babd-b770f8f6e124.png)


上図のように母平均に近い標本の場合、標本の分散は母分散より小さくなりますが、次図のように母平均から遠く離れると母分散より大きくなるので大小が打ち消しあい標本の分散（の期待値）は偏りません。
![qiita3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/e4b6d46c-e2aa-f595-db8b-ed1fbc0d48fb.png)


次図のように標本平均が母平均から上振れすると標本の分散は、母分散より小さくなります。
![qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/dfd9fbb3-d9bc-cab2-034e-91a454edf2f8.png)

下振れしたときも標本の分散は、母分散より小さくなります。
![qiita5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/26c65ca7-8306-272f-6b34-716b92fd1ff1.png)

上振れと下振れのどちらも標本の分散は母分散より小さくなるので打ち消しあうことはありません。<b>標本平均と母平均との乖離が原因</b>で標本の分散（の期待値）は、母分散より小さくなるということです。
![qiita6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/c6652155-74ef-6346-732e-c1616574eb89.png)

以上が標本の分散（の期待値）が母分散より小さくなる理由です。


## N-1 の理由
無作為抽出を何度も繰り返したとき<b>標本平均 $\bar{x}$ の分布は、母集団の分布がどのような分布であっても、平均 $\mu$、分散 $\frac{\sigma^2}{N}$ の正規分布になる</b>ことが知られています（中心極限定理）。
![qiita9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/5fafc46d-d1a3-36e6-2408-17c8fe459434.png)


母平均 $\mu$ を用いて母分散を推定するときは、$N-1$ ではなく $N$ で割りますが（次式）

![qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/fcd9912e-91e8-1300-b5e6-5f005074beea.png)

多くの場合、母平均は未知なので上式のままだと計算できません。
「標本の分散」と「標本平均の分散」に分解し、「標本平均の分散」を期待値 $\frac{\sigma^2}{N}$ に置き換えます。
![qiita8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/552b7a95-a157-281d-28d9-e47c7f9d0c28.png)



$\frac{\sigma^2}{N}$ を左辺に移します。

$$ \hat{\sigma}^2 - \frac{\hat{\sigma}^2}{N} \cong \frac{1}{N}\sum_i^N \left(x_i - \bar{x} \right)^2$$

$$ \frac{N-1}{N}\hat{\sigma}^2 \cong \frac{1}{N}\sum_i^N \left(x_i - \bar{x} \right)^2$$

これより

$$ \hat{\sigma}^2 \cong \frac{1}{N-1}\sum_i^N \left(x_i - \bar{x} \right)^2$$

$N-1$ で割る不偏分散となりました。
きちんとした導出は参考リンクを参照ください。

## 参考リンク
大数の法則から中心極限定理を経て不偏分散へという次の書籍の説明が、個人的に分かり易かったです。

http://www.amazon.co.jp/dp/4335000871
cscの作法 その227

# 概要
cscの作法、調べてみた。
ポートスキャンしてみた。

# サンプルコード

```
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class test0 {
	public static void Main() {
		for (int i = 5299; i < 5302; i++)
		{
			try
			{
				TcpClient client = new TcpClient("127.0.0.1", i);
				client.ReceiveTimeout = 2000;
				client.SendTimeout = 2000;
				Console.WriteLine(String.Format("port {0} connected.", i));
			}
			catch (Exception)
			{
				Console.WriteLine(String.Format("port {0} ng.", i));
			}
		}
	}
}
```

# 実行結果

```
>scan0
port 5299 ng.
port 5300 ng.
port 5301 ng.
```


以上。
Heroku CLIがSnapをサポートから外しました

### 環境
Ubuntru 20.4

### はじめに
Herokuにログインするときに、次のようなWarningメッセージが表示されました。Heroku CLIのマイナーバージョンアップが行われたため、バージョンをアップしてくださいという注意メッセージのようです。
```
Warning: heroku update available from 7.60.1 to 7.60.2.
```

インストール済のHeroku CLIのバージョンは次のコマンドで確認できます。確かに、7.60.1になっています。
```
$heroku -v
heroku/7.60.1 linux-x64 node-v14.19.0
```

次のコマンドで、Hereoku CLIのバージョンアップを試みるがエラーが表示されます。自分の環境では、Heroku CLIはsnapを使ってインストールしているため、snapを使ってアップデートしてくださいということのようです。
```
$heroku update
 ›   Warning: update with: snap refresh heroku
heroku: Updating CLI... not updatable
```

Heroku CLIの公式サイト（最終更新日 2022年04月26日の情報）を見ると、snapを使ったインストールをサポートしなくなったようです。
https://devcenter.heroku.com/ja/articles/heroku-cli

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/63b99391-0943-db73-1dd9-e0adcf86b432.png)

snapは、UbuntuをサポートしているCanonicalが作ったパッケージ管理システムで、次期apt？と期待されたが、ここにきて、サポートを見送ったということは、どうも今後も普及が期待できないと判断したものと想定されます。

snapを使ってインストールしたパッケージの一覧を表示します。確かに、v7.60.1であることが確認できます。
```
$snap list
core    16-2.56  13308  latest/stable  canonical✓  core
heroku  v7.60.1  4092   latest/stable  heroku✓     classic
```

アップデート可能なパッケージの一覧を表示すると、全てのsnapが最新ですと表示されます。
```
$snap refresh --list
All snaps up to date
```

リモートリポジトリにHerokuが存在することを確認するが、v7.60.1しか表示されません。
```
$snap search heroku
heroku           v7.60.1
```

リモートリポジトリに存在するHerokuの詳細情報を表示すると、バージョンの一覧が表示され、ここを見ると、v7.60.2が存在していることが確認できます。
```
$snap info heroku

name:      heroku
summary:   CLI client for Heroku
publisher: Heroku✓
store-url: https://snapcraft.io/heroku
contact:   https://cli.heroku.com
license:   unset
description: |
  The Heroku Command Line Interface (CLI), formerly known as the Heroku Toolbelt, is a tool for
  creating and managing Heroku apps from the command line / shell of various operating systems.
commands:
  - heroku
snap-id:      pAGMQ0HpmF09Smxc9d3ZOUiVNhtWhy7r
tracking:     latest/stable
refresh-date: 2022-04-01
channels:
  latest/stable:    v7.60.1 2022-03-31 (4092) 37MB classic
  latest/candidate: v7.60.1 2022-03-31 (4092) 37MB classic
  latest/beta:      v7.60.1 2022-03-31 (4092) 37MB classic
  latest/edge:      v7.60.2 2022-04-28 (4093) 37MB classic
installed:          v7.60.1            (4092) 37MB classic
```

snapでインストールされた全てのパッケージを一括でアップデートする場合は「snap refresh」コマンドになります。snapだけを特定してアップデートする場合は次のコマンドになります。こちらのコマンドを使って、Heroku CLIをアップデートします。（ルート権限でないと実行できないため、sudoを付けて実行します）
```
$sudo snap refresh heroku
snap "heroku" has no updates available
```

しかし、やはり、アップデートできませんと表示されます。Herokuがsnapをサポートから外したということは、新規インストールができなくなっただけでなく、アップデートもできなくなったようです。

### 結論
snapでインストールしたHeroku CLIを最新のバージョンにアップする場合は、一旦、現状バージョンをsnapでアンインストールした後、別の方法でインストールし直す必要があるようです。
cscの作法 その226

# 概要
cscの作法、調べてみた。
jwtのhashを暗号化してみた。

# サンプルコード

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

public class test0 {
	static void Main() {
		
		Console.WriteLine("ok0");
		AsymmetricCipherKeyPair privateKey;
		using (var reader = new StreamReader(@"privatekey.pem", Encoding.ASCII))
		{
			var pemReader = new PemReader(reader);
			privateKey = (AsymmetricCipherKeyPair) pemReader.ReadObject();
		}
		Console.WriteLine("ok1");
		var rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters) privateKey.Private);
		RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
		rsa.ImportParameters(rsaParams);
		Console.WriteLine("ok2");
		string token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJIZWxsbyxXb3JsZCEiLCJuYW1lIjoiS29zdWtlIE1hdHN1aSIsImlhdCI6ODc1Njc0ODM5Mjg0fQ.N_zzSrKu4emL6OzpAQ7nBsR6XkV3I2TEkkrqM4Ldm7m42a78HEXsHx5X7AQQlApSPzCuIL3elXfrr4Tl2IRlstlsU6Im79V7hpWigAWnT4HyINEX74LKGeGHwve1iJpXKvTYIsjwTaKWwVGmHG2CPqVz_gVlNJJoe9PyMGzLnzZcUIYj20ATaE1NgdSoZEc9xA4T7EQWdTS4WRtSffPTREPG1Wgf0LVQZueW2P1kYsf9-_ItJTJk2GRqnzqaob-5hRANrCqWcxEr-HKw4PIftnxiVN3WqT3NWG7qT6UKfsKVNfFJZJOWcmr0UJGIpHavuvjnd-5P_9AbYchkKCucMg";
		var tokenBytes = Encoding.UTF8.GetBytes(token);
		var tokenHash = SHA256.Create().ComputeHash(tokenBytes);
		Console.WriteLine(Convert.ToBase64String(tokenHash));
		var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
		rsaFormatter.SetHashAlgorithm("SHA256");
		var signBytes = rsaFormatter.CreateSignature(tokenHash);
		var signBase64url = Convert.ToBase64String(signBytes).TrimEnd('=').Replace('+', '-').Replace('/', '_');
		Console.WriteLine(signBase64url);
		var jwt = token + "." + signBase64url;
		//Console.WriteLine(jwt);
		Console.WriteLine("ok3");
	}
}


```

# 実行結果

```
ok0
ok1
ok2
oLN0oMLxb/PcMJXQ1F3lCCB9WiGw6b7QQiGj2n43NrA=
IA9bjBC8L82AmZQNEcBJv37Fp5GAk4NAXjIt-Ry8awn4xNy_Gk7cHAOsVVrT3VoV1vJOwGG0OYwabrF3gIGV3zGms0jO6rN0k0gL238GAa0dysys8mb73pd6sriyPxvbeLTApeBwAVZ88CM0sW8m1u-eH3u-CjBKBbg2oGKKOkjTR_bAHv-Ab6asOzN1gT6xTrBH6gR6g24V_DywgronJeVEIY7I4AzixoECoPf7wYOtskEuJSHbcyozt4Fl1i94eWVx5A-nMipuZ3e5LtVarAPZlo5GzLrFZHAXnbROdY44WQMa6Jqw3GHWPKUPLqvVv6IRnDyyMUMMoxrPqmIjV9pyD8FdA0-jx-1Dn1BDwuWnBhozKC5x_m5hyczhalBA3FaHm1VLz00z0mKhcRZXSP-hYnGbfa6L-2Mskh0_TVOVvV1iVT-J68BJUOMI56Au7nKz7Q90q7RtAU_9srZp_deHvPPXtovxzB29qkmGcUigJOkgCyBfEKDdsZ6uqaGTQhVEYlZ3y87tpKauWr5GtruwgrXNh5w6SGATugLhyAFATmh6IgSn0vvmemJnhNpC2icThrlX5yX2z_KcgJGBQ7zv24USf0Fv1ygUZwAPsjQDghiVgvfnpJ_iYX897ykMj-fqRCNJYz6RHfOThwkDD34YZwAWl8OIBRQcq_BPOI8
ok3

```

以上。
FortiClient VPNで初回の接続ができない場合

# 環境情報
バージョン: 7.0.1.0083
OS: Windows Server 2019

# 事象
FortiClient VPNをインストールし、VPNに接続しようとすると以下のエラーメッセージが表示されて接続できない。  
`To make SSL VPN connection work, please turn off IE Security Configuration`  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/97ed6545-905c-a4dc-f0cf-db8970e9f620.png) 
VPNの接続先をIEの信頼済みサイトに追加しても、セキュリティレベルを下げても発生する。

# 原因
IE ESC(IEセキュリティ強化の構成)が原因。  
過去のバージョンでは問題にならなかった。  
FortiClinetのバージョンアップによるものなのか、Windows Serverのセキュリティ強化によるものなのか不明。  
(Fortinetのフォーラムで[同じ質問](https://community.fortinet.com/t5/Fortinet-Forum/Latest-Forti-Client-Fails-With-quot-Turn-Off-IE-Security/td-p/209341)が挙がっていたが公式からの回答がなかったので後者の可能性が高い？)

# 対処
* 初回の接続時のみ、IE ESCを無効化する。(**後で有効化するのを忘れないように**)  
1. サーバーマネージャー → ローカルサーバー → IEセキュリティ強化の構成(「有効」と書かれたラベル)を選択。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/66c06d6b-3d94-0b1d-bc45-aad174a300e8.png)
2. Administratorsグループ、Usersグループ、ともに「オフ」にする。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/ef74a1ce-8e84-5ffe-1829-f4e9a9dddc58.png)
※ Administratorsグループだけでは事象が解決しなかった。FortiClient VPNを「管理者として実行」で起動するならAdministratorsグループだけ「オフ」でもよい？かも)  

3. エラーメッセージが表示されずにVPNに接続できるはず。  
**接続に成功したら元に戻す(IE ESCを有効化する)のを忘れないこと。**  

~~この作業は初回接続時だけでよい模様。~~  
~~2回目以降はIE ESCが有効になっていてもメッセージは出なかった。~~  
訂正: 2回目以降もIE ESCは無効にする必要がある模様。
【AWS】「AWS Well-Architected Framework」や「ベストプラクティス」を紐解く会（社内勉強会）を実施しました

# はじめに
最近、めちゃんこ暑くて、絶賛とろけてます。
換気のために窓を開けると、熱風が注ぎ込んできますね！

どーも、のぶこふです。

ついったでも少し呟いたのですが、社内向けに「[W-A](https://aws.amazon.com/jp/architecture/well-architected)」や、[AWS をはじめる 10 のことシリーズ「AWS でアーキテクチャ設計を検討する上で知っておくべき 10 のこと (+1)」](https://pages.awscloud.com/JAPAN-event-OE-At-least-10-Architecting-2020-reg-event-LP.html?aws_introduction_page)を紐解く会を実施しました。

https://twitter.com/nobkovskii/status/1535139208335335425?s=20&t=Ms9-YW8wJDV7V10YXBKTAA

## モチベーション

クラスメソッドさんの研修に参加させていただいて、W-Aの大切さを改めて実感したので、これは社内にも還元しないとアカンな、ということで突貫工事でパワポ作りました。

W-Aやベストプラクティスだけだと、サービスと紐づかないと思うので、私なりにいくつかサービスも記載しています（もちろん、もっと該当するサービスはあると思います）。
私もまだまだ勉強中なので、多分に間違いがあるかと思いますが、概要は伝えられたかと思います。
・・・と言っても、ありものの資料の転記がほとんですけど。

## 資料

なかなかのボリュームの資料となり、せっかくなので一部抜粋（と言ってもほとんどですが）して公開しようと思います。

アーキテクチャレビューの箇所は、大人の事情でスライドは非表示にしています。
内容としては、システム構成図を見て、良し悪しをやんややんや言う感じで実施しました。
題材はなんでも良いと思いますが、シンプルな方がとっつきやすいと思います。

「開発用と本番用で、VPC分けているねー」
「マネージドサービス使ってるね」
「リージョンが一つしか無いので、大阪リージョンとか使おう」

みたいな感じで、ワイワイ出来たかと思います。

<iframe src="https://docs.google.com/presentation/d/18VYpSiJjj0g6cWxawlNZaslQroSp9B6wbKjbNGVILZI/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

## おわりに
弊社では、このように月に数回勉強会を開催しています。
サービスだけ知っていても何も繋がらないので、次回はシステム開発系のハンズオンとか勉強会を実施予定です！

今回はここまでです。
ありがとうございました。
Salesforce Integration using Webhooks 【事前準備編】


ちょっと、情報収集と学習のための整理を行います。
+ [Qiita Engineer Festa 2022](https://qiita.com/official-campaigns/engineer-festa/2022?utm_medium=engineerfesta&utm_source=maincontentbanner)
+ [Claris Connect を使った SaaS 連携ユースケースを紹介しよう！](https://qiita.com/official-events/eeadea1de45a11be944e)

# Claris Connect側の考察

Claris ConnectにはSalesforceとのコネクターは用意されていないみたいです。しかしこの資料を読むと「WebhookがサポートされているAPIは連携可能です。」とある。比較対象のZapierにはこの記載はない（しかし、ZapierはSalesforceとのコネクターはあると思う）。ということで、Webhook機能を使えばClaris Connectを使ってSalesforceと連携できる可能性はありそうです。

[第0回〜Claris Connectを使ってみよう〜｜サポータス開発者ブログ](https://fmsolution.supportas.co.jp/blog/20210601)

---------------------
関連資料
+ [Claris Connect App Directory Find your app. Make a connection.](https://www.claris.com/connect/apps/?category=all)
+ [Using an On-Premise Agent with Claris Connect](https://support.claris.com/s/article/How-to-create-a-project-with-Claris-Connect?language=en_US#:~:text=Claris%20Connect%20lets%20you%20add,you%20are%20trying%20to%20access.)

# Salesforce側の考察

[SALESFORCE INTEGRATION USING WEBHOOKS](https://www.apexhours.com/salesforce-integration-using-webhooks/)

以下がSalesforceが受ける側として考えた場合に使える方法のようです。自由度を考えると1番目のApex REST APIを作るのがよさそうです。まぁ、Apexなので私でも作ることはできそう。

Creation of Webhook supported URL
In Salesforce creating a webhook supported URL involves the below steps:

1. Create Apex REST API
2. Create a public Site
3. Enable Apex class Access to the site

[Apex クラスを REST Web サービスとして公開](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_rest.htm)
FreeRadius設定項目

freeradius 3.0.20
almalinux9.0
10.150.200.26
共有鍵［apresia］
MAC認証パスワード(1q2w3e)

■ipv4設定
DGW:10.150.200.250
DNS:8.8.8.8

■SELinuxの無効化		
# vi /etc/selinux/config		
SELINUX=enforcing		
		
■FWの無効化		
systemctl stop firewalld		
systemctl disable firewalld		
		
# reboot		
# getenforce		
		
■freeradiusの設定		
dnf install freeradius*		
cd /etc/raddb/cert		
make ca.pem		ルート証明書
make server.pem		サーバー証明書
make client.pem		クライアント証明書
openssl dhparam -5 -out dh 1024		DHパラメータファイル
chmod 755 server.pem		なぜか読込めないのでパーミッションを変更
radiusd -X		デバックモードで起動



■設定ファイルの編集

/etc/raddb/users
#下記追記分
#MACアドレス認証
<mac-address> Cleartext-Password:="1q2w3e"
	Na-Vlan-ID=200

#WEB認証
wuser Cleartext-Password:="wuser"
	Na-Vlan-ID=200

#802.1X認証(EAP-PEAP)
euser Auth-Type:EAP,Cleartext-Password:="euser"
	Tunnel-Type = 13,
	Tunnel-Medium-Type = 6,
	Tunnel-Private-Group-Id = 200


/etc/raddb/dictionary
#下記追記分
VENDOR APRESIA 278 
BEGIN-VENDOR APRESIA 
ATTRIBUTE NA-Vlan-Id 192 integer 
END-VENDOR APRESIA


/etc/raddb/mods-enabled/eap
tls-config tls-common {...
#下記追記分
private_key_password = whatever 
private_key_file =/etc/raddb/certs/server.key 
certificate_file = /etc/raddb/certs/server.pem
 ca_file = /etc/raddb/certs/ca.pem
 check_crl = no #CRLのチェック省略
 allow_expired_crl = yes #有効期限の切れたCRLも使えるように
 ...}


/etc/raddb/sites-available/tls
tls {...
#下記追記分
private_key_password = whatever 
private_key_file =/etc/raddb/certs/server.key 
certificate_file = /etc/raddb/certs/server.pem 
ca_file = /etc/raddb/certs/ca.pem
check_crl = no #CRLのチェック省略
allow_expired_crl = yes #有効期限の切れたCRLも使えるように
...
【SwiftUI】モディファイアを条件によって変える

# はじめに
今回作成するサンプルはindexが3の倍数の場合にpaddingを付けるというものです。
いい案が思いつかなかったので、サンプルとしてはわかりにくいかも知れないです笑
完成形はこのような形になります。
![simulator_screenshot_606CF1B6-853E-400A-A0E9-684FC1AD1D5F.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/bf77a33d-5135-04f5-70df-b79683d393b4.png)


# やり方
Viewを拡張してif文で条件分岐します。
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        List {
            ForEach(0..<30) { index in
                Text("テキスト \(index)")
                    .listPadding(index)
            }
        }
    }
}

extension View {
    func listPadding(_ index: Int) -> some View {
        return padding(.leading, index % 3 == 0 ? 30 : 0)
    }
}
```

# おわり
私はよく端末によってモディファイアを変更する際に使用しています。
こんな感じ ↓
```swift
extension View {
    func trailingPadding() -> some View {
        return padding(.trailing, UIDevice.current.userInterfaceIdiom == .pad ? 17 : 3)
    }
}
```

あげたサンプルコードは全て`padding`でしたがどのモディファイアでも可能です。
ECS Execでトラブルが起きたら、amazon-ecs-exec-checkerを使ってみよう

ECS Execは、ECSで稼働しているコンテナに対しコマンドを実行できる仕組みです。

ローカル環境だと出ないエラーが出てしまって、原因がわからない場合や、
VPC内のリソース以外からはRDSへの接続が許可されていない場合に活躍します。
仰々しい名前が付いていますが、独立したサービスではなく、SSMでコンテナに接続する感じです。
AWS CLIが入っていれば、ぜひ試してみてください。

導入方法は下記のドキュメントを御覧ください。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html

さて、ECS Execするための設定なのですが、
簡単そうに見えて、ネットワークなどの設定によっては、一発で繋がらない事もあります。
AWS Execでは色々と隠蔽されているのもあり、トラブルの原因を探るのはなかなか難しい。
(よくあるのは、ssmmessagesへの権限付与が足りないとか..VPC Endpointがないとか..)

そんなときに役立つのが、 `amazon-ecs-exec-checker` です。

https://github.com/aws-containers/amazon-ecs-exec-checker

公式のツールです。
ヤバいことに、**Git Cloneしなくても実行できます**

下記のコマンドでもチェック可能です。
```bash
$ export AWS_PROFILE=myprofile # プロファイル使っているなら指定
$ export AWS_REGION=ap-northeast-1 # 適宜リージョンを指定
$ bash <( curl -Ls https://raw.githubusercontent.com/aws-containers/amazon-ecs-exec-checker/main/check-ecs-exec.sh ) <ECSクラスター名> <ECSタスクID>
```

ECSクラスター名と、タスクIDを引数に渡すと、以下のように理由を教えてくれます。

```bash
🔴 Read-Only Root Filesystem | ReadOnly
ECS Exec uses the SSM agent as its managed agent, and the agents requires that the container file system is able to be written in order to create the required directories and files. Therefore, you need to set the readonlyRootFilesystem flag as false in your task definition to exec into the container using ECS Exec. See the "Considerations for using ECS Exec" in the ECS official documentation for more details.
```

めっちゃ便利ですね！！！
「Lean と DevOps の科学」を読む前に知りたかったこと

# はじめに
**Lean と DevOps の科学** は科学的な調査、分析を基に組織のパフォーマンス向上を促すにはどうすればいいかを解説した本です。実際に読んでみて、「よりスムーズに読み進めるために事前に知っておきたかったこと」がいくつかあったのでご紹介したいと思います。

https://www.amazon.co.jp/dp/B07L2R3LTN/ref=cm_sw_r_tw_dp_V20DDQ4C59XN99G3EMZ5

# デリバリのパフォーマンス
本書では組織の生産性を **デリバリのパフォーマンス** と表現しています。
似たような用語として、組織のパフォーマンス、継続的デリバリ、継続的インテグレーションなどが紹介されていますが、全て別の概念なので混同しないように注意してください。自分は少しハマりました。

## 4 つの指標
デリバリのパフォーマンスは以下の 4 つの指標で計測可能であるとしています。

- デプロイ頻度
- 変更のリードタイム
- MTTR（インシデントからの平均修復時間）
- 変更失敗率

## クイックチェック
下記のサイトで上記の 4 つの指標を回答することで、自分のチームの相対的なデリバリのパフォーマンスを知ることができます。まずは現実を知りましょう。

https://www.devops-research.com/quickcheck.html

例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/602f3bc4-af56-1ae8-a281-384f76bd1d0c.png)

# ケイパビリティ
本書で幾度となく登場するケイパビリティという用語があります。なるべく短く端的に言うと

>「テクノロジーやビジネスを巡る状況は絶えず変化するもの」という前提に基づいて、組織が継続的な改善を行って進歩していくことを目的に、注目すべき組織的な能力あるいは機能。

というような意味のようです。
最初は理解できなかったので意味を深追いしてしまいましたが、そこまで時間をかける意味は無かったな、と思いました。 **「改善のために注目すべきポイント」と読み替えればOK** です。

## ケイパビリティ相関図
読み進めていくと分かるのですが、**ケイパビリティ同士の関係が複雑で非常に分かりづらい** です。
実は巻末の付録に相関図が載っているので、 **本書を手に取ったら最初に目を通すことをお勧めします。**
私は読み終わった後に気づいてしまいました...。

![1009063.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/af1a5696-500f-5045-7bc9-2fd788fd7367.jpeg)
出典元: Lean と DevOps の科学

# おわりに
色々モノ申しましたが、組織のパフォーマンスを改善したいと考えている方は、この本は読む価値ありです。是非。
.docをpdfに変換する

とりあえずのメモ。
.docxをpdf化するライブラリはpythonにあるが、.docは無さそうだったので。
指定したフォルダ内の.docをpdf化したものを同じフォルダ内に生成する。

sofficeコマンドを使用できるようにした後、以下を実行

```python:doc_to_pdf.py
import os
import glob
import pathlib
import subprocess

path = "/Users/user/Downloads/doc_folder/" #ここでどのフォルダで変換したいか指定
p_temp = pathlib.Path(path)

for i in list(p_temp.glob('**/*')):
    dirname = os.path.dirname(i)
    root, extention = os.path.splitext(i)
    if extention == '.doc':
        convert_command = f"soffice --headless --convert-to pdf:writer_pdf_Export {i} --outdir {dirname}"
        subprocess.run(convert_command, shell=True)
```
VisualStudioプロセス開始時にデバッガーアタッチする方法

プロセスの開始からデバッグしたいとき、プロセスが起動してからアタッチしても遅いので、プロセスの開始時にデバッガーアタッチする方法です。

こちらを参照しています。
事後デバッグを有効にする
https://docs.microsoft.com/ja-jp/windows-hardware/drivers/debugger/enabling-postmortem-debugging

**■レジストリ操作**
"Image File Execution Options" にデバッガでアタッチする被検査プログラムをキーとして追加します。

名前"Debugger"で、値はデバッガーを指定します。

例）キー
Hoge.exe
~~~text:レジストリ
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Hoge.exe]
Debugger="C:\\WINDOWS\\system32\\vsjitdebugger.exe"

~~~
名前"Auto"で、値は"1"を指定します。
64ビットアプリ、32ビットアプリで異なります。
~~~text:レジストリ
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
Auto="1"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]
Auto="1"

~~~
![debug2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189864/20d545c4-e172-d721-8e88-08ca5ccefab0.png)

**■操作**
プロセス（ここでは、AppForTest.exe）を起動するとデバッガーの選択ダイアログが表示されるようになります。
対象のデバッガーを選びます。
![debug1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189864/04ba3e7b-d97a-936b-ba1e-fa2ada6fffb9.png)
アタッチするプログラムを Visual Studio で開いて、ブレークポイントを設定しておきます。
実行されるとブレークポイントで停止します。
Vimiumのテーマを作った。

# なにこれ
Vimiumと言うブラウザ拡張機能の自作テーマです。
[Vimiumダウンロード先](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb)

# 画像
## 黒
![96675682-3C04-4A36-808D-8A33589E854D.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/268563cb-1a59-cf29-3150-a660a4348682.gif)
## 白
![B0A02A6F-A95D-4037-96EE-D4CE20670501.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/56c2950a-4fd3-00cf-a9f8-6cc1fbf3f07c.gif)

# 特徴
 - 虹色にアニメーションする。
 - カッコいい
 - ゲーミング
 - 白と黒の二種類がある
 - ゲーミングキーボードっぽい。

インストール方法とかは、githubのreadme.mdに書いてるので是非。MITライセンスです。

https://github.com/zozonteq/vimium-rgb-theme
[FormKit] Vue3, Nuxt3 で使える便利なフォームライブラリ「FormKit」を簡単に紹介するよ

## FormKitってなに？

* Vue3, Nuxt3 でフォームを作るときに便利なライブラリだよ
* FormKitひとつあれば、フォームに関すること（バリデーションやテーマ設定、国際化など）をすべて対応できるよ
* JSONにシリアライズできるオブジェクト（スキーマ）で、フォームを生成できるよ

https://formkit.com/

まだ日本語の記事をほぼ見かけないけれど、実際に使ってみて便利だなと思ったから、今回紹介してみる。

## 何が良いの？（個人的な感想）
* JSONにシリアライズできる簡潔なオブジェクトでフォーム生成できるのがとっても好き
* TailwindCSSとの噛み合わせも良い
* バリデーションもシンプル
* 公式ドキュメントがとてつもなく分かりやすい（大事）
* カスタムinputも簡単に作れる

## 実際にコード見せてよ

じゃあ、下記の条件を満たすフォームを作ってみるよ。
* 名前を入力して、submitで関数を実行できる
* 必須バリデーションあり
* 名前は30文字まで

こんな感じ

```vue
<script setup lang="ts">
import { FormKitSchemaNode } from '@formkit/core';

// 名前を入力するスキーマを定義（前述のJSONにシリアライズできる云々はこれ）
const nameFormSchema: FormKitSchemaNode = {
  $cmp: "FormKit",
  props: {
    type: "text",
    label: "名前",
    name: "nameForm",
    // 必須 + 文字列の長さは 0文字から30文字 まで
    validation: "required|length:0,30",
    // 検証タイミングはユーザがinputの値を変更した後
    validationVisibility: "dirty",
    // バリデーションの内容によってエラーメッセージを出しわけ
    validationMessages: {
      required: "名前を入力してください",
      length: "名前は30文字以内で入力してください。",
    }
  }
};

// 表示させたいフォームのスキーマを登録（複数可）
const schema = [nameFormSchema];

const submit = async (e: {nameForm: string}) => {
  // 好きな処理を実装してね （フォームのname属性をキー、入力値がvalueのオブジェクトが手に入る）
  console.log(e);
};
</script>
<template>
  <FormKit
    type="form"
    @submit="submit"
    submit-label="登録する"
    incomplete-message="入力内容に不備があるよ">
    <FormKitSchema :schema="schema"/>
  </FormKit>
</template>
```

これだけで、前述の条件を満たすフォームができた。

![kdswq-pyjsl.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267156/c898a0bf-d592-ddba-7d43-2060eb3b1073.gif)



コード中の `FormKitSchemaNode` は見ての通りフォームのname属性やラベル、バリデーションの内容を定義するスキーマになっていて、これが冒頭で書いた「JSONにシリアライズできるオブジェクトでフォームを生成できる」機能だよ。

シリアライズ可能だから、JSONに変換してフォームそのものをユーザごとに個別でDBに保存するなんてこともできるね。

## あとがき

今回は簡単な紹介だからここまでだけど、FormKitはカスタマイズも自在で、デザインをいじったり、 `FormKitSchemaNode` として扱える自作Inputもコンポーネントとして作れるから、要件に合わせた柔軟かつ迅速な実装を進めていくことができるよ。

▼ FormKitでカスタムInputを作るドキュメントはここ

https://formkit.com/guides/create-a-custom-input

よかったら使ってみてね！（使う人が増えたら、きっともっと良くなっていくと思うから）

## 著者プロフィール

faable01です。かつては創作仲間と小説を書いたり、製菓業界で楽しくやっていたはずが、紆余曲折を経て、サーバーレス技術を触るのが好きなITエンジニアになっていました。AWSのIaC兼サーバレス爆速開発ツール **「SST」** が好きです。個人ブログでもたまに記事を書いています。

https://signote.link

それから、業務日報SaaS **「RevisNote」** を運営しています。リッチテキストでの日報と、短文SNS感のある分報を書けるのが特徴で、組織に所属する人数での従量課金制です。アカウント開設後すぐ使えて、無料プランもあるから、気軽にお試しください。

https://revisnote.com?1710501811980
Delta Lakeのご紹介

[Introduction to Delta Lake \| Databricks on AWS](https://docs.databricks.com/getting-started/delta.html) [2022/1/23時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

有用なデータドリブンによる意思決定を行うための重要な条件の一つは、背後にあるデータストアの構造、アクセス容易性、品質です。このため、すべてのエンドユーザーのデータアクセスに対する適切な戦略を持つことが重要になります。

このような戦略の一つの観点は、[Delta Lake](https://delta.io/)によって提供されるようなデータストレージフォーマットとなります。

# Delta Lakeとは？

Delta LakeはDatabricksレイクハウスアーキテクチャの鍵となるコンポーネントです。Deltaテーブルフォーマットは、大規模エンタープライズレイクハウスで広く使われている標準となっています。別のオープンソースフォーマットであるParquetをベースとしており、Delta Lakeはさらなる頑健性、スピード、バージョン管理、データウェアハウスのようなACID準拠のような高度な機能を提供します。これは、既存の安価なblobストレージサービスを用いることによるコストメリットに追加されるものとなります。

DatabricksにはDelta Lakeのビルトインサポートがあり、最新のDatabricksランタイムには、さらにスピードと性能を改善するパフォーマンスのエンハンスメントが含まれています。

Delta Lakeとその機能に関するプレゼンテーションやディスカッションに関しては、[Making Apache Spark better with Delta Lake](https://databricks.com/discover/getting-started-with-delta-lake-tech-talks/making-apache-spark-better-with-delta-lake)をご覧ください。

# Delta LakeとDelta Live Tablesによるデータパイプライン

全体的なデータ戦略を分解すると、Delta Lakeで構築されたデータパイプラインは、レイヤー分けされたマルチホップの戦略に従うことになります。これは、生データ(ブロンズレベル)に対するデータクレンジング、データ変換の処理がされた状態(シルバーレベル)、最も処理され、ビジネスに活用できるテーブル(ゴールドレベル)に至る連続的なパターンとなります。

このアプローチに関する全体的な検証に関しては、プレゼンテーション[Simplify and Scale Data Engineering Pipelines](https://databricks.com/discover/getting-started-with-delta-lake-tech-talks/simplify-scale-data-engineering-pipelines)をご覧ください。

また、Databricksには高信頼、メンテナンス可能、テスト可能なデータ処理パイプラインを構築するためのパワフルなフレームワークである[Delta Live Tables](https://docs.databricks.com/data-engineering/delta-live-tables/index.html)が含まれています。お手元のデータに対する変換処理を定義することができ、Delta Live Tablesはタスクオーケストレーション、クラスター管理、モニタリング、データ品質、エラーハンドリングを管理します。

一連の別々のApache Sparkタスクを用いてデータパイプラインを定義するのではなく、Delta Live Tablesはそれぞれのステップで定義したターゲットスキーマに基づいてデータの変換を行います。

イントロダクションに関しては、[Delta Live Tablesクイックスタート](https://qiita.com/taka_yayoi/items/7fe8ed2c2f95fd53cc3d)をご覧ください。

# 概要とクイックスタート

Delta LakeとDelta Live Tablesを使い始めるには、以下をご覧ください。

- [Introduction](https://docs.databricks.com/delta/delta-intro.html)
- [Delta Live Tablesクイックスタート](https://qiita.com/taka_yayoi/items/7fe8ed2c2f95fd53cc3d)
- [Introductory notebooks](https://docs.databricks.com/delta/intro-notebooks.html)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
なにそれから学ぶCORS

# 初めに
OWASPからWAFの勉強をしようと思った際、[アクセス制御の不備](https://owasp.org/Top10/ja/A01_2021-Broken_Access_Control/#_1)で、早速わからないことが・・・

> CORSの誤設定によって認可されていない/信用されていないオリジンからのAPIアクセスが許可されてしまう。

CORS？なにそれ？聞いたこともない・・・

# CORS

ってことで[CORS MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)を見てみた。

> オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。

なるほどと言いたいところだが、ちんぷんかんぷん・・・
ということで、もう少し深堀して調べてわかったことをアウトプットします。

# 調べてわかったこと
## CORSとは
JavaScriptからXMLHttpRequestなどを使って異なるオリジンにアクセスすること。
（ブラウザからWebAPIをキックする際に使われる技術）

オリジンとは、ドメイン、プロトコル、ポート番号のこと。

例えば、送信元が`http://hogehoge:80/sample`だとします。
そこから下記URLに対してWebAPIをキックした際、異なるオリジン／同一オリジンの判定は以下の表のようになります。

| オリジン | URL |
| --- | --- |
| 異なる | http://hoge:80/sample |
| 異なる | http://hogehoge:8080/sample |
|異なる | https://hogehoge:80/sample |
| 同一 | http://hogehoge:80/sample/list |
| 同一 | http://hogehoge:80/list |



また、単純なアクセス（※1）と単純でないアクセスで、仕組みが異なります。
単純でないアクセスの場合、プリフライトと呼ばれる事前にOPTIONメソッドのリクエストを送信し、実際のリクエストを送信して問題ないか確認します。

※1　単純なアクセスは、以下のすべてを満たす場合と定義されています。
* リクエストのHTTPメソッドがPOST、GET、HEADのいずれかになっている
* HTTPヘッダーに、以下を含んでいる。
Accept、Accept-Language、Content-Language、Content-Type（application/x-www-form-urlencoded
、multipart/form-data、
text/plainのいずれか）


## 処理イメージ（プリフライトあり）
プリフライトなしは、単純にサーバーにリクエスト送信してレスポンスを返すだけなので割愛。
1. 【クライアント】実際のリクエスト前に相手側サーバーへのアクセスが可能か確認を行う（プリフライトリクエスト）
1. 【サーバー】アクセス許可され、HTTPステータス200を返す（レスポンスに許可するHTTPメソッドなどの情報を返します）
1. 【クライアント】アクセス許可された場合は、実際のリクエストを送信する
1. 【サーバー】通常と同様に応答を返す

## アクセス許可設定
`Access-Control-Allow-Credentials`、`Access-Control-Max-Age`も関連する設定ですが、今回は割愛。

### Access-Control-Allow-Origin
許可するオリジンを設定します。
制限を必要としない場合、ワイルドカード（*）を設定します。

```
Header set Access-Control-Allow-Origin "http://hogehoge:80"
Header set Access-Control-Allow-Origin "*"
```

### Access-Control-Allow-Method
許可するHTTPメソッド（POST、PUTなど）を指定します。

### Access-Control-Allow-Headers
許可するHTTPヘッダーを指定します。

## 最後に
マイクロサービスが流行っている昨今なら気を付けておくべき事柄と思いました。
現職では、APIを扱う機会があまりありませんでしたが、今後の触れる機会がある技術として良い勉強になりました。
また、今回は技術を調べるだけになってしまったので、検証もやってみようと思います。
Salesforceでケースのクローズが表示されないときの対応方法

Salesforceのケースオブジェクトの
状況項目に「Closed」があるにも関わらず項目で選択できないことがあります


（状況の項目）
![ケースのクローズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/175fecb9-5dc5-bdbd-33cb-7139521ad620.png)


（ケースのページ上）
![ケース更新.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fd703dba-84fe-d27a-834a-eb67e4d220a5.png)

この場合
「サポート設定」に「クローズケースの状況項目を表示」にチェックをつければ対応できることがございます。
ぜひご確認ください
![クローズのケース.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/464bd116-5cea-8584-e8c2-7d77a10d72a8.png)
WWDCのセッションビデオ一覧表の作り方

こちら [[WWDC22]セッションビデオ一覧 - Qiita](https://qiita.com/YokohamaHori/items/a67dcc89463ea9e7bcb0) でWWDC22のセッションビデオの一覧表をMarkdown形式で作成した手順になります。

もっとスマートな方法をとりたかったのですが、あまり時間をかけたくなかったので、最短の調査で完成する方法にしました。（やっつけ仕事なので、後で思い出せるようにメモしておきます）

# やりたいこと

WWDCのセッションビデオを曜日ごとに一覧表示したい。

## フォーマット

```swift
# Tuesday

| 項番 | タイトル(URLリンク付き) | メモ |
| --- | --- | --- |
| 1 | [Add accessibility to your Unity games](https://developer.apple.com/videos/play/wwdc2022/10151/) |  
```

## WWDCのセッション一覧

[Sessions - WWDC22 - Apple Developer](https://developer.apple.com/wwdc22/sessions/)

# 作成方法

## 使用するアドオン

- Chrome のアドオン 「GetTabInfo」
    - [複数ページのタイトルとURLを一発取得！ Chromeの必須アドオン「GetTabInfo」 | できるネット](https://dekiru.net/article/14276/)
- Google Spreadsheet のアドオン 「GenerateMarkdownTable」
    - [スプレッドシートを Markdown 表形式に変換してくれるアドオン GenerateMarkdownTable が便利だ](https://zenn.dev/junki555/articles/04fcee17f1a0eb)

## 作成手順

- 上記アドオンをインストールしておく
- (Chrome)セッションビデオ一覧のサイトを開いておく
    - [Sessions - WWDC22 - Apple Developer](https://developer.apple.com/wwdc22/sessions/)
- (Chrome)一覧を作成したい曜日のビデオの全リンクを新規タブで開く
- (Chrome)拡張機能から「GetTabInfo」を選択する
- (GetTabInfo) Template に以下のフォーマットを入力する
    
    ```swift
    [%%TITLE%%](%%URL%%)
    ```
    
- (GetTabInfo) PreviewにMarkdown形式のタイトル付きリンクが作成されるので Copy をする
- (適当なテキストエディタ)ペーストして整形する
    - 一番上の Sessions の行は不要なので削除
    - `WWDC22 - Videos - Apple Developer`の文言は不要なので一括削除
    - 整形したテキストをコピーする
- (Googleスプレッドシート)タイトル列にペーストして整形する
    - ヘッダーを用意する（#, Title, Memo）
    - 項番は行の数だけ振っておく
- (Googleスプレッドシート)Markdown に変換したい範囲を選択する
- (GenerateMarkdownTable)拡張機能から「Convert selected range to Markdown Table」を選択する
- (GenerateMarkdownTable)完成したMarkdownテキストをコピーして完成

# 対応方法の検討過程

## 対応案1

頑張って手動で作る

→いやだ

## 対応案2

（項番をふらずに）タイトルとメモだけなら GetTabInfo だけで対応できる

→やはり、項番がないと編集しづらいのでNG

[複数ページのタイトルとURLを一発取得！ Chromeの必須アドオン「GetTabInfo」 | できるネット](https://dekiru.net/article/14276/)

## 対応案3

プラグインなどを組み合わせて作る

→すぐに出来そうだし、業務でも使えそうなアドオンなので、今回はこの方法にしておく

[複数ページのタイトルとURLを一発取得！ Chromeの必須アドオン「GetTabInfo」 | できるネット](https://dekiru.net/article/14276/)

[スプレッドシートを Markdown 表形式に変換してくれるアドオン GenerateMarkdownTable が便利だ](https://zenn.dev/junki555/articles/04fcee17f1a0eb)

## 対応案4

自前でChrome拡張を作成する

→参考サイトのコードにちょっと手を加えれば実現出来そうだが、環境構築に時間がかかりそう（Chrome拡張作ったことがないので、物凄くやってみたいが、時間がある時にしよう）

[開いているウインドウの全タブのページタイトルとURLを取得するChrome拡張作った - Qiita](https://qiita.com/yukuduri/items/3f2159ab3cec95a1ba28)

[Chrome拡張の作り方 (超概要) - Qiita](https://qiita.com/RyBB/items/32b2a7b879f21b3edefc)

## 対応案5

ショートカットアプリを利用する

→ショートカットアプリの「アクティブになっているSafariのタブでJavaScriptを実行」を改変すれば作れそうだけど、サイト構成が変わったら使えなくなるし、JS得意じゃないし

[Macの「ショートカット」の「WebページでJavaScriptを実行」アクションを使う - Apple サポート (日本)](https://support.apple.com/ja-jp/guide/shortcuts-mac/apdb71a01d93/mac)

[【macショートカットアプリ】アクティブになっているSafariでJavascript - 脳無](https://irilyuu.com/mac-ios/mac/shortcut-safari-javascript/)

## 対応案6

セッションビデオ一覧をAPIで取得出来ないか確認してみる

→気が向いたらCharlesとかで確認してみよう（DeveloplerアプリはAPI使ってそう）


**さいごに**
娘が学級閉鎖なので暇つぶしに入力してます。
露出不足、露出過多、暗すぎる、明るすぎる画像をきれいにする　OpenCVってなんやかやすごい

![ダウンロード (59).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d8d312fc-69ba-c167-a368-1252ad2eed2b.png)
![ダウンロード (58).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b4701142-5a76-5339-a0df-93597f779999.png)

# 昼間の電気をつけていない室内など、画像内で明るさの差が大きい画像は、一部が明るく写りすぎたり、暗く写りすぎたりして、細部が見にくいことがあります。

# OpenCVで明るさ補正

OpenCVの補正メソッドが使えます。

```python
from __future__ import print_function
import numpy as np
import argparse
import cv2
def adjust_gamma(image, gamma=1.0):
	# build a lookup table mapping the pixel values [0, 255] to
	# their adjusted gamma values
	invGamma = 1.0 / gamma
	table = np.array([((i / 255.0) ** invGamma) * 255
		for i in np.arange(0, 256)]).astype("uint8")
	# apply gamma correction using the lookup table
	return cv2.LUT(image, table)
```


```python
img_src = cv2.imread('image.jpg', 1)
img = adjust_gamma(img_src, gamma=1.0)
```

露出過多で明るい画像を暗くすることもできます。

![people2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d93ddbc8-a274-5a52-52a5-24c36493f528.jpeg)
![ダウンロード (60).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/50cd33b9-5bd5-7c1a-73e8-e23cb51ceae1.png)


gammaを上げると明るくなり、下げると暗くなります。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
何番煎じ？ テキスト共有 Web サービスをリリースしました

## サイト

https://sharing-text.com

## 開発経緯

何番煎じかわからないけど、テキスト共有 Web サービスをリリースしました。
とにかく登録不要で期限付きのテキストページが欲しかった。
時々開発経験のない友達などから以下のような相談を受ける時がありました。
・「個人事業用の HP 作成してるんだけどこの JQuery のプラグインどうやったら動くの？」
・「こうゆうデータを取得したいんだけど、どんな SQL 書けばいいの？」
・「この処理でエラーが発生するんだけどどうすればいいの？」
同業者等なら Zoom で画面共有したり、Slack やらなんやら何かしら使っているツールでファイル共有できたりしますが、相談してくる友達などはそうゆうツール類とは無縁だし、開発ツールが Dreamweaver だったりと自分に縁のないツールを使っている状況のため、色々と不便を感じていました。
かといって、Zoom や Slack といったそうゆうツールをわざわざ入れさせて、自分の Slack のワークスペースに招待したり、されたりするのもめんどいので勧めたりはしたくありませんでした。
ただ、やはりどんなことしたいのか、どんな処理をしているのか一々ファイルをメールやらなんやらで、送ってもらったり、それを修正してまた送るのがめんどくさかった。
そんな悩みを解決するために、本サービスを作成することにしました。

## 技術スタック

- 言語: TypeScript
- フロントエンド & バックエンド: [Remix](https://remix.run/)
  - React ベースのフルスタック Web フレームワーク
  - 直近の仕事やプライベートでも SPA で開発していたが、MPA の方が今回のようなサービスを個人開発する時は楽じゃない？と思うこともあって使ってみましたが、比較的楽しく開発できて正解でした。
- インフラ: AWS
- 環境構築: Terraform
  - Remix には AWS にデプロイするために [architect/architect](https://github.com/architect/architect) を使っているのですが、構築されるリソースが個人的にアレだったので、[architect/architect](https://github.com/architect/architect) を使わずに、Terraform で構築しています。
- ライブラリ
  - [Monaco Editor](https://microsoft.github.io/monaco-editor/)
    - ハイライトや比較/差分表示機能が欲しかったので、オーバースペック気味ではあるがこちらのエディターを採用しました。
    - モバイルブラウザなどはサポートされていないとのこと。
  - [Chakra UI](https://chakra-ui.com/)

## 機能

- 言語指定
  - エディターに monaco-editor を使ってるので、取り敢えずそれがサポートしている言語全て選択可能にしてます。
- 有効期限設定(日単位 or 時単位 or 分単位)
  - 日単位: 直近 1 ヶ月分の日にちを選択できます
  - 時単位: 1 ~ 24 時間後を選択できます
  - 分単位: 5 ~ 60 の範囲で 5 分単位できます
- 比較/差分表示
  - 比較しながら修正したかったのもあって、個人的に地味に気にいっている機能。
  - 仕事で似たようなサービスに課題が記載されて、答えを書いていたときに元の課題見ながらできたらいいなと思ったのがきっかけ。
  - 個人的に問題とかを複数人に共有して、解答者は新規作成(コピー)してリンクを提出してもらうというのをやってみた際にもこの機能は便利だった。
- ファイルダウンロード
- コピー(URL or 本文 or 有効期限)

### 新規作成画面

![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150875/aba638bb-3cbf-d8f1-0cb4-5fc95e557ce6.png)

### 閲覧画面

![view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150875/09ce3620-9ee1-34ee-26aa-c5f4d9ab9620.png)

### 新規作成(コピー)画面

コピー元のテキストを参照しながら新規作成が可能です。
比較/差分自体はデフォルトでオフになっています。
また、画面下部の警告にあるように、この新規作成(コピー)機能を使って新規作成した場合、閲覧画面でコピー元のデータを参照することができます。
もし、コピー元のデータを参照・維持させる必要がない場合は、チェックボックスにチェックを入れる必要があります。

![copy_and_create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150875/9877d8ad-cbed-476e-04e4-adb8491777ed.png)


### 閲覧画面(新規作成(コピー)で作成した場合)

![copy_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150875/fae57b34-e3f5-c5e9-aecd-b0f067abfd6d.png)

## まとめ

仕事柄今はプロダクト開発をしてませんが、改めて開発の楽しさを実感できました。
今回採用した Remix や Chakra UI が使いやすくてこれらを使って開発できただけでも満足でした。
【VSCode】C++の開発環境構築

Windows端末のVSCodeでC++の開発環境を構築する

# Visual Studio Codeのダウンロード

下記サイトからVSCodeをダウンロードする

https://code.visualstudio.com/

# MinGWのインストール

下記サイトからMinGWをダウンロードする

https://osdn.net/projects/mingw/

ダウンロードが終わったら、MinGW のインストールを開始する

インストールが完了するとインストール管理画面が表示される

「mingw32-base-bin」と「mingw32-gcc-g++-bin」をクリックして「Mark for Installation」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/8cf77b93-da72-7bd1-d1ac-60278af2a8b3.png)

左上のメニューから「InStallation > Apply Changes」を選択してパッケージをダウンロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/e4d2dbf6-221c-378d-fb9c-0862f5a90eb9.png)

# C++コンパイラのパスを通す

環境変数に`C:\MinGW\bin`を追加する

# VSCodeの実行環境構築

拡張機能「C/C++ for Visual Studio Code」をインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/3d436609-19f3-9ac2-a019-6182b83d84a8.png)

適当にフォルダを作成してVSCodeで開く

## InteliSense設定

「F1」を押して「C/C++ edit UI」と入力して「C/C++：構成の編集（UI）」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/070f99a4-0468-75e3-4d1d-6f066814d3d1.png)

「構成名」に「MinGW」と入力して「構成の追加」をクリック

コンパイラパスには「C:\MinGW\bin\gcc.exe」を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/2ebfcc9c-6d33-4fcf-eefb-69dae9fb0d65.png)

Intelisenseモードは「windows-gcc-x64」を選択

「パスを含める」に「C:\MinGW\include」を追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/521fefd4-ebc1-af0e-3644-574e23569fe4.png)

# Build実行

「test.cpp」を作成し「Hello world.」を表示するプログラムを書く

```cpp
#include <iostream>

using namespace std;

int main(){
  cout << "Hello world." << endl;
  return 0;
}
```
「F1」を押して「>C/C++ run C/C++ File」を入力して「ファイルの実行」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/55cc5e89-4d57-e455-6dc8-59c230ede8d6.png)

「アクティブファイルのビルドとデバッグ」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/a2940b5f-6dd4-1624-9db8-dca41f0ae2af.png)

コンソールに「Hello world.」が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/94d1fc00-f451-5fcd-d94d-27709e7af092.png)
【Virtual Box】VM間での接続(NATネットワーク)


以前、VirtualBoxにCentOSを導入しました。
ネットワークの設定はNATで設定しており、ホストOSからゲストOSにSSH接続するまでを行いました。

[VirtualBoxでCentOS7.9導入＆ssh接続までを行ってみた(NAT接続)](https://qiita.com/hitorigotsu/items/881432da88599691d53d)

今回はゲストOS間での接続を行います。

まず、VirtualBoxの設定です。
「ファイル」→「環境設定」→「ネットワーク」をクリックします。
＋マークを押すと、「NatNetwork」が作成されます。
「NatNetwork」をクリックし、設定内容の確認を行います。
今回IPの振り分けを自動で行いたかったので、DHCPのサポートにチェックを入れます。

※NATはホストOSとゲストOS間で接続を行えましたが、ゲストOS間での接続は行えません。NATネットワークは複数の仮想マシンが同一のネットワークに繋がっています。ゲストOS間での接続が行えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/f7a64ac5-e1ce-fe14-ac7b-b37df95f4a60.png)

VMの設定を行います。
割り当てを「NATネットワーク」に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/e47c6883-9bf1-6d0c-069e-e3f3b3fbaa67.png)

上記設定で疎通できると思います。

短いですが、以上です。
100日後くらいに個人開発するぞ！day051

## 今日はクラスとインスタンスを学んでみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/aebc7b0f-72df-b942-24af-ad4b602d2c8f.png)


## 今日の学び
### クラス
* プログラムの設計図をクラス、生成されるものをインスタンスという
* インスタンスを生成するステップ
    * クラス（設計図）を用意する
    * クラスからインスタンスを生成する
    * インスタンスに情報を追加する
* クラスは「class クラス名」で定義できる
    * クラス名は必ず大文字で始める
    * 「end」を書く必要がある



### インスタンス変数
* クラスのインスタンスの変数をインスタンス変数という
    * 例：Menuクラスにnameというインスタンス変数を設定する場合
        * `class Menu`
        * ` attr_accessor :name`
        * `end`
* 1つのクラスに対して複数のインスタンス変数を用意できる
    * 例
        * `class Menu`
        * ` attr_accessor :name`
        * ` attr_accessor :price`
        * `end`

### インスタンス
* 新しくインスタンスを作成するには「クラス名.new」とする
* 「変数名＝クラス名.new」とすることで生成したインスタンスを変数に代入することができまる
*「インスタンス.変数名＝値」とすることでインスタンス変数に値を代入することできる
STM32L010を使い1から4096を文字列に変換 例intの1234を文字列の「1234」(改)

x Mbed2
x 軽量高速化

目的
シリアルのテスト
10進数変換のテスト

![o_con560.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/25b2762c-2c55-a2c3-8be1-5a72cd152e16.jpeg)



計算式


```

256
512
1024 10
2048 11
4096 12
8192

 12345678
.10011001 (0.6...)
 10011001 (153)
 10011010 (154)

(1) (10*409.6)/4096=1

(1) 10*409.6=4096
(2)          4096/4096=1

(1) 10*409     =4090
(2) 10*154/256 =   6.015
(3)             4096/4096=1


(1) 4096*409     = 1675264
(2) 4096*154/256 =    2464
(3)                1677728/4096=409.6015625


(1) 9999*409     = 4089591‬
(2) 9999*154/256 =    6015
(3)                4095606/4096=999.9038


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)


//10の割り算 0から9999までは、正しい。
#define DIV10(n) (((n*409)+((n*154)>>8))>>12)




```


プログラム



```c++



//B0_4096_2

#include "mbed.h"

RawSerial pc(PA_2, PA_3); //010

//10の割り算 0から9999までは、正しい。
#define DIV10(n) (((n*409)+((n*154)>>8))>>12)

int main() {

    int d;
    char data[15];

    pc.printf("START\r\n");

    while(1){

        d=1234;

        data[4] = 0;
        data[3] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        d = DIV10(d);
        data[2] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        d = DIV10(d);
        data[1] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        data[0] = '0' +  DIV10(d);                  // '0'+(d/10)

        pc.printf(data);
        pc.printf("\r\n");
        wait_ms(1000);

    }//while

}//main




```


https://paiza.io/ja/projects/new?language=c


テストプログラム


```c++



//10の割り算 0から9999までは、正しい。
#define DIV10(n) (((n*409)+((n*154)>>8))>>12)

#include <stdio.h>
int main(void){

    int n01 =  0;

    for(int ii = 5000;ii <= 10000;ii++ ){
        
        printf("[%d]=",ii);
        n01=DIV10(ii);
        //n01=((ii*409)+((ii*154)>>8))>>12;
        //n01=0;
        printf("[%d]\r\n",n01);
        if(n01 != (ii/10) ) break;
        
    }//for


    
}



```