OmniAICreator/Qiita-1.07M huggingface dataset:
【合格体験記】Google Cloud Digital Leader

## はじめに

本日Google Cloud Digital Leaderの2回目を受験して結果画面に合格と表示されたため、
体験記を残します。

## 前提知識
 - モバイルエンジニア5年目。普段はGoogleCloud/AWSを少し触る程度。
 - 2021年9月AWS CLF合格
 - 2022年2月AWS SAA合格

## 勉強時間など
約50時間くらい

2022年7月1日：勉強開始
2022年7月17日：受験 -> `不合格`（点数は不明）

-- 少し勉強休憩(1回目不合格の後再受験までは2週間の間隔が必要[※ 再受験ポリシー](https://support.google.com/cloud-certification/answer/9749448?hl=ja)) --

2022年9月11日：勉強再開
2022年9月23日：合格 

平日業務後約1時間、休日4時間程で詰め込みました。

![スクリーンショット 2022-09-26 10.16.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410187/ee67cee0-069d-87ec-f6ec-6d45b7871f11.png)

## おすすめ勉強ロードマップ

AWS試験であれば豊富な試験問題のサイトが準備されているため、ある程度試験対策が行えました。
Google Cloudに関してはAWSでいう[CloudTechさん](https://kws-cloud-tech.com/)のような日本語での充実した対策サイトは多く無い印象でした。
ただ、公式サイトが勉強資材を準備してくれているので、それを補助資料として進めると良いと思います。

試験自体は1度目不合格のため、過去受けた問題の対策がしやすかったというのも合格の要因かもしれません。
あくまでもご参考まで。


### 1. 参考書を読む

https://www.amazon.co.jp/dp/4297123010/ref=cm_sw_r_tw_dp_AV7H85MSHWK1YG3K5595?_encoding=UTF8&psc=1

本書で全てを網羅できる訳ではないですが、全体的な用語を理解するためにはこの本がオススメです。
私はAWSSAAを持っていたので、AWSだと対応するシステムはなんだろうとイメージしながら進めると定着しやすかったです。

1周ほどざっと読んで一旦終了。

### 2. 公式の試験ガイドを見る。

https://cloud.google.com/certification/guides/cloud-digital-leader

試験の出題者が「こういう範囲の問題出すよ」って言ってくれているので目は通しておきましょう。
ひとまず、出題範囲の感覚をつかむ程度で十分です。

### 3. 試験問題を解いてみる。

#### 3-1 模擬試験

まず、公式試験は必ず解いておきましょう。
公式から模擬試験を無料で受けられるので是非とも受けておきたいです。
ただ、問題数は20問程なので、ボリュームは少なめです。

https://docs.google.com/forms/d/e/1FAIpQLSdyQtCFqpNSlv8xJwc8goExJOzSAKxiWW2BoVhO1QWRUEUuKA/viewform?hl=ja



#### 3-2 試験問題集で演習を実施

正誤が怪しそうな問題がたまに見受けられる為、あくまでも参考程度に見た方が良いですが、
チラホラ本番とほぼ一緒の問題もあるので解いてみる価値はあると思います。

https://www.jpnshiken.com/exam/Cloud-Digital-Leader-JPN-google-cloud-digital-leader-cloud-digital-leader%e6%97%a5%e6%9c%ac%e8%aa%9e%e7%89%88-13864.html#


#### 3-3 公式学習プラグラムより試験問題を実施。

公式より学習プログラムが準備されています。
それぞれの章末問題が準備されていたので、時間短縮のためにその問題をメインに解いていました。

https://cloud.google.com/certification/cloud-digital-leader?hl=ja


こんな感じです
![スクリーンショット 2022-09-23 22.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410187/b94e4e55-7f66-8351-7f89-311ec45d6e39.png)

基本英語ですが、以下の方の記事を参考にすれば進めることはできると思います。

https://qiita.com/wuyiniaoniao/items/0a54e5b659ebbd550d08#%E5%AD%A6%E7%BF%92%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88


#### 3-4 Udemy（これはどちらでも…）

試験問題対策としてUdemyを探して、以下を購入してみました。

https://www.udemy.com/share/105fdg3@DuxLOV8zip0FdhekFJ8_GERLfczzQUG6-6Ds0DpEHhL6QpX1VMH0xReBU_NyHCui/

問題数が多いのはメリットなのですが、少し内容が細かすぎて試験範囲外の部分も含まれている気がするので、あくまでも補助教材として進めると良いと思います。
「**初試験に不安である程度問題はこなしておきたい**」「**試験に限らず網羅的に知識を吸収しておきたい**」といった思いがあれば購入をオススメします。

私は購入したものの、とりあえず答えだけ見てざっと流し読みした程度で使いました。

### 4. 理解できるまで繰り返し演習&復習

## 曖昧な理解だった問題
本番のテストや、よく対策問題を解く中で少し苦しんだ問題や観点等を抜粋しておきます。
 - 99.999%の可用性での年間ダウンタイム（A.約5分）
 - データウェアハウスとデータレイクの違い
 - 構造化データと非構造化データの違い
 - AutoMLVisionとVisionAPIの違い
 - Bigtableとspannerの違い
 - クラウドモニタリング/トレース/デバッガの違い
 - DataprocとDataprepの違い
 - グリーンフィールド/ブラウンフィールドの違い
 - DirectPeeringとCloudVPNの違い
 - CapEx(資本的支出)とOpEx(経費的支出)の違い
 - エラーバジェットの指標とは

## まとめ
試験対策をどうするのがベストか分からず、私の勉強方法も非効率だった可能性があります…。

勉強する方の前提知識で対策方法は変わるかもしれませんので、Udemy受講は人によってはコスパが悪いかもしれません。
ただ、難易度激ムズの試験でも無いので、ちゃんと対策して受験すれば必ず受かることが可能な試験だと思います。


合格に向けて頑張りましょう！
setIntervalで指定した時間に文字を表示して音を鳴らす方法


## 秒数を計算し表示させる
setIntervalで指定した時間に文字とHTMLのaudioタグで指定した音声ファイルを使って音を出す方法を紹介します
今回のコードではカウントダウンさせています

```javascript:timer
//連想配列で指定したい秒数と表示したい文字を記述する
$(function () {
      var timer = {
        40: "残り40秒です",
        20: "残り20秒です",
        10: "残り10秒です"
      };
```


```javascript:timer
          //60秒からカウントダウンをはじめる
          var sec = 60;
```

```javascript:timer
var timer1;
        timer1 = setInterval(function () {
          //secをマイナス１秒させる
          sec -= 1;
          //　Mathでsec÷60（1分=60秒）して分を計算する
          //  floorで端数を切り捨てる
          var min = Math.floor(sec / 60);
          // Mathでsec÷60...余り（1分=60秒）して秒を計算する
          //  floorで端数を切り捨てる
          var rem = Math.floor(sec % 60);

          //　■ 秒数に0を付けたい時
          //  remが9以下の時:(rem > 9) ?
          //  9以下ならremを表示してそうじゃなければ'0'をつけて表示
          var i = (rem > 9) ? rem : '0' + rem;
          //HTMLで表示したい場所:$('.clock')に
          //min(分) + ":" + iで分と秒が表示される
          $('.clock').html(min + ":" + i);
          $('.timer').html(timer);
```

## 音声ファイルをplayさせる秒数を設定する
```javascript:timer

 switch (sec) {
            case 40:
              $("#audio1").get(0).play();
              console.log($("#audio1").prop("volume"));
              break;
            case 20:
              $("#audio2").get(0).play();
              break;
            case 10:
              $("#audio3").get(0).play();
              break;
          }
```
## タイマーを停止させる

clearIntervalでタイマーを停止させる
0秒以下の時タイマーが止まるように指定しました
```javascript:timer
if (sec <= 0) {
            clearInterval(timer1);
          }
     //1000ミリ秒（1秒）ごとにこの動作を繰り返す
        }, 1000);
      });
    });
```
リーダブルコードまとめ(第7章:制御フローを読みやすくする)

# 第7章:制御フローを読みやすくする
## 概要
本章では、条件やループなどのループなどが無いコードは読みやすいと言うことを前提に、コードの制御フローを読みやすくすることについて説明している。

### まとめ
「if文で比較をする際、変化する値は左側に、より安定した値は右側に書く。」「if/elseはブロックを適切に並び変える。一般的には、肯定文・単純・目立つものを先に処理する。」「三項演算子・do/whileループ・gotoなどはあまり使わないようにする。」「ネストは浅くする。」「関数は早めに返す。」これらが本章では大事であると解説していた。

### 学んだ点
・条件やループなどの制御フローはできるだけ「自然」にして、読み手が立ち止まったり読み返したりしなくていいように記述する。
・条件式（if文等）は左側に「調査対象」の式で変化するものを右側に「比較対象」の式を記述する。
・条件には、否定形よりも肯定形を使うようにして、単純な条件を先に記述する。ifとelseが同じ画面で見られるようにする。
・関心を引く条件や目立つ条件を先に書く。
・関数の中でreturnを使ってできる限り関数の処理から早く返すようにする。
・Ｃ言語等？では、gotoは使わないようにする。
・ネストの深いコードは読みにくいので、できる限りネストは浅くして理解しやすいコードにする。
・変更するときには、コードを新鮮な目で見て、一歩下がって全体を読む。
・関数を早めに返すことで、ネストを削除したりコードをクリーンにしたりできる。特に「ガード節」（関数の上部で単純な条件を先に処理できる）が便利である。

### 感想と振り返り
制御フローのレビューを出した際に、if elseで条件を増やして文章を増やすのか「!=」で条件文を短くするかで少し議論になった覚えがあります。こちらに関しても、プロジェクトやその文が書かれている状況によって書き方があると思うので、レビューをしていただく方と審議する必要があると思います！
自分的には、この審議するということで他の方のコードの書き方や癖であったり、どの書き方が一番ベターかなども勉強することができたのでコードを書く際の考え方の幅が広くなる良い機会になりました！
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript 座標圧縮

座標圧縮 (paizaランク B 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_speedup_step9

JavaScriptで解いてみました。

# 解答例(単純に探索する)

色を塗ったマスが左から何番目かわかりやすいように、Aを昇順にソートする。


数列Xの質問に答えていく時、単純に「数列`A`の中から、`X[i]`を探して、出力する」を繰り返す。時間はかかるが時間内に処理がされる。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//N 個のマスに色を塗る, 全部で Q 回行われる質問
const [N, Q] = lines[0].split(" ").map(Number);
//色を塗ったマス番号の数列 A
const A = lines[1].split(" ").map(Number);
//質問の数列 X, X_iは色が塗られているマスの何番目か知りたい
const X = lines[2].split(" ").map(Number);

//数列Aを昇順に並べ替える
A.sort((a, b) => a - b);

//数列Xの質問に答えていく
for (let i = 0; i < Q; i++) {
    console.log(A.indexOf(X[i]) + 1);
}
```

# 解答例(辞書を使う)
条件より、`Aの要素数 1 ≦ N ≦ 100,000, Xの要素数 1 ≦ Q ≦ 100,000`なので、計算量が多くなり、多少時間がかかる。

辞書を使って、処理時間を短縮してみた。

辞書に登録するときは、キーを"マスの番号"、値を"左から数えて何番目か"、にする。
すると、数列Xの質問に答えていくとき、"マスの番号"から、一発で答え"左から数えて何番目か"がわかる。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//N 個のマスに色を塗る, 全部で Q 回行われる質問
const [N, Q] = lines[0].split(" ").map(Number);
//色を塗ったマス番号の数列 A
const A = lines[1].split(" ").map(Number);
//質問の数列 X, X_iは色が塗られているマスの何番目か知りたい
const X = lines[2].split(" ").map(Number);

//数列Aを昇順に並べ替える
A.sort((a, b) => a - b);

//辞書に登録していく
let compressed = new Map();
for (let i = 0; i < N; i++) {
    //キーをマスの番号、値を左から数えて何番目か、にする
    compressed.set(A[i], i + 1);
}

//数列Xの質問に答える
for (let i = 0; i < Q; i++) {
    //左から X_i 番目のマスは色が塗られているマスのうち左から何番目のマスか出力
    console.log(compressed.get(X[i]));
}
```
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript Top - k (hard)

Top - k (hard) (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_speedup_step0

JavaScriptで解いてみました。
 a の k_i 番目に大きい値を、その都度、数列aの中から探していると時間がかかります。
先に数列`a`を大きい順に並べ替えると、`a` の k_i 番目に大きい値は`a[k_i - 1]`で、一発で求まります。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n, q 
const [n, q] = lines[0].split(" ").map(Number);
//数列 a
const a = lines[1].split(" ").map(Number);
//数列 k
const k = lines[2].split(" ").map(Number);

//aを降順にソート
a.sort((a, b) => b - a);

//1 以上 q 以下の各 i について、 
for (let i = 0; i < q; i++) {
    //a の k_i 番目に大きい値をそれぞれ求め、改行区切りで出力
    console.log(a[k[i] - 1]);
}
```
(Ubuntu-20.04)WSL2でping google.comが通らなかった経緯と解決策

## 環境
* windows11
* wsl2
## ubuntuのインストール
```bash
$ wsl --install -d  Ubuntu-22.04
```

## インストールされていることを確認
```powershell
wsl -l -v
  NAME            STATE           VERSION
* Ubuntu          Running         2
  Ubuntu-22.04    Running         2
```



## ubuntuの起動
```
wsl -d Ubuntu-22.04
```

## pignが通らない

```bash
$ ping www.google.com
ping: www.google.com: Temporary failure in name resolution
```

## 原因
DNSサーバーの設定ができていない模様

## 対策
* /etc/wsl.confにresolv.confを再生成しないよう記述
```bash
# /etc/wsl.conf
[network]
generateResolvConf = false
```
* /etc/resolv.confにnameserverを指定
```bash
# /etc/resolv.conf
nameserver 8.8.8.8
```
* このままだとwsl起動するたびに上で作ったresolv.confが削除されるので、ファイルの属性を変更
```bash
$ sudo chattr +i /etc/resolv.conf
```

## 結果 
通りました！
```bash
$ ping google.com
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
```

## 参考文献
[WSL2でresolv.confが消える問題の解決方法](https://zenn.dev/frog/articles/9ae2428be2825a)

[【chattr】ファイルの属性を変更する](https://xtech.nikkei.com/it/article/COLUMN/20140115/529923/)
UnityPackageManagerの埋め込みパッケージでcsprojを作成する

## 背景
dotnet formatで整形するためにcsprojを生成したかった。
Assets下のスクリプトは勝手に生成してくれるけどPackage下は生成してくれない。
カスタムパッケージの[ドキュメント]にはなかった。

## やり方

![スクリーンショット 2022-09-23 22.20.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/5e9feac2-a7b1-e1d7-cde6-bdd04b96cd0a.png)

External Toolsにいた。
Embedded packagesにチェックしてRegenerateで生成された。
リーダブルコードまとめ(第6章:コメントは正確で簡潔に)

# 第6章:コメントは正確で簡潔に
## 概要
前章では、コメントで書く内容の部分に関して解説していたが、本章ではその内容をどのように書くべきかという点を解説してくれている。

### まとめ
小さな領域にできるだけ情報量を詰め込み、簡潔に正確にコメントをするためのコツを説明していた。

### 学んだ点
・コメントは領域に対する情報の比率が高くなければならない。要するに、画面にコメントの領域を取られるため正確かつ簡潔なものでなければならない。
・「その」「あの」のような曖昧な代名詞を使用しないようにする。
・あいまいな代名詞を避ける。
・歯切れの悪い文章を変更する。例えば、「優先度を変える」よりも「優先度を高める」の方が何をどうするといったように意図がわかりやすい。
・コードの動作をそのまま書くのではなく、そのコードを書いた意図を記しておく。
・情報密度の高い言葉を使う。
・コメント後長くてくどいと感じたら、短縮して意図が伝わるか考えてコメントを編集する。要するに、多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ。

### 感想と振り返り
そもそも、普段開発に関わる際にコメントを使用する習慣がなかったので、これを機に適切にコメントを付けられるように試行錯誤したいと思った。また、その際はこの章で解説してくれていた通り無駄のない簡潔で正確なコメントを書けるように心がけたいですね！既存のコメントにも目を向けていきます！
AWS CDK Merit Badgesってなに？

# はじめに

表題の通り、CDKのアップデートで`AWS CDK Merit Badges`が採用されたようです。
何だろう、ということで簡単にまとめてみた。

※2022/09/23時点の情報です。

## 読んでみる

- 原文はこちら

https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#badges-pilot-program

大体ニュアンスはわかりますが、念のためGoogle翻訳してみましょう。

```text
CDK Merit Badges はパイロット プログラムです。取得するバッジは実験的なものであり、変更される可能性があります。

CDK Merit Badges は、CDK コントリビューターのエクスペリエンスを向上させることを目的としたプログラムです。CDK リポジトリに新しいプル リクエストを送信すると、リポジトリへの以前の成功した貢献の数を反映するメリット バッジを受け取ります。現在、これらのバッジは楽しみのためのものであり、CDK への継続的な貢献へのささやかなインセンティブを目的としています。

バッジには次の意味があります。

beginning-contributor: CDK に 0 ～ 2 件の PR を提供
repeat-contributor: CDK に 3 ～ 5 件の PR を提供
valued-contributor: CDK に 6 ～ 12 の PR を提供
admired-contributor: CDK に 13 ～ 24 の PR を提供
star-contributor: CDK に 25 ～ 49 件の PR を提供
distinguished-contributor: CDK に 50 件以上の PR を提供
```

ほえ～。ちなみにPR≒コミット数という雑すぎる仮定で、50以上はContributerの23人/1051人のようです。
https://github.com/aws/aws-cdk/graphs/contributors

## 何がうれしい？

基本的にはメリットがあるわけではなく、お楽しみ機能の様子。ステッカーとかもらえたら嬉しいね。
gamificationすると楽しいし、レビュワーもPRがどんな属性から来たかわかりやすくなる、という事情もありそう。

## ちなみに

いま3つほどPRが溜まっているのだが、CDK Merit Badgesは付与されていないので、本機能適用後のPRに付与されると想定される。

気になったので私もPRしてみると……？

![cdk-badge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/d67a96a1-a17f-4045-57c9-7e0b3b3cc865.jpeg)
![cdk-badge2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/21243c5a-3fb2-a88b-8695-f68a7ed9e62c.jpeg)

`admired-contributor`が付与されていました。

ちなみに今回のPRでランクが上がった模様。なんか申し訳ない。

## 後日談

https://github.com/aws/aws-cdk/pull/22209#issuecomment-1256297294

カウントの対象となるPR数は当然Mergedが対象なのだけど、バグって全部カウントされていた様子。
※つまり実際は`valued-contributor`でした:)

## まとめ
ということで、突然加わったCDK Merit Badgesプログラム。
気軽にPRしようぜ！というCDKチームからのメッセージだと思うので(個人の見解です)、みなさんも軽率に始めちゃっていいと思います。
【Eclipse】「色テーマ」設定の追加と設定方法

## 環境
Eclipse IDE for Java Developers 2022-09 (4.25.0)

## はじめに
以下のような「設定 > 一般 > 外観 > **色テーマ**」の設定を追加する方法とその設定方法を紹介する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/80c5fe0a-7487-d94c-fcca-1bdf1a7d9d26.png)

## Eclipse Color Theme のインストール手順
「ヘルプ > 新規ソフトウェアをインストール」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/44386c49-2bda-439c-c54b-baf8c83e0062.png)

「作業対象」に `http://eclipse-color-theme.github.io/update/` を入力し「追加」をクリック。「リポジトリーの追加」のダイアログが出たらそのまま「OK」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/765ee06d-b5cd-dcd8-e323-2e3d601146d7.png)

Eclipse Color Theme が表示されたらチェックを入れて「次へ」をクリック。警告が出てもそのまま進む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/7119fb54-0540-3f05-d485-12edf982efe8.png)

これで「色テーマ」設定が追加された。

## 色テーマの設定手順
「ウィンドウ > 設定 > 一般 > 外観 > 色テーマ」で好きなテーマを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/e4140227-9e41-e22e-0be7-ae78e710d909.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/1c4ad129-8e88-0877-a4cd-36212f592b5e.png)

## 参考

https://wp.tech-style.info/archives/170

https://qiita.com/rin-bamboo/questions/a02b67d651a9aa526824
【bootstrap v5.x】UtilityAPIを使ってクラス定義を変更しようとしたらハマった話

Bootstrap5.x には[UtilityAPI](https://getbootstrap.jp/docs/5.0/utilities/api/)という仕組みがあるのですが、これを活用して生成されるクラスに手を入れようとしたらうまくいかずにハマりました。

## やろうとしたこと

[Sizing](https://getbootstrap.jp/docs/5.0/utilities/sizing/)カテゴリに属する width/height を[Grid](https://getbootstrap.com/docs/5.1/layout/grid/#grid-options)よろしくレスポンシブに出来ないかな～と思い、手を付けたのが発端でした。

コードは後述しますが、意図通りに動作すれば元々ある`w-25`や`w-50`、`w-auto`といったクラスの他に、`w-sm-25`、`w-md-25` 、`w-lg-25`のような規則のクラスが誕生するはずでした…が、うまくいかず。

## 失敗例

[デフォルトの定義をそのまま流用しつつ、一部分を改変できるサンプル](https://getbootstrap.jp/docs/5.0/utilities/api/#modify-utilities)があったので、これを参考に scss を書いてみます。

```scss:App.scss
// このファイルはReactを使ったフロントアプリの一部からimportされていますが、
// この記事とは関係ない部分なので省きます

@import "bootstrap/scss/bootstrap";
@import "scss/utilities";
```

```scss:scss/utilities.scss
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
// ↓のimportも必要（utilitiesが依存してるので）
@import "bootstrap/scss/maps";
@import "bootstrap/scss/utilities";

$utilities: map-merge(
    $utilities,
    (
      "width": map-merge(
          map-get($utilities, "width"),
          (responsive: true)
      )
    )
);
```

生成された css を見ても`w-sm-25`みたいなのは見当たらず。

## 成功例

`App.scss`に記載していた import の順番を逆にした所、意図通りにクラスが生成されました。
bootstrap 本体の import よりも先に $utilities に対しての変更を行う必要があったようです。

```diff_scss:App.scss
// このファイルはReactを使ったフロントアプリからimportされていますが、
// 記事とは関係ない部分なので省きます

+ @import "scss/utilities";
@import "bootstrap/scss/bootstrap";
- @import "scss/utilities";
```

## なんでや

今回の例では下記のような形で bootstrap 本体を import しています。
じつは、この中にヒントがありました。

```scss
@import "bootstrap/scss/bootstrap";
```

上記の[ソース](https://github.com/twbs/bootstrap/blob/main/scss/bootstrap.scss)を見てみると、ファイルの末尾で **"utilities/api"** を import しています。
この **"utilities/api"** は、bootstrap にて定義された $utilities 等の変数から実際に CSS クラスを生成する役割を持っているようです。

生成処理が実行されるタイミングは"utilities/api"が import されたタイミング（≒bootstrap 本体が import されたタイミング）なので、これよりも後に加えられた変更は生成された CSS クラス群には反映されないようです。
改めて失敗例を見てみると、 "utilities/api" の import よりも後に変更を行っており、まさしく前述の通りのパターンになっていました。変更が反映されなかったのも当然の帰結…

## 所感

bootstrapなんもわからん。
あと、元々あったクラスと生成されたクラスの中身に差がなくて泣いた

## 参考

- [Grid system](https://getbootstrap.com/docs/5.1/layout/grid/)
- [Utility API (ユーティリティAPI)](https://getbootstrap.jp/docs/5.0/utilities/api/)
- [bootstrap(GitHub)](https://github.com/twbs/bootstrap)
WSL2のsystemd組み込み

WSL2のsystemd組み込みしたらしい

https://forest.watch.impress.co.jp/docs/news/1441775.html

バージョン見てみると対応「0.67.6.0」しているようなのでコンフィグおいて
再起動してみます

```bash
$ wsl.exe --version
WSL バージョン: 0.67.6.0
カーネル バージョン: 5.15.62.1
WSLg バージョン: 1.0.44
MSRDC バージョン: 1.2.3401
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.25206.1000
$ cat /etc/wsl.conf
[boot]
systemd=true
$
$ ps -aef | grep systemd
root           1       0  0 21:38 ?        00:00:00 /lib/systemd/systemd --unit=graphical.target
root          26       1  0 21:38 ?        00:00:00 /usr/lib/systemd/systemd-journald
dbus          32       1  0 21:38 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
alice        558      68  0 21:45 pts/1    00:00:00 grep --color=auto systemd
```

おお

ストアにはいるけど、`wsl.exe --list --online`には出てこないalmalinuxというのを使っていますがちゃんと動くようです。GUIなchromeとかは動きますね、、

環境はWindows11のinsiderです。

感想
こんなんdaemonizeで実現できるんだからどうでもいい！、windows10通常のpodman動くようにしてほしいが
rhel系のバグなのかなぁ、、、
C/C++ アプリを WASI で WasmEdge で動かすメモ

WebAssemblyランタイム比較(Lucet, Wasmer, Wasmtime)
https://zenn.dev/zaki_yama/scraps/cd40f7535b3224

wasi-sdk + wasmer-python で C/C++ アプリを WASM でポータブルに動かすメモ
https://qiita.com/syoyo/items/300d4ef7fd105e69ad10

WASI で動かすのは wasmer, wasmtime が主にありましたが,
最近(2022/09 時点), WasmEdge というのも出てきました.
AOT(Ahead of time) compile で高速実行目指す?っぽい.
C/C++ アプリを速度落とさずのサンドボックス実行できそうな気がしますので試してみます.


* wasmer(C/C++ をポータブルなプラグインにして Python で呼んだりしたいときとか)
* wasmtime : 最近(2022/09) 1.0 リリースされてセキュリティ的に安心して使いたいとき用?
* WasmEdge : C/C++ アプリを限りなく爆速で sandbox(isolation)実行したいとき用?

という感じの棲み分けになるのでしょうか... 

## SIMD, thread

wasmtime とかと違い?(一応 wasmtime とかでもサポートされているようではあるが...) 
SIMD, thread が使えます.

https://wasmedge.org/book/en/features/proposals.html

ただどれだけセキュアに使えるかどうかは不明です.

## TinyGLTF を動かす.

https://wasmedge.org/book/en/quick_start/use_docker.html


TinyGLTF を試してみます. thread や SIMD は使っていません.

https://github.com/syoyo/tinygltf/tree/master/wasm

まず wasi-sdk あたりで `.wasm` 作っておきます.

その後, `wasmedgec` で `.wasm` を AOT コンパイルします(数分くらいかかりました)

```
$ wasmedgec loader_example.wasm loader_example.aot.wasm
```

あとは実行するだけです!

`--dir` でファイルアクセスを許可するフォルダを指定します. `../` など親フォルダはダメでしたので, カレントディレクトリあたりにファイルを置いておきましょう.

```
$ wasmedge --dir . loader_example.aot.wasm Cube.gltf
Reading ASCII glTF
=== Dump glTF ===
asset.copyright          : 
asset.generator          : VKTS glTF 2.0 exporter
asset.version            : 2.0
asset.minVersion         : 

=== Dump scene ===
defaultScene: 0
scenes(items=1)
.. 
```

Voila!

## thread 対応

https://github.com/WasmEdge/WasmEdge/issues/1467

https://github.com/WasmEdge/WasmEdge/tree/master/examples/capi/mandelbrot-set-in-threads

https://qiita.com/syoyo/items/f14bf74c1eb26fb8b9aa

WASM 自体では C/C++ のネイティブな Thread 対応は現状(2022/09 時点)無理です.
現状ですと C から JS レイヤーで Worker を建てる感じでの対応になっています.

## SIMD

実行側で SIMD 機能のある CPU が必要になりそうな予感...?
あと, WASM SIMD は iOS Safari では対応していませんので, 同じ WASM バイナリをブラウザで動かしたいときなどは SIMD on/off でコンパイルし直しが必要になります.

## TODO

* WasmEdge の thread API を試してみる.
画像生成AIサービスを整理してみた

AIを利用したサービスは技術は具体的な仕組みの話が多く専門家以外はなかなか理解しにくいところもあるため、一般利用できる画像生成ツールに関して自分用に整理します。

## 画像生成AIとは
入力されたテキストをAIが解釈して新しい画像を作成したり、既存の画像や動画の画風を異なる画風に変更するような技術を指し、一般向けに公開されているツールもある。これにより、今までデザイナーではなかった人も望む画像を作成できるようになった。

## ツール一覧


| ツール | 利用方法|アカウント登録|準備 | 課金 |商用利用|
|:-----------:|:------------:|:------------:|:------------:|:------------:|:------------:|
|  [Stable Diffusion](https://github.com/CompVis/stable-diffusion "Stable Diffusion")       | オープンソース|必要|必要        | -         | ○|
| [DALL・E 2](https://openai.com/dall-e-2/ "DALL・E 2")     | ブラウザ|必要| -      | -       | ○|
| [Midjourney](https://www.midjourney.com/home/ "Midjourney")       | Discord|必要| 必要        |無料版は利用上限あり  | 有償のみ可|
|  [Imagen](https://imagen.research.google/ "Imagen")                 | 利用不可| 利用不可| 利用不可         | 利用不可           |利用不可 |
|  [Craiyon](https://www.craiyon.com/ "Craiyon")                | ブラウザ         | -| -         |-            |× |


## 各ツールについて
### stable Diffusion
Stability AIが開発したオープンソース。オープンソースのため、セットアップを行えば実機でも利用でき、商用利用も可能。[Linna社](https://rinna.co.jp/)より日本語版も公開されている（[GitHub - Colaboratory](https://github.com/kaz12tech/ai_demos/blob/main/StableDiffusion_demo_jp.ipynb  "GitHub - Colaboratory")）

* セットアップ手順

https://www.12-technology.com/2022/09/stable-diffusion-ai-text2img.html?m=1




### DALL・E 2
Open AIがリリースした画像生成サービス。招待制となっており、利用するためにはウェイティングリストに登録して順番待ちをする必要がある。クレジット制となっており、時点で50回分の画像作成が可能。毎月15回分のクレジットが発行され、追加購入も可能。また商用利用も可能。


### Midjourney
Discordサーバ上で誰でも試せる画像生成ツール。Discordのアカウントを登録すればだれでも利用可能で、1アカウントで25枚までの画像生成を無料で試せる。有料プランの場合は、月額料金に応じて月毎の利用回数が決められており、商用利用も可能。基本は英語で、日本語も利用可能だが精度は落ちるとのこと。

* セットアップ手順や料金について

https://nft-japan.works/how-to-use-midjourney/



### Imagen
Googleがリリースした画像生成システム。あえて不適切データも含めて訓練しているため、一般公開していないとのこと。


### Craiyon
OpenAIのDALL・Eをオープンソースのモデルで再現したもの。英語のみ認識する。


## プロンプトエンジニアリングについて
画像生成AIの発展に伴い、プロンプトエンジニアリングという概念が生まれた。プロンプトエンジニアリングとは人工知能の思考を人間が助けるための手法を指す。例えば、画像生成AIへの入力テキストも、AIが解釈しやすい文章を打ち込むことでより望む画像を生成しやすくなる。

DALL・E2向けにプロンプトエンジニアリング用の資料が公開されている。

https://dallery.gallery/the-dalle-2-prompt-book/
Go言語、Visual Studio Code でのデバッグ方法を調べる

# Go言語、Visual Studio Code でのデバッグ方法を調べる

Windows を使っているとする  

👇 とりあえずググって適当に記事を読む。大筋で、以下の記事の通りやるとできる  

📖 [Goのデバッグ環境 on VSCode](https://future-architect.github.io/articles/20201117/)  

とりあえず真似する  

# Step [O1o0] はじめに

## Step [O1o1o0] エディター

Visual studio code を使っているとする  

## Step [O1o2o0] プログラム言語

Go 言語をインストール済みとする  

## Step [O1o3o0] Go エクステンションを入れる

📖 [Go for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=golang.Go)  

## Step [O1o4o0] 関連するツールをインストールする

`[Ctrl] + [Shift] + [P]` をキーにする  

`Go: Install/Update Tools` を選ぶ  

出てくるツールを全部選んでインストールする  

Output:  

```plaintext
All tools successfully installed. You are ready to Go. :)
```

このとき、 `dlv` もインストールしたものとする  

# Step [O2o0] デバッガーを使用する

## Step [O2o1o0] 設定ファイルの作成

VSCodeのツールバーの　虫みたいなアイコンをクリック  

`create a launch.json file` をクリック  

VSCode の上の方にフォルダー名か出てくるので、とりあえず ソースを置いているフォルダーを選ぶ  

👇 以下のファイルが自動生成される

```plaintext
    📂 .vscode
    └── 📄 launch.json
```

```json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}"
        }
    ]
}
```

## Step [O2o2o0] デバッグの実行

ブレークポイントを置く  

エントリーポイント（main関数）が書いている `*.go` ファイルを開く  

`F5` キーを押すとデバッグが開始される  

# Step [O3o0] 標準入力の差し替え

dlv では、以下のコードを実行できない  

```go
		var scanner = bufio.NewScanner(os.Stdin)
		for scanner.Scan() {
            // ...略...
        }
```

`delveは標準入力を受け付けられない` という致命的な不便がある  

👇 アタッチするといいらしい  

📖 [標準入力のあるプログラムを delve でデバッグしたい](https://qiita.com/_natsu_no_yuki_/items/505e74e598d3d6a0cb24)  

👇 アタッチしないなら  

そこで、 標準入出力と、ファイル入出力をラッピングした `VirtualIO` を作ることにし、  
標準入出力は直接使わず `VirtualIO` を使うようにし、  
標準入出力と、ファイル入出力を 切り替えられるようにする。  
入力したいコマンドは、ファイルへ書き込むことにする  

👇 以下を参照  

📖 [muzudho / go-virtual-io / docs / how_to_make.md](https://github.com/muzudho/go-virtual-io/blob/main/docs/how_to_make.md)  

# Step [O4o0] デバッグ実行でコマンドライン引数を渡すには

C++の記事だが参考にする  

👇 以下を参照  

📖 [https://code.visualstudio.com/docs/cpp/launch-json-reference](https://code.visualstudio.com/docs/cpp/launch-json-reference)  

```json
{
  "name": "C++ Launch",
  "type": "cppdbg",
  "request": "launch",
  "program": "${workspaceFolder}/a.out",
  "args": ["arg1", "arg2"],
  "environment": [{ "name": "config", "value": "Debug" }],
  "cwd": "${workspaceFolder}"
}
```

`args` という項目を追加できそうだ  

# 参考にした記事

## デバッグ環境

📖 [Goのデバッグ環境 on VSCode](https://future-architect.github.io/articles/20201117/)  

## デバッグと標準入力

📖 [scanner.Scan() hangs in GoLand debugger](https://stackoverflow.com/questions/53461228/scanner-scan-hangs-in-goland-debugger)  
📖 [golangのAtCoder向けデバック方法(VSCode)](https://qiita.com/tasmas/items/d2d5a8c95fa48e415702)  
📖 [Goでスリープしようとしてハマった](https://imagawa.hatenadiary.jp/entry/2016/12/15/190000)  

EOF
axios v0.27からmultipart/form-dataが簡単に送れるようになった

# はじめに

axiosで`multipart/form-data`形式のリクエストを投げるときに、
うまくいかなくてハマったことのある人は多いんじゃないでしょうか？

例えばこの記事がドンピシャであります！
[Node.js + axios で 画像を mulitpart/form-data でアップロードしようとしてハマった話](https://qiita.com/kazu_death/items/a94ac4ae4d71928920c5)

コード引用

```js
const fs = require('fs')
const axios = require('axios')
const FormData = require('form-data')

const uploadImage = async ({ auth_token, imageFilePath }) => {
  const form = new FormData()
  const file = fs.createReadStream(imageFilePath)
  form.append('image_file', file)
  const config = {
    headers: {
      'X-AUTH-Token': auth_token,
      'X-API-Token': env.API_TOKEN,
      ...form.getHeaders(),  // ← ← ← ← ここ!!
    },
  }
  const result = await axios.post(env.API_BASE_URL + 'api/v1/images', form, config)
}
```

`getHeaders()`を使ってヘッダーを設定しないと、
`multipart/form-data`になってくれなかったのです。。。。


v0.26までは！！！

# v0.27からは余計なこと考えなくてよいのです！

リリースノートがこちら
https://github.com/axios/axios/releases/tag/v0.27.0

> Added a multipart/form-data testing playground allowing contributors to debug changes easily ([#4465](https://github.com/axios/axios/pull/4465))

以下のように`getHeaders()`を省略しても、
ちゃんと`multipart/form-data`になってくれるようになりました〜。

```js
const fs = require('fs')
const axios = require('axios')
const FormData = require('form-data')

const uploadImage = async ({ auth_token, imageFilePath }) => {
  const form = new FormData()
  const file = fs.createReadStream(imageFilePath)
  form.append('image_file', file)
  const config = {
    headers: {
      'X-AUTH-Token': auth_token,
      'X-API-Token': env.API_TOKEN,
    },
  }
  const result = await axios.post(env.API_BASE_URL + 'api/v1/images', form, config)
}
```

# 参考

この記事でnode-fetchとaxiosの違いに触れられていて、

[Nodeでmultipart/form-dataを送る](https://qiita.com/akameco/items/dc61497ad16200c67b44)
> なぜ node-fetch はヘッダーでgetHeaders()を利用しなくていいのか？
理由は単純で、form-dataを特別に扱っている。
https://github.com/node-fetch/node-fetch/blob/c167190c6ee21234ba41bd8430700d4720bf64ce/src/body.js#L320-L323

axiosもv0.27で似たような処理が入ったということですね。
https://github.com/axios/axios/pull/4465/files


ちなみにこの記事執筆時点で、ずっとバージョン0.xxだったaxiosに
ようやくv1.0.0-alpha.1が登場していました！

https://github.com/axios/axios/releases/tag/v1.0.0-alpha.1

betaじゃなくてalphaというのが相変わらず慎重な感じですが、
v1.0のリリースも待ち遠しいですね！

ではまた〜。
Rubyの配列で複数要素の位置を得る ( index を複数得たい )

# 例


```rb
arr = ["A", "B", "X", "A", "X", "A"];
arr.each_index.select { |i| arr[i] == "X" } # [2, 4]

```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
【Linux】lsコマンドでディレクトリのみやファイルのみを表示する方法

## ディレクトリのみ

```zsh
ls -F [パス] | grep /
```
隠しファイルも含めて表示
```zsh
ls -aF [パス] | grep /
```
```zsh:サンプル
$ ls -F path/to/sample | grep /
app/
bin/
config/
db/
lib/
log/
public/
spec/
storage/
templates/
test/
tmp/
vendor/

$ ls -aF path/to/sample | grep /
./
../
.devcontainer/
.docker/
.git/
.vscode/
app/
bin/
config/
db/
lib/
log/
public/
spec/
storage/
templates/
test/
tmp/
vendor/
```

## ファイルのみ
```zsh
ls -F [パス] | grep -v /
```
隠しファイルも含めて表示
```zsh
ls -aF [パス] | grep -v /
```

サンプル
```zsh
$ ls -F path/to/sample | grep -v /
Gemfile
Gemfile.lock
Guardfile
README.md
Rakefile
compose.yml
config.ru
lefthook-local.yml
lefthook.yml
package-lock.json
package.json
typescript

$ ls -aF | grep -v /
.DS_Store
.dockerignore
.editorconfig
.env
.git-lint.yml
.gitattributes
.gitignore
.rspec
.rubocop.yml
.ruby-version
.solargraph.yml
Gemfile
Gemfile.lock
Guardfile
README.md
Rakefile
compose.yml
config.ru
lefthook-local.yml
lefthook.yml
package-lock.json
package.json
typescript
```
Laravel テストを実行する前にキャッシュをクリアする

Laravelあるある。ローカルでキャッシュしたままテストを実行してしまう。
誰もが一度はハマるであろう由々しき問題です。

ローカルでキャッシュしなきゃいいってのはありますが、
一応キャッシュした時にエラーが起きないかの動作確認などはしたいので、テスト前にキャッシュファイルを削除できればなと色々考えてみました。

公式ドキュメントでも `テストを実行する前は必ずconfig:clear Artisanコマンドを使用して設定のキャッシュをクリアしてください。` とあります。
https://readouble.com/laravel/9.x/ja/testing.html

ということで良さそうな方法を3つ考えました。

## 方法1. Composer Scriptsを使用する

```json:composer.json
{
    "scripts": {
        "test": [
            "@php artisan config:clear",
            "@php artisan test"
        ]
    },
}
```

```shell-session
$ composer test
```

とてもお手軽な方法です。

:::note info 
`@php` とすると実行中のphpプロセスに自動的に解決されるとか。
https://getcomposer.org/doc/articles/scripts.md#executing-php-scripts
:::

## 方法2. Makefileを使用する

```Makefile:Makefile
test:
	php artisan config:clear
	php artisan test
```

```shell-session
$ make test
```

こちらもお手軽な方法です。
`composer` の半分の文字数で実行できます笑

:::note info 
Makefileのインデントは半角スペースではなくTabにする必要があります。
:::

## 方法3. キャッシュクリアするテストを作る

方法1, 方法2の場合は `php artisan test` や `./vendor/bin/phpunit` と直接実行されたら当たり前ですがキャッシュクリアされない訳です。
phpunitの設定で実行前にスクリプトを流すようなことはできなさそうなのでキャッシュをクリアするだけのテストを作ってみます。
(これがやって良いのか悪いのかは分かりません...)

FeatureやUnitのテストとは分けたいので、 `tests/SetupConfigClearTest.php` と配置します。

```php:tests/Setup/ConfigClearTest.php
<?php

declare(strict_types=1);

namespace Tests\Setup;

use Tests\TestCase;

final class ConfigClearTest extends TestCase
{
    /**
     * @return void
     */
    public function testConfigClear(): void
    {
        $this->artisan('config:clear');
        $this->assertFalse(file_exists(base_path('bootstrap/cache/config.php')));
    }
}
```

`phpunit.xml` のUnitとFeatureの上にSetupのテストを追加します。

```xml:phpunit.xml
    <testsuites>
        <testsuite name="Setup">
            <directory suffix="Test.php">./tests/Setup</directory>
        </testsuite>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
```

```shell-session
$ php artisan test

   PASS  Tests\Setup\ConfigClearTest
  ✓ config clear

...
```

最初に `ConfigClearTest` が実行されていればOKです。
オプションを指定しないとキャッシュクリアできなかったときにそのままテストが続きます(まずないと思いますが...)

:::note info 
```shell-session
$ php artisan test --stop-on-failure

   PASS  Tests\Setup\ConfigClearTest
  ✓ config clear

...

`--stop-on-failure` オプションを指定すればエラー出たらテストが即終了するようにできます。
:::

## まとめ

方法3が個人的には一番良いのかなーと思います。
本当はテストクラスとして書きたくない気持ちはあるのですが、Setupとディレクトリ分けてれば良い気もしてきました。

どの方法でもそうですがファイルを指定してテストを実行した場合はキャッシュクリアはされませんのでご注意ください。

```shell
$ php artisan test tests/Feature/ExampleTest.php
```

## 関連記事

https://qiita.com/ucan-lab/items/0e31a1a7447934674a0f
php.iniを編集してもOpenSSLが有効化されない場合の対処法（Windows Server・Apache 環境）

Windows Server・Apache 環境でphp.ini(PHP7.4)を編集してもOpenSSLが有効化できなかった。
原因はPHPのディレクトリにパスを通してないことでした。
システム環境変数でパスに追記すれば良いのですが
PHPのディレクトリにパスを通さない場合でも有効化する手順を記します。

### ①php.iniを編集
 コメントアウトを外します。
```php.ini 
extension=openssl
```
### ②-1 PHPのディレクトリにパスを通してある場合
 ①で動作します。

### ②-2 PHPのディレクトリにパスを通さない場合
何らかの事情でパスを通せない場合は以下の操作が必要です。
■PHPのディレクトリ直下から下記の2ファイルをコピーします。
:page_facing_up:libcrypto-\*.dll
:page_facing_up:libssl-\*.dll

上記が見つからない場合は下記の可能性があります。
:page_facing_up:libeay32.dll 
:page_facing_up:ssleay32.dll 


■DLLファイルをパスを通してある:file_folder:ディレクトリに貼り付けます。
・C:\Windows\System32でも動作しますが（標準でパスが通っているので）、システムディレクトリなので推奨しません。
・Apacheの場合はApacheのbin配下に置いても動作します。


### 参考
■パスが通った場所にDLLファイルを置くこと
[PHP: インストール手順 Win32 ユーザーへの注意](https://www.php.net/manual/ja/openssl.installation.php)
> この拡張モジュールを動作させるには、 Windows システムの PATH が通った場所に DLL ファイルが存在する必要があります。

■OpenSSLのDLLファイル名について
[OpenSSL 1.1.0+ have changed library names in windows · Issue #1931 · arvidn/libtorrent · GitHub](https://github.com/arvidn/libtorrent/issues/1931)
>Since version 1.1.0 OpenSSL have changed their library names from:
(バージョン 1.1.0 以降、OpenSSL はライブラリ名を変更しました)
>libeay32.dll -> libcrypto.dll
>ssleay32.dll -> libssl.dll
cscの作法 その280

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
Marshal.GetDelegateForFunctionPointerを使ってください。


# 方針

- dllimport使わない、dllインポート。

# 参考にしたページ

https://toruuetani.hatenablog.com/entry/20060702/p1

# サンプルコード

```
using System;
using System.Runtime.InteropServices;

namespace App
{
	public class LateBinding : IDisposable {
		[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
		[DllImport("kernel32", SetLastError = true)]
		private static extern bool FreeLibrary(IntPtr hModule);
		[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)]
		private static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
		private IntPtr _module;
		public LateBinding(string filename) {
			_module = LateBinding.LoadLibrary(filename);
			if (_module != IntPtr.Zero) 
			{
				return;
			}
			int result = Marshal.GetHRForLastWin32Error();
			throw Marshal.GetExceptionForHR(result);
		}
		public Delegate GetDelegate(string procName, Type delegateType) {
			IntPtr ptr = LateBinding.GetProcAddress(_module, procName);
			if (ptr != IntPtr.Zero) 
			{
				Delegate d = Marshal.GetDelegateForFunctionPointer(ptr, delegateType);
				return d;
			}
			int result = Marshal.GetHRForLastWin32Error();
			throw Marshal.GetExceptionForHR(result);
		}
		public void Dispose() {
			if (_module != IntPtr.Zero) 
			{
				LateBinding.FreeLibrary(_module);
			}
		}
	}
	public delegate int MessageBox(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string text, [MarshalAs(UnmanagedType.LPWStr)] string Caption, int type);
	static class Program {
		[STAThread]
		static void Main() {
			using (LateBinding b = new LateBinding("user32.dll")) 
			{
				MessageBox m = (MessageBox) b.GetDelegate("MessageBoxW", typeof(MessageBox));
				m(IntPtr.Zero, "hello c#", "App", 0);
			}
		}
	}
}





```


以上。
エンジニア転職　11ヶ月目振り返り

こんにちは！未経験からエンジニア転職した『まさきち』です。
エンジニアに転職して11ヶ月経ちましたので業務や感じた事などを振り返ろうと思います。

これまでの振り返りは下記の記事に書きましたので合わせて読んでいただけると嬉しいです。

https://qiita.com/masakichi_eng/items/be6604f78ebf90f5df69

https://qiita.com/masakichi_eng/items/9495eac6e3ae27898ca9

https://qiita.com/masakichi_eng/items/1d5cbafcca60b5746fe8

https://qiita.com/masakichi_eng/items/18509590c0a1c7c9f996

https://qiita.com/masakichi_eng/items/3fb064e5c1654bd7fa8a


11ヶ月目は、新しい外部の業務委託の案件に入りました。結合テスト中のアプリのバグ修正の作業です。
言語はVue/Nuxtでどちらもほぼ触ったことないのでキャッチアップからになりました。

## 初期
キャッチアップと言っても現在結合テスト進行中の案件なので時間はなく、実際のバグ修正のタスクをこなしながらになります。アプリの概要も仕様も全て限られた時間で把握しなくてはいけないので大変でした。

社内にVue/Nuxtを触った経験のある人がおらず、誰にも聞けない状況...とはいえ業務時間に学習のまとまった時間も取れないので休日にUdemyや書籍でひたすら勉強の日々...

正直最初は全然わかりませんでした。社内にもわかる人がいないのでお客さんに聞いて教えてもらうという状況で申し訳ないという気持ちもありながらアプリの仕様や設計、Nuxtの書き方など聞きまくってました。

最初は遠慮してなかなか聞けなかったのですが、聞くとしっかり答えてくれたので助かりました。
当たり前かもですが、相手の負担が最低限になるようにと質問の仕方は具体的かつ簡潔になるように気を使いました。

# まとめ
### 成長を感じた部分
全然触ったことなくて訳分からん状況でも、コードを読み解いたり、自分から情報を取りに行ったりして課題をこなすことができ始めたので、突破力みたいなのはついたと思う。あと諦めない心。あと、ほぼ完成しているプロジェクトのコードを1から読み解いてバグを特定するのに丸一日かかったりとかしたので忍耐力がついた(気がする)。

### 課題に感じた部分
いろいろな事を経験できるのはとても刺激になるのですが、どれも中途半端になっている様な気がしているので、自分は〇〇ができます！と言えるようにある程度一つの事を深めたい。

# 余談
今まではプログラミング学習に力を入れてきましたが、最近モチベが低下気味なので他の領域にも手を広げてプライベート充実させていきたいと思っています。なんかあんまり人生幸福度上がってないなと最近感じていて...

最近私と同じくらいか後から未経験エンジニアとしてスタートした方がどんどん待遇が上がったり、より良い待遇の会社へと転職していっててスゴい！WEBエンジニアって夢があるなーと。私もそろそろ行動していきたい。

以上になります。
最後まで読んでいただきありがとうございました。
Deno で UnoCSS を SSR する

Deno で UnoCSS を SSR する方法の紹介です。

# UnoCSS とは

UnoCSS は [Tailwind CSS](https://tailwindcss.com/) と互換性のある、Atomic CSS エンジンです。

Vite や Vue のコアメンバーである [Anthony Fu](https://github.com/antfu) によって開発が始められ、現在は複数のメンバーによって活発に開発が続けられています。

Anthony Fu は UnoCSS を開発する以前に、似たような Atomic CSS エンジンである Windi CSS を開発していました。Windi CSS では、プラグインの機構なども含めて、かなり厳密に Tailwind との互換性を取るようなデザインをしていましたが、その制約によって、Windi CSS の使い勝手が悪いという不満を作者自身が感じるようになりました。Tailwind との細かい互換性を無視して、速さと設定のフレキシブルさによりフォーカスしたデザインで1から作り直したものが UnoCSS です。(この辺りの経緯が UnoCSS 開発の動機を説明した[ブログ記事](https://antfu.me/posts/reimagine-atomic-css)で詳しく説明されています。

# Deno とは

[Deno](https://deno.land) は TypeScript や開発ツール (リンター、フォーマッター) がビルトインされた新しい JavaScript エンジンです。

# Deno で UnoCSS を SSR する

Deno から UnoCSS を使うには、esm.sh でホストされているバージョンを使います。

```ts
import { createGenerator } from "https://esm.sh/@unocss/core@0.45.22";
import presetUno from "https://esm.sh/@unocss/preset-uno@0.45.22";
```

`createGenerator()` で UnoCSS の Generator クラスを作る事が出来ます。これが UnoCSS エンジンの本体になります。`presetUno` は UnoCSS のデフォルトのクラス定義集です。Tailwind にほぼ互換な設定がプリセットされています。

```ts
// Creates Uno generator
const uno = createGenerator({ presets: [presetUno()] });
```

`Generator` である `uno` に対して `.generate(...)` メソッドを呼び出すと、与えられたクラス群に対応するスタイルシートを生成してくれます。

```ts
// Generates css
const { css } = await uno.generate("ml-1", { preflights: false });
console.log(css);
// 以下のように出力されます
// /* layer: default */
// .ml-1{margin-left:0.25rem;}
```

`.generate(...)` の1引数目に色々なクラスを指定すると、それに応じた内容のスタイルシートが出力されます。

```ts
const { css } = await uno.generate("border border-t border-blue-100", { preflights: false });
console.log(css);
// 以下が出力される
// /* layer: default */
// .border{border-width:1px;border-style:solid;}
// .border-t{border-top-width:1px;border-top-style:solid;}
// .border-blue-100{--un-border-opacity:1;border-color:rgba(219,234,254,var(--un-border-opacity));}
```

上記の例で指定しているオプションで `preflights: true` を指定すると、リセット CSS に相当するスタイルシートが同時に出力されます (冗長なため、サンプルは割愛)

サーバーに組み込む場合は、上記の `css` 変数の内容を、`<style>` タグにセットする事で必要なスタイルを効かせる事が出来ます。
プログラミング教室でRubyとRailsを中心に習っていた初心者がJavaで課題作成に取り組んだ備忘録1

調べながら完全に我流で課題に取り組んだので手順などはデタラメかもしれないのでご容赦ください。

取り組んだ課題内容は
１、文字列と数値を格納する配列を一つずつ作る
２、文字列の配列に対してfor分を使って繰り返し処理を行う
３、特定の文字の際には指定した数字を出力する

間違っている箇所やもっと良い書き方などがありましたらぜひご教授を。

ツールはEclipseの2022版を使ってMacで書いてます。

## ワークスペースの作成
ワークスペースはフォルダのこと。 ワークスペースの中には、複数のプロジェクトのフォルダが入っている。要はディレクトリのこと。
Eclipseの起動時に新規作成or選択する。


## Javaプロジェクトとパッケージの作成
パッケージエクスプローラーの項目から「javaプロジェクトの作成」を選択![スクリーンショット 2022-09-23 15.04.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/425bf9a0-d236-d7b7-e03b-6fecffc1b99e.png)
任意のプロジェクト名を決めて「完了」を押す
プロジェクトが出来たら右クリックで「新規」→「パッケージ」を選んでパッケージ名を決める

## クラス作成の仕方
クラスとは、「 データ 」と「 処理 」の集まり。
Javaのプログラムは、クラスを複数組み合わせてプログラミングしていく。
Javaのプログラミングは クラスのプログラミング と、呼び出し側のプログラミングの2つの作業に分かれる。
自分で命名するか、既存のクラスを使う。
命名規約でJavaはクラス名は大文字から入力する必要がある
（基本的にはRubyのクラスのイメージと変わらない？）
Eclipse だとメニューバーから作成する（C＋のマーク）
![スクリーンショット 2022-09-23 10.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/74e771f8-6695-43e9-77b7-f33e80f53694.png)

## Javaを実行するには
Javaを実行するには「public static void main(String[] args)」というメソッドが必要でこの記述がないと実行できない。
（この記述がない状態で出力するとコンソールにこのメソッドが必要だよとエラー分で教えてくれます。）
・「public」は変数やメソッドやクラスが、どこからアクセスできるかを表すアクセス修飾子。publicだとどこからでもアクセス可能(Railsだとローカル変数に変えるイメージ？)
・「static」はインスタンスを生成しなくても呼び出せる特別なメソッド。mainメソッドには必ずstaticがついてくる。
・「void」はメソッド内の処理後、呼び出し元に返す値（Rubyでいうreturn）
・「main」はメソッド名
・「String[] args」は、プログラム起動時に指定する値。引数をString型の配列で受け取り（String[]）、argsは引数名

コンソールに出力するには「System.out.println」を使う
{}の数が合うようにする（これはjavascriptと同じ）
構文エラーと出たら{}が合っているか確認する。
```
class Hello{
    public static void main(String[] args) {
        System.out.println("Hello World");        
    }
}
```


備忘録1は以上になり備忘録２に続きます。
後から知りましたが「public static void main(String[] args)」ってクラスを作成する時に自動で作成するかどうかを指定できるんですね…
Deviseで、メールテンプレートの編集ができないときの対処法（template_pathではなく、headers_forを使う）

# Rails & deviseにてメールのテンプレートを変更

カスタムメーラー `app/mailers/user_mailer.rb`を、
```
class UserMailer < Devise::Mailer
  default template_path: 'users/mailer'
end
```
と定義したが、以下のデフォルトのメールが変更できずでした。![スクリーンショット 2022-09-23 18.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/90478abf-c56e-e1ff-f6c6-ddf2d34ae8af.png)

## 対応方法

以下のように、headers_forメソッドをオーバーライドすることで、設定したテンプレートが使用できるようです！
```
class UserMailer < Devise::Mailer
  # 以下の記述では動作しない
  # default template_path: 'users/mailer'

  def headers_for(action, opts)
    super.merge!(template_path: 'users/mailer')
  end
end
```
![スクリーンショット 2022-09-23 18.27.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/e76052f8-85cf-780d-7393-00c0b817be3e.png)
PHPのコンストラクタでreurnを省略すると何が返るのか

## 結論

コンストラクタで`return;`した場合に返されるのは自インスタンス


## 前提

恐らくこの書き方はレアケースであまり遭遇しないと思います。

## 背景

あるコードをみていた時以下のような書かれていました。

```php
class Hoge
{
    public function __construct()
    (
        // 略
        if (何らかの条件) {
            return;
        }
        // 略
    }
}
```

また利用箇所では以下のような記述がありました。

```php
$hoge = new Hoge();
if (empty($hoge)) {
    // 略
}
```

PHPでは`return`のを省略することができ、省略した場合はnullを返します。

```
注意:
return を省略した場合は null を返します。
```

https://www.php.net/manual/ja/functions.returning-values.php


恐らくコードの意図としては、return時の`null`を利用する処理だったと思うのですが、`null`が返ることは無かったです。

## 実際に確認してみた

```php
<?php

class Hoge
{
    public function __construct()
    {
        return;
    }
}

$hoge = new Hoge();
var_dump($hoge);
var_dump($hoge instanceof Hoge);
```

出力
```
object(Hoge)#1 (0) {
}
bool(true)
```

## まとめ

* コンストラクタで`return;`したらインスタンスが返る
* コンストラクタで`return;`しても`null`は返らない
* 多分こんな書き方あまりしない
* もっとphpの深いところを知りたいと思いました
* 間違えコメントありましたら教えてください
Rubyでダイヤル問題を解く

# 問題

- AからZまでの目盛りを持つダイヤルがあるとする。
- このダイヤルは右に回すことも左に回すことも出来る。
- ダイヤルは丸いのでAとZは隣り合わせだ。

ひとつの目盛りから別の目盛りまで、動かす必要のある最小の目盛り数を求めたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/b21d7d04-6302-6b49-e3ec-2e81a17e660a.png)


# コード

XからBまでの距離を計算すると、移動距離は4であることが分かる。

B -> A -> Z -> Y -> X で4マス移動だ。


```rb
SCALES = ("A".."Z").to_a

current_dial = "X"
next_dial = "B"

current_dial_place = SCALES.index(current_dial) + 1
next_dial_place = SCALES.index(next_dial) + 1

formal_move_diff = (next_dial_place - current_dial_place).abs
reversed_move_diff = SCALES.size - formal_move_diff

minimum_diff = [formal_move_diff, reversed_move_diff].min # 4
```




# 解説

ダイアルの配列全体はこうだ。

```rb
SCALES = ("A".."Z").to_a
# => ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
```

XからBまでの距離を求める時は、位置の差分を求めれば良い。
Bは2番目、Xは24番目に位置する。

```rb
next_dial_place = SCALES.to_a.index("B")+1 # => 2
current_dial_place = SCALES.to_a.index("X")+1 # => 24
```

配列内での2つの位置の距離は、片方の値から片方を引き算して絶対値を得れば良い。

```rb
formal_move_diff = (next_dial_place - current_dial_place).abs # 22
```

AからZの配列の中では、XとBは22個離れている。

だがこれはダイヤルなので逆順にも回すことが出来る。
逆順での距離は `ダイヤルの全ての目盛りの数 - 正順での距離` で求められる。

(ここでは便宜的に片方を正順、もう片方を逆順と呼ぶ)

```rb
reversed_move_diff = SCALES.size - formal_move_diff # 4
```


正順と逆順、両者の小さい方が最小の目盛り数である。

```rb
minimum_diff = [formal_move_diff, reversed_move_diff].min
```

# 感想

逆順での計算が大変だと思ったが、意外に引き算だけで大丈夫だった。

# 別案

AからZまでの同じ配列を2個つなげて、AとZが隣り合わせの配列を作ろうかとも考えていた。
こちらのほうが良かったかもしれない。


```rb
# AからZまでの配列二個分を連結する
SCALES = ("A".."Z").to_a*2 

# XとBの位置を得る
# アルファベットは2セットなので合計4箇所が見つかる
places = SCALES.each_index.select { |i| ["X", "B"].include? SCALES[i] } # [1, 23, 27, 49]

# 最初のXから最初のBまでの距離
move1 = places[1] - places[0] # 22

# 最初のBから二個目のXまでの距離
move2 = places[2] - places[1] # 4

[move1, move2].min # 4
```

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Kotlinの変数宣言

<h2>変数宣言</h2>

    // Java
    String str1 = "あいうえお";
    final String str2 = "かきくけこ";

    // Kotlin
    var str1: String = "あいうえお"
    val str2: String = "かきくけこ"

    // Kotlin
    // 下記のように型の記載をしなくても定義が可能
    var str1 = "あいうえお"
    val str2= "かきくけこ"

上記を見ればわかるが、変数の宣言は下記の形式となる。
　・Java　「変数 変数名 = "〇〇";」
　・Kotlin 「var 変数名 = "〇〇"」「var 変数名 = "〇〇"」
　　　　　「var 変数名 : 型 = "〇〇"」「var 変数名 : 型 = "〇〇"」
また、Javaでは「;」が必要だが、Kotlinでは不要である。
また、Kotlinでは変数名の前に「var」か「val」の記載が必要である。

<h2>型推論</h2>
Kotlinはコンパイラが型を判断してくれるので、多くの場合は型の記述を省略することが可能である。(=の右側で自動的に判断)

    var str = "あいうえお"  //→ var str: String = "あいうえお"
    var num = 100      //→ var num: Int = 100

ただし、下記のように変数の定義と同時に初期値を記載しない場合は、必ず型の指定が必要となる。

<h2>「var」と「val」はどのように使い分ければ良いか</h2>

違いは下記である。
　・var：変数を再度代入することが可能
　・val：変数を再度代入することが不可能(Javaで言うfinalに相当する)

    // Kotlin
    var str1: String = "あいうえお"
    val str2: String = "かきくけこ"
    str1 = "abcde"  →　OK
    str2 = "ABCDE"  →　NG
【React + Typescript】useContextで子コンポーネントに値を渡す

全ページに共通して使用している親コンポーネントにて実行した処理結果を、
子コンポーネントに渡す必要があったため、useContextを使うことにしました。

処理としては、カスタムフックを使用して生成されたインスタンスを子に渡します。

```JavaScript:parent.tsx(親コンポーネント)
import React, { createContext, useState } from 'react';
import { useCreateInstance } from '@/hooks/api/useCreateInstance';

type InstanceType = Record<string, any>;
export const Instance = createContext<InstanceType>({});

const ParentComponent: React.FC = () => {
  const instance = useCreateInstance();

  return (
    <>
      <Instance.Provider value={instance}>
        <ChildComponent />
      </Instance.Provider>
    </>
  )
}
```

```JavaScript:child.tsx(子コンポーネント)
import React, { useContext } from 'react';
import { PayjpInstance } from '@/pages/parent.tsx';

const ChildComponent: React.FC = () => {
  const instance = useContext(instance);
  // ここから下でinstanceが使用できる

  return (
    <>
      {/*割愛*/}
    </>
  )
}
```


propsを使わずとも一気に下層の子コンポーネントまで値を簡単に渡すことができて感動しました。


## 参考記事
https://reffect.co.jp/react/react-usecontext-understanding
くだらないアプリのアイデアを募集してみた結果

最近ひろゆきメーカーというのが流行っているのをきっかけにくだらないアプリのアイデアを募集してみました！

### 1.twitter apiから発言を分析して自分の所属する界隈でどんな発言がイイネもらえるか

### 2.youtubeのapi使って動画の（ｘヵ月分）期間売却アプリとか・・・（規約わかんない）

### 3.くだらないwebアプリのアイデアをAIが教えてくれるwebアプリ

### 4.自分のツイートにいくらの価値があるか調べるアプリ

### 5.バナナの魅力を書いてそれのスコアを出してくれるアプリ

### 6.指定した時間に指定した場所に行けなかったら上司などに自動的に謝罪のメールを送るアプリ

### 7.webカメラと連動して視線がモニターから一定時間離れたら(スマホを見るなど)画面が`赤文字ですぐに消せ`となる(新女神転生のバグみたいな)

### 8.SNSなどをロックするアプリ解除するにはバナナの魅力を500文字以上書かなければいけない。

### 9.TODOアプリタスクと所要時間を決める。時間が迫ってくると魔王の音楽が流れて緊張感を出してくる。完了したら止まる

### 10.カイジのハンチョウがメチャクチャ誘惑してくるアプリ。

## 終わりに
すごい奇抜なアプリのアイデアをたくさんいただけました笑
他にも面白いアイデアや実際に作ってみたなどの感想がありましたコメントください！
情報処理安全確保支援士　令和3年春期　午後Ⅱ

■問2（難易度：難）
テーマ：クラウドセキュリティを高める方法
【問われていること】
1.DHCPサーバのIPアドレス枯渇
・障害原因となるものが発見されず、障害っぽいのが出ている人と出ていない人がいて、その差がランダムなときはDHCPの割当に問題があるかもしれない
・IPアドレスが枯渇した際に払い出されるのはリンクローカルアドレス
・無線LANで接続する環境の場合、外部から悪意のあるDHCPサーバを偽装される危険がある
・↑の見破り方は？
　DHCP起動中：L2SWにミラーポートを設定して、DHCP　Offerの数を調べる
　DHCP停止中：正規のDHCPサーバの提供するIPアドレスがないことを調べる

2.アカウントが不正利用された際の影響調査
・アクセスログを調べる
・アカウントでアクセスできる場所に置いてあるファイルがどういったものかを調べる

3.無線LANセキュリティ
・サプリカントはクライアントPCなど、認証装置はAP(アクセスポイント。Wifi端末など)、認証サーバで最終的に認証する。この方式をインフラストストラクチャモードという。機器同士が直接通信するのはアドホックモード。PSPとかは後者で対戦してた。
・APでの認証方法
　パーソナルモード　　　：端末とAPに共有鍵を配る。共通鍵は1種類なので、変更する際は全端末に配り直す。
　エンタープライズモード：IEEE802.1X認証。ユーザごとに鍵配るので、管理しやすく、企業向け。
・セキュリティを高める
　ESS-ID隠蔽やMACアドレスフィルタリングもあるが、牽制程度にしかならない。本質的にはエンタープライズで鍵管理するしかない。

4.SaaSへの認証
・クラウド型セキュリティサービス(SECaaS)
　セキュリティサービスは幅広い。認証・認可(IDaaS)、データ漏えい防止の為の暗号化(DLP)、システムのセキュリティ評価、侵入の検知・防御、セキュリティ情報の更新やイベント管理(SIEM)、災害対策と事業継続（BCP）、NWセキュリティ、メールセキュリティ、Webセキュリティなど。

4ではNWセキュリティと認証・認可が問われた。

　プロキシ重視なら代表製品はZscaler。
　■Zscaler
　主機能は2つ。
　・ZIA：Zscaler Internet Access。プロキシサーバのクラウド版。主に外部への接続。
　・ZPA：Zscaler Private  Access。VPNサーバのクラウド版。主に内部への接続。

　上記の副産物として以下もできる。
　・フィルタリング：利用者IDごとやURLごとに通信可能なSaaSを制御できる。
　・トラフィック可視化：アクセスログの収集が可能であり、SOCとも連携できる。振る舞い検知もできる。要するにCASB。
　・保管時の暗号化：SaaSにデータを保管する際、SECaaS側ですでに自動暗号化する。

　認証能力重視なら代表製品はOkta、AzureAD。
　■Okta
　主機能は2つ。
　・ユーザ認証：SSOやMFAなど
　・ユーザ管理：UD(:Universal Directory)LM(:Lifecycle Management)など。

共通していることとしてクラウド型サービスはオンプレミス型に比べて導入ハードルが低い。
クラウド型の需要増加は、SaaS利用の増加、テレワークによる社内環境外からの接続などが原因である。

5.SaaSの規格
・ISAE3402　：SaaS提供会社の内部統制を証明する国際基準の保険業務版
・SSAE16　　 ：↑の米国公認会計士版。
・ISMS認証　 ：JISQ27001に基づく第三者による認証

6.エンドユーザが設定を書き換えて、セキュリティ違反をしないような仕組み
・PKI(:Public Key Infrastructure)認証
　↑の認証で大事なのは「秘密鍵」が「その端末に」入っているということ。
　証明書のダイジェストを秘密鍵で暗号化したものと平文を送り、送信先で検証してもらう。
　管理者は秘密鍵がその端末から移動できないように、「書き出し不可」の設定にすれば良い。
・端末が必ずクラウド型プロキシサーバを経由してほしい
　→この環境では以下が条件。
　　端末にはエージェントが必ず入っている。
　　エージェントが有効ならば、クラウド型プロキシに必ず接続する。
　　端末のサインインは一般アカウント。

　だから、管理者アカウントでエージェントの設定変更（有効→無効）ができないようにする。
FlutterでMVVMを採用して、カレンダーアプリを作成してみた件　その１

カレンダーで表示する日付を取得するための定数を実装していく
ここがカレンダーの実装における肝になるかと思います


```calendar_constraint.dart
/// 有効表示内の最初の日付
final DateTime calendarStartDay = DateTime(
  DateTimeExtension.today.year - 1,
  DateTimeExtension.today.month,
  DateTimeExtension.today.day,
);

/// 有効表示内の最後の日付
final DateTime calendarEndDay = DateTime(
  DateTimeExtension.today.year + 1,
  DateTimeExtension.today.month,
  DateTimeExtension.today.day,
);
```

カレンダーで表示する範囲を定めてあげないと無限に生成する必要があるので宣言してあげる
今回は今日の日付±1年としました


次に曜日を列挙型で宣言します
カレンダーによっては日曜日や月曜日を始めにすることもあると思うのでそこも宣言しておきます


```calendar_constraint.dart
/// 始まりの曜日
const startWeekType = WeekType.sunday;

/// 曜日
enum WeekType {
  /// 月曜日
  monday,

  /// 火曜日
  tuesday,

  /// 水曜日
  wednesday,

  /// 木曜日
  thursday,

  /// 金曜日
  friday,

  /// 土曜日
  saturday,

  /// 日曜日
  sunday,
}
```


startWeekTypeを変更すると始まりの曜日が変わります

```calendar_constraint.dart
/// 始まりの曜日
const startWeekType = WeekType.monday;
```

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737689/3df347ce-d6a5-5090-d149-eec3795dcb48.png">

このような実装をするためにstartWeekTypeを最初に持ってきて配列で返す処理を実装しています

```calendar_constraint.dart
extension WeekTypeExtension on WeekType {
  /// 曜日の配列を取得
  static List<WeekType> get weekTypeList {
    // 曜日の配列を作成
    final list = [...WeekType.values];
    // 曜日の始まりが配列がどこにあるか検索
    final start = list.indexOf(startWeekType);
    // 曜日の始まりから日曜日までを取得
    final addList = list.sublist(start);
    // 曜日の始まりから日曜日までを先頭に持ってくる
    list
      ..removeRange(start, list.length)
      ..insertAll(0, addList);

    return list;
  }

```

※ちなみに、```[...WeekType.values]```で宣言しないとremoveとかaddができないので注意です


## リンク
https://qiita.com/slovenly_engineer/items/05247129070352bb534c