OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】CodeDeployによるBlue/Greenデプロイ実行時エラー「The ELB could not be updated due to the following error: Green taskset target group cannot have non-zero weight ...」の解決方法

# 概要
Fargateへのデプロイを、CodeDeployによるBlue/Greenデプロイにより実施した。
その際、CodeDeploy画面で、下記のエラーが発生した。

>The ELB could not be updated due to the following error: Green taskset target group cannot have non-zero weight prior to traffic shifting on listener arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:listener/app/my-app-alb/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx.

※xは伏せ字

# 解決方法
ALBのTarget groupの指定を１つにする。

変更前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948830/93e1fab3-bb78-36cd-0655-b72ee3d290ae.png)

変更後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948830/43c693ab-b508-b7cb-c523-c5fa9f418552.png)
AnimateCC(CreateJS)で文字をキャプチャする

文字をキャプチャして図形とかに変換したいな
って思っても、CreateJS だけではできないようで
どうやら、HTML の Canvas の getImageData() メソッドで、ImageDataオブジェクトを取得すればいいことが分かった
でも、CreateJSとどう連動したらいいの?

# 文字をキャプチャする
```JavaScript
let w:number = Math.floor(this._myDisp.text_txt.getMeasuredWidth() + 4);
let h:number = Math.floor(this._myDisp.text_txt.getMeasuredHeight() + 4);
this._myDisp.text_txt.cache(0, 0, w, h); // 一旦キャッシュ
let canvasElement:HTMLCanvasElement = this._myDisp.text_txt.cacheCanvas; // これでいろいろできる
let context = canvasElement.getContext("2d"); // Contextを取り出す
let imageData:ImageData = context.getImageData(0, 0, w, h); // ImageDataを取り出す
this._myDisp.text_txt.uncache(); // 取り出したからキャッシュクリアしとく
```
```_myDisp``` は、AnimateCC上に配置してあるシンボル自身です
https://qiita.com/aichime/items/577af749bfa342d6087f
を参照して下さい
```text_txt``` は、シンボル内に配置してあるテキストのシンボル名です

途中の HTMLCanvasElement ってのを媒介すると、HTML の Canvas の機能をいろいろ使えるらしい（掛け渡し?）
```cacheCanvas```は、DisplayObject Class のプロパティで、同じく DisplayObject Class の cache()メソッドを使うとデータが入ってきます
（cache()しないと cacheCanvas は、nullです）

最後に取り出した imageData の data プロパティに画像データが入ってきます
imageData.data は配列になってて、左上から1ドット毎にRGBAの順に並んでます
[R,G,B,A,R,G,B,A...]になってるらしい

# 画像データを1ドットずつスキャンしていく
imageData.data 配列のアルファ値のとこを、ある閾値以上で拾ってけば、
文字の図形変換ができそう

```JavaScript
let w:number = Math.floor(this._myDisp.text_txt.getMeasuredWidth() + 4);
let h:number = Math.floor(this._myDisp.text_txt.getMeasuredHeight() + 4);
// ... 略

let sh:createjs.Shape = new createjs.Shape(); // Shape生成
this._myDisp.addChild(sh); // Shapeをシンボル内に配置
let g:createjs.Graphics = sh.graphics; // Graphicsを取り出しておく

const RADIUS:number = 1; // 丸の半径
const SC:number = 5; // 図形の大きさ
const LEFT:number = 10;
const TOP:number = 10;
let x:number, y:number;
for(y = 0; y < h; y ++){ // 下にスキャン
	for(x = 0; x < w; x ++){ // 右にスキャン
		let idx:number = (x + y * w) * 4; // 配列内のインデックスを計算
		idx += 3; // alphaチャンネル
		if(imageData.data[idx] > 150){ // アルファ値が150越えのものを丸で描画
			g.beginFill("#ffffff");
			g.drawCircle(x * SC + LEFT, y * SC + TOP, RADIUS);
			g.endFill();
        }
	}
}
```
これで文字を図形に置き換えることができました

this._myDisp.text_txt にフォントを割り与えればいろいろと楽しめます

# まとめ
HTMLCanvasElement を媒介すれば、他の図形ライブラリとかにも渡せると思うので
いろいろできそう

今回はスキャンデータを直接描画してるけど、パーティクルクラスとかにして、アニメーションさせれば、
また表現が広がると思います
Django REST frameworkのGETとPOSTリクエストをpytestでテストしたい

## はじめに
テストなくしては安心して開発をすることはできません。

私はこれまでpythonの開発を行う時にpytestを使って単体テストや結合テストを行なってきました。

これからDjango REST frameworkを触ることになりそうなのでDjangoでのテスト実装方法について調べておきたいと思い、記事を作成しました。

## 環境
記事を作成した時に使用した端末はMacbook Pro 16のM1Proモデルです。
```bash
$ uname -om
Darwin arm64
```

本記事の内容は[こちら](https://github.com/abemaru/django_unittest)のリポジトリで内容を確認することができますので、よければ参考にしてください。

### 必要なライブラリ
筆者はpipenvを使って環境を構築しています。
必要なライブラリは以下となっております。
```requirements.txt
pytest
pytest-django
Django
django-filter
djangorestframework
markdown
```

## テストディレクトリ構成について
テストのディレクトリ構造について2つ方法を見かけたの両方紹介します。
1. 機能毎にディレクトリを分ける方法
2. プロジェクト丸ごと一つのディレクトリでテストを管理する方法

```README.md
# 1. 機能毎にディレクトリを分ける方法
sample/
├─ foo/
│  ├─ tests/
│  │  ├─ foo_tests.py
├─ bar/
│  ├─ tests/
│  │  ├─ bar_tests.py

# 2. プロジェクト丸ごと一つのディレクトリでテストを管理する方法
sample/
├─ foo/
├─ bar/
├─ tests/
│  ├─ foo_tests.py
│  ├─ bar_tests.py
```
小規模のプロジェクトであれば2の丸ごと管理でも良いかもしれませんが、せっかくRESTfulな設計にするのであれば機能毎にディレクトリを分けてテストを実装しておくと機能が増えた時も安心だと思います。

# テスト実装の方法について
### GETリクエスト
まず単純なGETリクエストを実装します。
```my_api/sample/views.py
from rest_framework import APIView
from rest_framework.response import Response

class OnlyViews(APIView):
    def get(self, request, format=None):
        return Response(
            ["foo", "bar"]
        )
```

```my_api/my_api/urls.py
from django.contrib import admin
from django.urls import path
from sample.views import OnlyViews

urlpatterns = [
    path('admin/', admin.site.urls),
    path("only_views/", OnlyViews.as_view(), name="show foo bar"),
```
次に先ほど作成したgetリクエストのテストを実装します。
以下の実装を行い、`pytest run sample`を実行することでテストができるようになります。

```my_api/sample/tests/test_views.py
import pytest
from rest_framework.test import APIRequestFactory

from sample.views import OnlyViews

class TestAPIViewTests:
    def test_get(self):
        factory = APIRequestFactory()
        view = OnlyViews.as_view()

        url = "http://127.0.0.1:8000/my_api/only_views"
        request = factory.get(url)

        response = view(request)
        assert response.data == ["foo", "bar"]
```



### POSTリクエスト
次に単純なPOSTリクエストの実装を行います。
かなり無理やりな実装になっていますがサンプルのため、処理は適当に書いていますのでご容赦ください。。
```my_api/sample/views.py

class OnlyViews(APIView):
    ...

    def post(self, request, format=None):
        
        return Response(int(request.data.get("number")) + 1)
```
GETとリクエストと同じように実装することができますが、postする内容の記載を忘れないようにしてください。

```my_api/sample/tests/test_views.py
class TestAPIViewTests:
    ...

    def test_post(self):
        factory = APIRequestFactory()
        view = OnlyViews.as_view()

        url = "http://127.0.0.1:8000/my_api/only_views"
        request = factory.post(url, {'number': 10})

        response = view(request)
        assert response.data == 11
```

## さいごに
今回はサラッとDRFでGETとPOSTリクエストのテスト実装方法についてまとめました。
基本的な機能だけでなく、もっとさらに進んだテストを行いたい場合は[Django REST frameworkのテスト公式ドキュメント](https://www.django-rest-framework.org/api-guide/testing/)をご参照ください。
自動翻訳を上手くする5つのTips

どうしても英語が苦手で自動翻訳をよく使っているが、よくわからない日本語に翻訳されたことはありませんか？
私も英語を集中的に習得したての頃はDeepLといった自動翻訳を多用していましたが、おかしな日本語がたまにありました。
翻訳したい英文をそのまま翻訳にかけると、上手く自然言語処理のモデルが解釈できないことが原因であるため、そのモデルに配慮した英文を渡してあげる必要があります。
ここでは、そのまま英文を翻訳するよりも正確な日本語に翻訳される5つのTipsを紹介します。
翻訳したけどよく意味がわからないという時間がなくなると思います。

## 5つの翻訳Tips

### 1.  長い英文を短く区切る

- 編集前
 このままでは翻訳しない
```md
- The first is to use the Compositions API, which was introduced in Vue 3, and the second is to use the "Options API," which is the prototypical pattern for defining Vue components. In this guide, we'll begin with the Options API and then progress to the Compositions API to demonstrate how things work.
```
- 編集後
  ３つに分けて翻訳する
```md
- The first is to use the Compositions API, which was introduced in Vue 3, 


- and the second is to use the "Options API," which is the prototypical pattern for defining Vue components. 


- In this guide, we'll begin with the Options API and then progress to the Compositions API to demonstrate how things work.
```

### 2. 一読して意味が通じたら手を加えない
投げた英文を翻訳して意味が通じていたらそれ以上英文をいじらない方がいいです。

### 3. コンマ(,) の直後で改行する

- 編集前
```md
- When we save the file and open it in the browser, nothing appears on the page.
```
- 編集後
```
- When we save the file and open it in the browser, 
  nothing appears on the page.
```

### 4. 接続詞  `before` / `after` / `but` /  `when` /  `if` の直後で改行する

- 編集前
```
- This phase employs the beforeCreate lifecycle hook and is executed before the app has completed its initialization.
```
- 編集後
```
- This phase employs the beforeCreate lifecycle hook and is executed 
before the app has completed its initialization.
```


### 5. 英文の文末にはピリオド(.)をつけて、その後にスペースをつける。

- 編集前
```
- This phase employs the beforeCreate lifecycle hook and is executed before the app has completed its initialization
```
- 編集後
```
- This phase employs the beforeCreate lifecycle hook and is executed 
before the app has completed its initialization. 
```

## 翻訳サービス

### [DeepL](https://www.deepl.com/translator)
かなり有名で、とりあえずこれ使えばいい

### [chatGPT](https://openai.com/blog/chatgpt/)
最近流行りのchatGPTも翻訳してくれます。
以下のように入力したら翻訳してくれます。
```
次の文を日本語に翻訳して

(翻訳したい英文：English Sentense yow wanna translate into Japanese)
```


## おわりに
英語をうまいこと使って大切なことに集中できるようになれたら幸いです。

## 文献
- [ 自動翻訳大全 終わらない英語の仕事が5分で片づく超英語術 (ENGLISH HACKER'S HANDBOOK)](https://www.amazon.co.jp/%E8%87%AA%E5%8B%95%E7%BF%BB%E8%A8%B3%E5%A4%A7%E5%85%A8-%E5%B1%B1%E7%94%B0-%E5%84%AA/dp/4866731931/ref=sr_1_3?adgrpid=110168833116&gclid=Cj0KCQiAiJSeBhCCARIsAHnAzT9T6G0AM9VqkyY9jCZWPthnv70oa_Qyt79zCIEe8zGiMcrHrI0SgLYaAo6rEALw_wcB&hvadid=618675558430&hvdev=c&hvlocphy=1009343&hvnetw=g&hvqmt=e&hvrand=11253590551668440039&hvtargid=kwd-968994965403&hydadcr=10876_13554687&jp-ad-ap=0&keywords=%E8%87%AA%E5%8B%95%E7%BF%BB%E8%A8%B3%E5%A4%A7%E5%85%A8&qid=1673869587&sr=8-3)
配列とリストの違い、配列とリストは何に使う？

# 配列、リストは何に使う？
結論：複数のデータを格納するときに使う。
例）
社員リストを作るときに、社員が１００名いる時、変数定義では大変。そこで、配列、リストを使うことで、まとめて管理ができるので、効率的になる。

# 配列とリストの違い
配列は、<b>あらかじめ数が決まっている</b>（効率的）が、リストは<b>あらかじめ数が決まっていない</b>（柔軟性がある）。

# 参考文献
配列とリストの違いとは？基本的な相違や言語別の特徴もプログラマーがわかりやすく解説

https://study-z.net/100189196/3#:~:text=%E9%85%8D%E5%88%97%E3%81%AF%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%8C%E6%B1%BA%E3%81%BE%E3%81%A3,%E6%B1%BA%E3%81%BE%E3%81%A3%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82
エンジニアインターン3日目

今日はテスト環境からwordpressのテンプレートを作成した。
データベースから商品の品番、商品状態、色を取得して、商品の最新の値段を更新する仕組みを作った。
phpにsql文とwordpressからget_field()を使って値を取得し、その値に合った商品の最新の値段をデータベースから読み込んでhtmlに表示させた。
mysqlからデータを読み込む場合は情報を守るためのセキュリティーも大事になってくる。$query = 変数->prepare(SELECT文 %s,変数...)この記述でデータを守ることができる。$変数のところを%sに置き換え、sql文の最後に%sに置き換えた変数をコンマ(,)区切りで順番に書いて、$変数=$wpdb->get_result($query);を記入すれば完成だ。
インターンに参加して初めて大まかなタスクを任されてうれしい気持ちと責任感を感じた。早く自分が成長し、もっと多くのタスクを任されるようになりたいと思った。一つ一つ経験を積み、身に覚えさせて自信を持ってコードを書いていきたい。
Yolov6の使い方

# v7 v8を超える？？

https://github.com/meituan/YOLOv6

Yolov6のリポジトリによると、v7やv８より高速で精度が良いようです。

![speed_comparision_v3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/76e5ccbb-eebb-cbcc-d9a8-1be671edce2c.png)
公式リポジトリより↑

# 使い方

### インストール

```shell
git clone https://github.com/meituan/YOLOv6.git
cd YOLOv6
pip install -r requirements.txt
wget https://github.com/meituan/YOLOv6/releases/download/0.3.0/yolov6s.pt # Download pre-trained model.
```

モデルは以下の種類が提供されています。

![スクリーンショット 2023-01-16 20.49.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5fd193bc-10c7-07ef-6325-3c11fc7bd010.png)

### 推論

```shell
python tools/infer.py --weights yolov6s.pt --source img.jpg / imgdir / video.mp4
```
![pexels-büşranur-aydın-13685389 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f26b7f76-07be-d3f8-cf97-eb523a437a8c.jpeg)

### トレーニング

dataset.yamlを独自のデータセットのパスに書き換え、train.pyを実行します。

```yaml
# Please insure that your custom_dataset are put in same parent dir with YOLOv6_DIR
train: ../custom_dataset/images/train # train images
val: ../custom_dataset/images/val # val images
test: ../custom_dataset/images/test # test images (optional)

# whether it is coco dataset, only coco dataset should be set to True.
is_coco: False

# Classes
nc: 20  # number of classes
names: ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog',
        'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']  # class names
```

```shell
python tools/train.py --batch 32 --conf configs/yolov6s_finetune.py --data data/dataset.yaml --fuse_ab --device 0 --resume your_recent_checkpoint_path
```

トレーニング用のベースモデルは以下で提供されています。

https://github.com/meituan/YOLOv6/blob/main/configs/base/README.md

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

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
C言語で標準入力から二次元(多次元)配列を受け取る方法

# あとで整理したい
# 注意
[paiza]の[STEP: 18 二次元配列の入力 3](https://paiza.jp/works/mondai/array_primer/array_primer__2dmatrix_input_step3)のネタバレあり。
# 正解したコード
```C
#include <stdio.h>
int	main(void)
{
	int	n;
    scanf("%d",&n);
	//printf("%d\n",n);
	int a[n][5];
	int j;
	for (int i = 0; i < n; i++)
	{
		for (j = 0; j < 5; j++)
		{
			if(j >= 1){
				printf(" ");
			}
			scanf("%d",&a[i][j]);
			printf("%d", a[i][j]);
		}
		printf("\n");
	}
	return (0);
}
```
# ググったキーワード
二次元配列 c言語 for文 仕組み
# 参考記事まとめ
[二次元配列をfor文で回す](https://yu-nix.com/archives/c-for-array/)
[AtcoderのC++で多次元配列の解説](https://atcoder.jp/contests/APG4b/tasks/APG4b_t)
ラズパイでの4Gpiの設定

## (1)下記サイトにアクセス
https://github.com/mechatrax/4gpi
## (2)ページ内の1.1 リポジトリの追加実施
```
$ curl https://mechatrax.github.io/setup.sh | sudo bash
```
## (3)ページ内の1.2 NetworkManagerの有効化実施
＊Raspberry Pi OS September 6th 2022 以降の公式イメージが対象です。
```
$ sudo raspi-config nonint do_netconf 2
```
## (4)ページ内の1.3 パッケージのインストール実施
```
$ sudo apt install 4gpi-utils 4gpi-net-mods 4gpi-networkmanager
```
【順次更新】Minecraft Modding（Forge 1.19.2）を頑張ってみた。

こちらにて、順次更新しております。

https://zenn.dev/cyber_hacnosuke/books/minecraft-modding

# 現在更新されている内容
## [はじめに](https://zenn.dev/cyber_hacnosuke/books/minecraft-modding/viewer/intro)

- この本について
- 私について
- 執筆動機
- 本書の対象
- Minecraft Forge について
- MODについて詳しく
- 更新について
- 参考文献など

## [環境構築](https://zenn.dev/cyber_hacnosuke/books/minecraft-modding/viewer/env)

- エディタの準備
- MDKの準備
- Javaの準備
- MOD設定
- Javaをいじる
- 実行してみる

## [Item（基本編）](https://zenn.dev/cyber_hacnosuke/books/minecraft-modding/viewer/basic-item)


- Itemとは
- MODへの追加について
- Itemを登録する
   - DeferredRegisterを使う
   - RegisterEventを使う
- assetsファイルを追加する
   - 言語ファイルを追加する
   - Modelファイルを追加する
   - テクスチャを追加する
- 実行してみる

## [Item（応用編）](https://zenn.dev/cyber_hacnosuke/books/minecraft-modding/viewer/adv-item)


- クリエイティブタブの追加
- 食料
    - .nutrition(int)と.saturationMod(int)
    - .effect(java.util.function.Supplier<MobEffectInstance>, float)
    - .alwaysEat()
    - .meat()
    - .fast()
    - .build()
- カスタムクラスがなくてもできるその他の設定
    - 希少度
    - 火炎耐性
    - 最大スタック数
    - 最大耐久値
    - クラフトによる修理
- 燃料
- 右クリック
- ブロックに対して右クリック
- エンティティに対して右クリック
- ブロックを破壊したとき
- エンティティに対して左クリック
- インベントリにアイテムがあるとき
- クラフトされたとき
- ホバー時の説明
- Shiftの判定
- 修理について
    - 別のアイテムで修理する
    - 同じアイテムで修理する
- 耐久値
    - まとめ
    - 更新予定
pythonのopencv用カスケード分類器のダウンロード方法

# 学習済みカスケード分類器をダウンロード

## GUIでの方法
(1)下記サイトにアクセス
https://github.com/opencv/opencv/tree/master
(2)下記画像の右上【code】をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113724/f7d8437e-ff6e-7201-1a84-d615008f1396.png)
(3)【Download ZIP】をクリック
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333131333732342f39633238643863362d383530332d333363652d336137322d373563393.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113724/78b24bfc-e0ca-bbae-2648-258185e07fc6.png)
(4)先ほどのファイルを解凍
```
$ unzip /Download/opencv-master.zip
```
ラズパイをpython２からpython３に変更する方法

## (1)pythonのバージョンを確認 
＊現在のバージョンはpython2系であることを確認
```
$ python -V
python2.7.0
```
## (2)シンボリックリンク確認
```
$ cd /usr/bin
```
```
$ ls -l | grep python
rwxrwxrwx 1 root root     10 Oct 4  2022 python -> python2
```
## (3)シンボリックリンク削除
```
$ cd /usr/bin
```
```
$ sudo unlink python
```
## (4)シンボリックリンク作成
```
$ cd /usr/bin
```
```
$ sudo　ln　-s　pytohn3　python
```
## (5)再度シンボリックリンク確認
```
$ cd /usr/bin
```
```
$ ls -l | grep python
rwxrwxrwx 1 root root     10 Oct 4  2022 python -> python3
```
## (6)再度pythonのバージョンを確認 
＊変更後のバージョンはpython3系であることを確認
```
$ python -V
python3.7.0
```
GoogleDriveのファイルをコンソール上でダウンロードする

# 概要
GoogleDriveに置かれた60GBくらいの大きいzipファイルをブラウザからダウンロードしようとした際に、ダウンロード失敗ばかりで困ったため、その解決策の１つになります。

GCP上にダウンロード用のインスタンスを作って、コマンドでダウンロードすることで200MB/sくらいでダウンロードできました。
そのままインスタンス上で展開してから適宜分割して、もともとデータが欲しかったPCに転送を行いました。

以下は、こちらの内容になります。
https://www.quora.com/How-do-I-solve-a-Google-Drive-download-issue-with-large-files-the-files-keep-getting-canceled

# 手順
1. [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/)にアクセスする。
1. ```Drive API v3```の中にある```https://www.googleapis.com/auth/drive.readonly```を選択する。
1. ```Authorize APIs```をクリックして認証を通す。
1. ```Access token```をメモしておく。→ XXXXX
1. ダウンロードしたいファイルをブラウザで開いて、右クリックの```リンクを取得```からURLを取得する。
1. URL中に含まれる、```https://drive.google.com/file/d/YYYYY/view?usp=share_link```のYYYYY部分をメモしておく。
1. 以下のコマンドを実行する。XXXXXとYYYYYはメモしていた内容で置き換えておく。
    ```shell
    curl -H "Authorization: Bearer XXXXX" https://www.googleapis.com/drive/v3/files/YYYYY?alt=media -o download.zip
    ```

後は展開するなり、好きなようにしましょう。
Kali LinuxにインストールしたGophishの初回Usernameとパスワード

<h1>事象</h1>
Kali LinuxにGophishをインストールして、無事に起動、アクセスできたが、初回ログインIDとパスワードがわからない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/6629d6e3-93b9-e5dd-e24d-9cbb0da739a2.png)

<h1>対処方法</h1>
初回パスワードは、# ./gophish で起動時の吐き出されたログに記載してあります。
以下のように、

**"Please login with the username admin and the password ここは人による"** 
と記載されている箇所が、初回ログインUsernameとパスワードになります。

![スクリーンショット 2023-01-16 18.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/a895099e-5078-851c-7974-e15d417495b8.png)

また、初回のログイン後には、パスワードの変更を求められますので、それは忘れなうに。

尚、ログは標準出力されるだけで、ログファイルたるものはなさそうです。
【参考】

https://docs.getgophish.com/user-guide/documentation/logging

https://github.com/gophish/gophish/issues/543
[Azure DevOps]Azure Pipelines実行エラー発生時に確認するPipelinesログの設定

# この記事の内容
Pipelines実行した際にjobの実行ログをDevOpsポータルのPipelinesの画面から確認ができますが、デフォルトではエラー発生時に詳細なログは表示されません。
設定を追加することでデバッグログを表示することができるようになるため、この記事ではパイプラインのログ設定方法の手順を掲載します。
MS公式のドキュメントで「パイプライン実行時のトラブルシューティング」というページにも記載はありますが少しわかりづらかったので実際の画面キャプチャで手順を記載します。
MS公式：[Troubleshoot pipeline runs](https://learn.microsoft.com/en-us/azure/devops/pipelines/troubleshooting/troubleshooting?view=azure-devops)

# パイプライン詳細ログの設定
Pipelinesの詳細ログ設定には2つの方法があります。
1. パイプライン実行時に「システム診断を有効にする」を選択し1回の実行に対して詳細ログを出力する
1. 標準で詳細ログを毎回出力する

#### 1,パイプライン実行時に「システム診断を有効にする」を選択し1回の実行に対して詳細ログを出力する


パイプラインの実行を選択します。
![runpipeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/043b0096-ccc3-c9fa-928f-d7089efc4e63.png)

パイプライン実行の確認ダイアログが表示されますが、デフォルトでは詳細ログを出力するための[**Enable system diagnostics**]にチェックが入っていないため注意です。
![{A6D18631-7C97-44FD-BC93-E56BAE30B9F3}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/e23d99e8-3904-a269-262b-4b3cc453ac84.png)
チェックを入れて実行すると、今回の実行に対してのみ詳細ログが出力されます。

#### 2,標準で詳細ログを毎回出力する

パイプライン実行画面の右側三点リーダーを選択し、パイプラインのオプション設定を表示します。
![PiplineMoreoptionDebug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/d19d5537-b6fd-c186-5a3b-bd2b00c59d20.png)

Editを選択します。
![edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/93933b23-7281-bd11-de21-0696bc4efb72.png)

画面右上のVariablesを選択します。
![Option.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/901b0483-f426-dfda-0940-5b5e44e94f16.png)

New variableでsystem.debug変数を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/44025bad-94f6-d27d-4c0b-fe3e57817609.png)

画面のように入力しOKを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/8b5552fb-801f-6cbd-f208-7df1bce16f9d.png)

以下のように設定されていればOKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/d613cd0a-055a-8ff0-da76-9d7bce2906cd.png)




# 詳細ログの確認
上記２つのうちどちらかの設定が完了した状態でPipelinesを実行し、実際に詳細ログが出力されている画面を確認してみます。
<font color="Red">※掲載しているキャプチャ内のログやエラー内容はPipelines実行jobの内容によって違います。本記事では詳細ログの出力有無比較のために例として掲載しています。</font>

パイプライン実行jobのログ画面を確認します。
以下は詳細ログ出力を設定していない画面です。この状態ではまだ詳細ログは出力されていません。
![debug出力なし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/006de1ef-fded-e207-ee4b-119c9f5e9fc8.png)


詳細ログ出力設定をしたあとのパイプライン実行jobのログ画面です。
182行目から187行目にかけて紫色で<font color="Puple">##[debug]</font>と出力されているものが今回設定した詳細ログの出力になります。
![debug出力あり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/ff21e082-935e-981c-1592-660a6d6262ac.png)



このような形でPipeline実行時にエラーが発生した場合に詳細な調査を実行するうえで必要な詳細ログを取得することが可能となります。
デフォルトでは出力されるように設定はされていないため、適宜設定が必要となります。




# エージェント診断ログの確認

今回はAzure DevOps上でPipelinesの実行エラーが発生した際にAzure DevOpsポータル上から確認ができるPipelinesの詳細ログについて簡単にまとめましたが、実際にPipelinesのビルドやリリースを実行しているエージェントの実行時の動作ログを確認することもできます。

エージェント側で何かエラーが発生している場合にはエージェント診断ログを確認することが必要になってきますので、次回はエージェント診断ログの確認方法についてまとめてみたいと思います。
Excelでお絵描きするとき便利な子ネタ［オブジェクトの選択］

# Excelで図形選択って面倒
新人研修とかやっていると、Excelでこんな絵を描かされる場面があります。描くのも面倒だけど、後から図を崩さないで移動したりコピーするのってかな～り面倒なんですよね。CTRLキー押しながら図形選択したりして、特にExcelに慣れていない新入社員の皆様はあくせくしていらっしゃいます:confounded::sweat_drops:。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/8084cadd-c6ac-dfae-759e-692a407708be.png)
## オブジェクトの選択があるじゃないか、でも
そんな時便利な「オブジェクトの選択」と言う機能があります。ホームタブの右端のところにあります。ここですね。よく知らない方も多いと思います。そもそもExcelでこんな絵を描くのはナンセンスなんてことはわかりますが、あまりにわかり難いところに追いやられている気がします:cold_sweat:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/db64c1bd-0046-1d77-89b8-332a9c555425.png)

## ショートカットキー未割当てだから
こいつ、ショートカットキーが割り当てられていないので毎回毎回メニューから選択するの面倒なんすよ。そこで、ショートカットキーで使える様にクイックアクセスツールバーに登録しちゃいます。クイックアクセスツールバーってここなんですけど、いろんなコマンドを登録できるんですよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/fa0b8c18-692f-8660-6c89-2ee02609b17b.png)

## クイックアクセスツールバーに登録しよう
こんな画面が出てくるのでコマンド選択を「ホームタブ」にすると上から5番目に「オブジェクトの選択」がありますので、選択して追加します。追加したら右側の▲ボタンを押して一番上に持って行きましょう。そんで、OKボタンを押すと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/fdfb9e86-e208-79a8-9810-2b5faeaef619.png)

## これでショートカットキーが使える！
クイックアクセスツールバーの一番左に「オブジェクトの選択」が追加されます。クイックアクセスツールバーは左から「ALT+1」～から自動的にショートカットキーが割り当てられるので、ALT+1で「オブジェクトの選択」が実行できる様になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/f04928b4-0001-ae40-5c63-501c31e61d97.png)



ショートカットキーで楽々選択できちゃう:exclamation::grin:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106424/1b870ab0-2cd7-dcc2-dcba-c16bceae0300.png)

これ、昨年の新人研修でフローチャート描く演習の時に教えてあげたらみんなとても喜んでました:smile:。
Ruby 環境構築【Mac】

お久しぶりです。かのうです。
今回は勉強がてら、Rubyの環境構築から記事にしていきたいと思います。

<h3>【環境】</h3>
macOS Big Sur 11.5.2

まず、バージョンを確認してみましょう。
下記、コマンドを実行します。
```
ruby -v

>> ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
```
上記のように、OS標準搭載のものを使っても良いです。
ただ今回は、新しいバージョンのものをインストールしましょう。

必要なもの
・brew
・rbenv

※brewが入っていない方は、xcodeをインストール等してください。
この記事ではbrewがインストール済みであるという前提から、進めます。

brewを最新版にアップデートする。
```
brew update
brew upgrade
```
rbenvをインストールする。
```
brew install rbenv
```

このrbenvを使って最新のrubyをインストールします。（2023/1/16時点）

```
>>
2.7.7
3.0.5
3.1.3
3.2.0
jruby-9.4.0.0
mruby-3.1.0
picoruby-3.0.0
rbx-5.0
truffleruby-22.3.0
truffleruby+graalvm-22.3.0
```

今回は3.2.0をインストールしましょう。
```
rbenv install 3.2.0
```

rbenvのバージョンを確認する。

```
rbenv versions

>>
* system
  3.2.0
```
*のついている方が適応されているバージョンとなります。

なので、これを設定します。
(ここで一回ターミナルを再起動した方が良さそうです)
```
rbenv global 3.2.0
```

設定の確認
```
rbenv version

>>
3.2.0 (set by /Users/username/.rbenv/version)
```
以上で設定ができました。

rubyのバージョンを確認して見ましょう。
```
ruby -v

>>
ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-darwin20]
```

以上となります！


※エラーがなければ、下記は読み飛ばしていただいて結構です。
<h3>【エラー対応まとめ】</h3>

M1 Macでインストール中に落ちる場合は
```
RUBY_CFLAGS="-w" rbenv install 3.2.0
```
というふうにRUBY_CFLAGSを設定してやれば良いらしい。

参考：

https://kenzoblog.vercel.app/posts/m1-chip

OpenSSLの環境変数を設定する方法

https://autovice.jp/articles/178

私が出したエラー
```
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych
```
何やらlibyamlが必要らしいですね。
```
brew install libyaml
```

上記コマンド実行後に、

```
rbenv install 3.2.0
```
上記を実行すると3.2.0のrbenvがインストールできます。
ubuntuのよく使う設定ファイルの場所をまとめてみた

# wifi #
## wifi設定ファイルディレクトリ
```
$ /etc/netplan/50-cloud-init.yaml
```
## wifi設定記述
＊有線LANはethernets、無線LANはwifisに記述
```
network:
    ethernets:
        eth0:
            dhcp4: true
            optional: true
    version: 2
    wifis:
        wlan0:
            dhcp4: true
            optional: true
            access-points:
                【SSID】:
                     password: "【PASSWD】"
```
## wifi設定ファイル反映 
```
$ sudo　netplan　apply
```
# bash #
## bashの設定ファイルディレクトリ ##
```
$ ~/.bashrc
```
Androidの通知アイコンが指定通りの色にならない問題

# Androidの通知アイコンが指定通りの色にならない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134740/9613993b-acc4-6ed9-b275-1dbd51cf9ab2.png)

Androidの通知アイコン(①)が指定した通りの色にならず、なぜか黒ずんでしまうので原因を調べたら、Androidの仕様によるものでした。

```kotlin
val builder = Notification.Builder(context, id)
.setColor(ContextCompat.getColor(context, R.color.colorAccent)) // ←この色が正しく出ない
```

## Androidの仕様が原因？
どうやら、背景色とコンテンツ色の**コントラスト比が一定以下だと自動的に補正される**というAndroidの仕様があるらしい。
公式ドキュメントの記述を見つけられなかったが、ソースを見たところでは **4.5** がしきい値のようだ。
[WCAG](https://waic.jp/docs/WCAG20/Overview.html)の基準に則しているのだろう。

```java:ContrastColorUtil.java
    /**
     * Finds a text color with sufficient contrast over bg that has the same or darker hue as the
     * original color, depending on the value of {@code isBgDarker}.
     *
     * @param isBgDarker {@code true} if {@code bg} is darker than {@code color}.
     */
    public static int ensureTextContrast(int color, int bg, boolean isBgDarker) {
        return ensureContrast(color, bg, isBgDarker, 4.5);
    }
```

https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/com/android/internal/util/ContrastColorUtil.java#423

# 色のコントラスト比を確認する方法
コントラスト比は https://webaim.org/resources/contrastchecker/ で簡単に確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134740/a187cf57-2761-225f-24f3-8ad56173c59f.png)

4.5 って、けっこう濃い色になっちゃうよね。

### 参考
https://stackoverflow.com/questions/47590944/android-n-notification-title-and-icon-color-is-darker

https://stackoverflow.com/questions/40877715/cannot-use-yellow-with-android-nougat-notifications-small-icon
【TypeScript】オブジェクトのキーに型をつける方法

# 方法1

`[key: string]: number`のようにする。
これでhogeのキーは文字列型ならどんなものでも指定できるようになる。

```typescript
type hogeType = {
    [key: string]: number
}
const hoge:hogeType= {}

for (let i = 0; i < 20; i++) {
    hoge[i.toString()] = i
}
```

# 方法2

`Record<キーの型, プロパティの型>`を使う

```typescript
type fugaType = Record<string, number>
const fuga:fugaType = {}

for (let i = 0; i < 20; i++) {
    fuga[i.toString()] = i
}
```
Kali LinuxのFirefoxにGophishの自己証明書を登録してアクセスする方法

<h1>事象</h1>
KaliLinuxにGophishをインストールして、いざ、Firefoxでアクセスしようとしたら、

**Warning:Potential Security Risk Ahead** とエラー表示され、アクセスできない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/5fd7dcdc-0b4f-3c09-cbb5-4cb9833975c1.png)

「Advanced...」 を押してみると、以下のように表示される

![スクリーンショット 2023-01-16 19.11.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/ab55edb7-30d5-0643-b7eb-268887c4a57f.png)

<h1>原因</h1>
この事象の原因ですが、Error codeをみると、

**MOLLA_PKIX_ERROR_SELF_SIGNED_CERT** と記載があります。その下には、view Certificateとあります。CERTとは、Certificateのことです。Certificateというのは、「証明書」という意味です。MOLLA_PKIX_ERROR_SELF_SIGNED_CERTとあるので、自分自身の証明書？的なことを言われていそうですね。<br><br>

その通りで、これは、
**サーバ側であるGophishが所有する証明書が、自己証明書(オレオレ証明書とも)であることが原因です。** 通常、インターネットに公開される安全なウェブサイトは、信頼された証明機関が発行してお墨付きを得た証明書を保有して、クライアントであるブラウザに、「自分は安全なやつだよ」と言って、そのページにアクセスできるようにしています。しかし、この証明書は誰でも、作れてしまいます。閉じたネットワーク内で使用するには、必ずしもお墨付きを得る必要はないですからね。このように、信頼された証明機関が発行したものではなく、自分で作った証明を自己証明書と言います。<br><br>

そして、
**Firefoxは、セキュアなブラウザで、気が利くので、自分で作ったような怪しい証明書を持つサーバに対しては、デフォルトで、アクセスできなようになっているのです。**

<h1>対処方法</h1>
ということで、


**Firefoxに、「Gophishの証明書は例外的に大丈夫だよ」と教えてあげることで、解決できます。**

①firefoxの設定（右上の歯車アイコン）> 「Manage more setting」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/7a0d772c-23b8-35de-0a2a-1e2e5ddc2dc1.png)


②certificateと検索して「viewCertificate」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/390c1b69-78de-6f2b-11bc-4fe387fd7afe.png)

③Servers > Add Exceptionをクリック
※Exceptionとは例外という意味です

![スクリーンショット 2023-01-16 19.38.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/45a2a9b9-c5cf-8206-3418-cc12aab42780.png)

④入力バーに、GophishのIPアドレスを入力して、GetCertificateをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/b5efa492-2fe9-b28c-c2ab-47cae224e809.png)

⑤Confirm Security store this exceptionをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/372f0752-9ca9-8709-527a-6dd839c0df95.png)

⑥CertificateNameにGophishが表示されたのを確認してOKクリック
![スクリーンショット 2023-01-16 19.44.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/1137e3e5-0fa2-e703-3e97-2a61fc4cadfa.png)

⑦無事にアクセス成功
![スクリーンショット 2023-01-16 19.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058458/3502a64d-d2fe-6cbd-3a23-e8bdfeaca290.png)

ちなみに、画像はログイン後の画面となっていますが初回は、ログインページが表示されると思います。初回ログインパスワードは以下記事をご参考に。

https://qiita.com/ST-eng/items/624145416df23574c4ff
SUMと CASE文を使って異なる条件の集計を行う ~ SUM(CASE WHEN) ~

## はじめに
- 実務においてとても使い勝手がよかったSQLがあったのでメモ。集約関数とCASE文を組み合わせて、**異なる条件の集約を1つのSQLで行う**

## 実行環境
- ブラウザ上で手軽に使えるDB実行環境：[DB Fiddle](https://www.db-fiddle.com/)を使用

## SQLサンプル
### サンプル：異なるタイプの集計結果を1つのSQLで行う

```sql:テーブル：商品在庫テーブル（MySQL8.0）
CREATE TABLE `shohinStock` (
  `id` int NOT NULL AUTO_INCREMENT,
  `type` int NOT NULL comment '1: 商品A, 2: 商品B',
  `stockNum` int default 0,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
```sql: insert
INSERT INTO shohinStock VALUES(1, 1, 100);
INSERT INTO shohinStock VALUES(2, 1, 200);
INSERT INTO shohinStock VALUES(3, 2, 150);
INSERT INTO shohinStock VALUES(4, 1, 200);
INSERT INTO shohinStock VALUES(5, 2, 300);
INSERT INTO shohinStock VALUES(6, 1, 100);
INSERT INTO shohinStock VALUES(7, 1, 200);
INSERT INTO shohinStock VALUES(8, 2, 200);
INSERT INTO shohinStock VALUES(9, 1, 50);
```

type別に`stockNum`（在庫数）を求めようとした場合、WHERE句でやるとなると、typeごとに集約する必要がある

```sql: Where句でtype毎に絞り込み＆集約
SELECT 
  CASE WHEN type = 1 THEN '商品A' WHEN type = 2 THEN '商品B' ELSE 0 END AS '商品分類',
  SUM(stockNum) AS '在庫総数'
FROM
  shohinStock
WHERE
  type = 1;
  
SELECT 
  CASE WHEN type = 1 THEN '商品A' WHEN type = 2 THEN '商品B' ELSE 0 END AS '商品分類',
  SUM(stockNum) AS '在庫総数'
FROM
  shohinStock
WHERE
  type = 2;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/e17ed402-75fb-5e97-7553-e2f08e49f314.png)

#### SUMとCASE文を使って1つのSQLで表現してみる
```sql: SUM + CASE
SELECT 
  SUM(CASE WHEN type = 1 THEN stockNum ELSE 0 END) AS '商品A:在庫総数',
  SUM(CASE WHEN type = 2 THEN stockNum ELSE 0 END) AS '商品B:在庫総数'
FROM
  shohinStock;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/6c28ae35-aba0-38c8-ff9f-5173bfc6fb1f.png)



## 参考文献
この記事は以下の情報を参考にして執筆しました。

- [達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ](https://www.shoeisha.co.jp/book/detail/9784798157825)
- [SUM(CASE WHEN)を使った条件付き集計](https://qiita.com/hisaitami/items/2ede408806088e634eed)
Next.js + Supabase | TTFB(Waiting for server response)を早めるTIPS

-　getServersideProps(SSR) → getStaticProps(SSG)を検討する
-　getServersidePropsでcacheを活用する
-　ファーストビューで画面外のデータはuseEffectやuseSWR、react/supspenseで取得をする
-　supabaseのjoin tableを活用して通信の回数を極力減らす
【React】 create-react-appで躓いた : npm install --no-audit --save --save-exact --loglevel error react react-dom react-scripts cra-template has failed.


# 参考
https://stackoverflow.com/questions/71733043/npm-install-no-audit-save-save-exact-loglevel-error-react-react-dom-reac

# 環境
- node.js v16.18.1
- npm 8.19.2
- react 18.2.0

# 内容
Reactの環境を作成しようとしたところ以下の問題が発生し上手くいかなかった

```
$ create-react-app <project_name>
```
↓エラー内容
```
...
Aborting installation.
  npm install --no-audit --save --save-exact --loglevel error react react-dom react-scripts cra-template has failed.

Deleting generated file... node_modules
Deleting generated file... package.json
Deleting academy-react-app/ from /home/bitnami
Done.
```

npmのキャッシュを削除すると解決した

```
npm cache clean --force 
```

以上
Azure認定資格 AZ-400を取得しました

Azure認定資格にはExpertという上位資格が2つ存在しています。
認定資格一覧は [こちら](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE2PjDI)

Expertの1つである[DevOps Engineer Expert](https://learn.microsoft.com/ja-jp/certifications/devops-engineer/)に認定されるためには、[AZ-400](https://learn.microsoft.com/ja-jp/certifications/exams/az-400)試験に合格する必要があります。
2年前に不合格だったAZ-400のリベンジに成功したので体験記を残します。

他の資格体験も書いていますので良ければご覧ください。
* [Azure認定資格 AZ-900を取得しました](https://qiita.com/shingo_kawahara/items/86b4b7599318996f6f60)
* [Azure認定資格 AZ-203を取得しました](https://qiita.com/shingo_kawahara/items/551ac6b880a4a59e4291)
* [Azure認定資格 AZ-300を取得しました](https://qiita.com/shingo_kawahara/items/7d1c217e2588c5a232e3)
* [Azure認定資格 AZ-301を取得しました](https://qiita.com/shingo_kawahara/items/5e5c1febeb773a95b6af)

# 試験の傾向は？
* 問題：46問
これまでのAssociate試験やExpert試験と同じように「2択問題」「1問1答」「ケーススタディ」は出題されました。各セクションを先に進めると前のセクションに戻ることができません。
* 時間：120分
申込みでは140分になっていますが、そのうち20分は事前の同意書などの時間なので、実際は120分でした。
* 合格ライン：700点
結果700点で超ギリギリの合格でした。かなり難しかったです。

# 試験範囲
* プロセスと通信を構成する (10 - 15%)
* ソース管理を設計し、実装する (15 - 20%)
* ビルド パイプラインとリリース パイプラインを設計し、実装する (40 - 45%)
* セキュリティおよびコンプライアンス計画の策定 (10 ～ 15 %)
* インストルメンテーション戦略を実装する (10 - 15%)

[学習ガイド](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3VP8d)にもう少し詳しく出題内容が示されています。

Azure DevOpsやGitHubの知識はもちろんですが、Gitやコンテナー関連、IaC、DevSecOpsなど幅広い知識が求められます。

# 学習方法
2年前にMicrosoft Learnをサッと流してチャレンジしてみたところ、620点ほどで不合格となりました。2年前の段階ではAzure DevOpsを本格的に使っておらず、Learnのチュートリアルを流した程度でした。

ここ最近Azure DevOpsのReposやPipelinesでCI/CD環境を構築することが増えたので、改めてLearnを全て見返して受験することにしました。

一度不合格を経ての体験から、Learnのハンズオンだけでなく実際にコンテナアプリケーションをReposにPushし、Dockerfileを書き、Pipelineでビルド/ACRへのPush、App ServiceやContainer Appsへのリリースといった一連の流れを経験していないと厳しかったなと感じました。

あとAZ-400のLearnは最近日本語対応されたのでそれも大きかったですね。

# まとめ
120分のうち、90分くらいで終わったので時間は余裕があるかなと思います。
インフラがバックボーンの私にとってはこれまでのAzure認定資格の中で一番難易度が高いと感じました。
その分Learnで学習する際に知らなかった知識を身に付けることができ、こういった知識習得が資格のメリットだなと改めて思いました。

ちょうどタイミングよく [Microsoft Learn Cloud Skills Challenge](https://www.microsoft.com/ja-jp/cloudskillschallenge/ignite/registration/2022) が開催されており、AZ-400が無料バウチャーの対象になっていたのでラッキーでした。Cloud Skills ChallengeはBuildやIgniteといった大きなイベントのときに開催される可能性があるので今後も要チェックです。

次はAZ-500かAZ-700を目指したいと思います！
React、日時を表示する

Reactで現在の日時を表示する機能を実装したのでまとめます。

Javascriptで使用できるDateオブジェクトが持つ値から日付と時刻の値を
それぞれ取得するメソッドを使用いたします。

```
//年の値を取得する
getFullYear	

//月の値を取得する
getMonth

//	日の値を取得する
getDate	

//曜日の値を取得する
getDay	

//時の値を取得する
getHours	

//分の値を取得する
getMinutes	

//秒の値を取得する
getSeconds	

//ミリ秒の値を取得する
getMilliseconds	
```

①useEffectで現在の日時を取得する。

②、①で取得した値をuseStateに保管する。

③、②で保管した日時を出力する。

実際のコード
```
import React, {useEffect, useState} from "react";
import Dropdown from "@/Components/Navgation/Dropdown";

export const MCNavigation = ({auth}) => {

    const [date, setDate] = useState([])
    const [time, setTime] = useState([])

    useEffect(() => {
        setInterval(() => {
        let d = new Date();
        let year = d.getFullYear();
        let month = d.getMonth() + 1;
        let day = d.getDate();
        let dayofweek = d.getDay();

        const dayname = ['日','月','火','水','木','金','土'];

        setDate(year + '年' + month + '月' + day + '日' + '[' + dayname[dayofweek] + ']');

        let hour = d.getHours().toString().padStart(2, '0');
        let minute = d.getMinutes().toString().padStart(2, '0');
        setTime(hour + ':' + minute);
        });

    },[])


    return (
            <p>{date}<span>{time}</span></p>
           
    );
}
```
表示結果
![スクリーンショット_20230116_193938.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096726/4ddcb2b3-e346-821f-7c18-085b38177fc7.png)
ABC285回答メモ

0.はじめに
　D問題まで解けてレート+37。
　久々に爽快感のある回答でした。

1.A - Edge Checker 2
　しょっぱなにしては難しい問題・・。
　頭が回らず、愚直に図を見ながら
　aが1かつ、bが2or3の時Yes　その他はNo
　aが2かつ、bが4or5の時Yes　その他はNo・・・・
　と、書いているうちに法則性に気づき
```
if(b==2*a or b==2*a+1):
    print("Yes")
else:
    print("No")
```
　に、行きつきました。
　まぁ、まずはやってみるというのも大事ですね。

　https://atcoder.jp/contests/abc285/submissions/38046872

2.B - Longest Uncommon Prefix
　最初見たときは全く意味が分からず、ほんとにB問題？？と質問しそうになりました。
　いったんCを解いた後戻ってきて眺め返してみたら、解法が見えてきました。
　まずはやってみないというのも大事ですね・・・。

　考え方
　　1)何個後の文字を判定するかの変数i(1～N-1)を用意しループ_1
　　2)ループ_1ごとに1文字目から、N-i文字目までチェックする変数ｊと回答用変数ansを
　　　用意しループ_2
　　3)ループ_2ごとにS[j]とS[j+i]を比較し、同じならans+=1、ちがったらブレイク
　　4)ループ_2を抜けたら、ansを出力

　iとjの関係性をつかむのにてこずりました。（わたしだけ？）

　https://atcoder.jp/contests/abc285/submissions/38060955

3.C - abc285_brutmhyhiizp
　アルファベットを26進数と置き換えて計算すれば一発だなと思い
　そのようなPythonプログラムをググる。
　ドンピシャなソースが見つかり解答・・・。
　大体ヒントになりそうなページを見つけて参考に回答するのですが
　そのものずばりなソースを見つけてしまい、そのまま使い反省・・・。

　https://atcoder.jp/contests/abc285/submissions/38057032

4.D - Change Usernames
　例題を見て
　A→B
　B→C
　C→A
　といった感じのループが発生していなければOKと判断。
　ついでに、1回調べたループは調べないよう調べたフラグを付けたところ
　そのせいでうまくいかなくなってしまいました。

　その結果、ループをチェックする回毎に
　その回で調べたかのみをチェックすることに変更
　
　結果として、TLEは出ずにAC頂けました。
　再帰関数深度を増やすオプションは必要だったので、
　これはもう次から必須にしてしまおうかな・・・。

　https://atcoder.jp/contests/abc285/submissions/38068722

以上
わからない時はすぐ質問しよう

コードを書いていると必ず訪れるのが、「わからない」という現象。

システムエンジニアとして仕事をし始めた頃は、プログラミング言語の使い方・コードの書き方、ソースの意味などが分からず手が止まってしまいます。

ある程度できるようになってくると、次は仕様の意味が分からずに止まってしまう時が来ます。

つまり、**エンジニアの仕事は、常に「わからない」ことと向き合います。**

他の仕事では、なかなかないことだと思います。
なので、**「わからないことに遭遇した時は、すぐに先輩や上司に質問しましょう。」**
というのが今回の記事で言いたいことです。

## わからない時は何分考えたら質問する癖を付けましょう
わからないことを一人で抱えていても解決しませんし、わからないことでずっと悩んでいても時間が勿体ないですしね。
ただ、考えすぎないのも良くないことなので、時間の制限を決めて質問すると良いです。

例えば、**「10分考えてわからなかったら質問する」**
こういう自分ルールを作っておくだけでも、質問はしやすくなります。
**一人で何時間も悩んだ問題でも、先輩に聞くと5分で解決したりしますからね（笑）**

### 簡単なエラーも最初は全くわからないです。。
DBのエラーやLaravelのキャッシュなど、この類のエラーは慣れてない時は、さっぱりわからないと思います。

急に
「Class not found」や
「SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user' in 'field list'」
など出てきても「はてっ？」となってしまいます。

慣れていると一発でわかるエラーですが、1時間悩んでしまうこともあります。
**慣れていないエラーが出たら、どんどん聞きましょう！**

システム開発をしていて、よく聞かれるのは、「ソースを変更したのに画面に反映されない」です。
原因は、ビルドし忘れてるだったりします。

このあたりは、Read.meをよく読むことや、チーム内のコミュニケーションが円滑だと回避しやすいですね。
最初から「npm run watch」のコマンドを手順書に書いてあると、エンジニア初心者だけでなく新規にメンバーが参画する時に、親切で良いですね。

### さいごに
わからない時はすぐ質問しましょう。
サクサクと進んでいくほうが、自分も開発チームも気持ちがいいですよ。

https://amzn.asia/d/hfYfxvf

https://amzn.asia/d/6q6warR
SPIKE プライム のファームウェアを抽出する方法

# SPIKE プライム のファームウェアを抽出する
バックアップとして残しておきたいのでファームウェアを抽出する必要があったので、その方法を備忘録としてまとめました。

# 事前準備

WSL2でUbuntuを起動できるようにしておく。
dfu-utilを使えるようにインストールする。
```
sudo apt-get install -y dfu-util
```
ubuntuにusbipdをインストールする
```
sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip $(ls /usr/lib/linux-tools/*/usbip | tail -n1) 20
```
windowsにusbipd-winをインストールする

https://github.com/dorssel/usbipd-win/releases

# Ubuntuとスパイクプライムの接続
SPIKE プライムをDFUモードでPCに接続する。
その後、Windowsで
```
usbipd wsl list
```
を実行後、SPIKEのbusidを調べ、Ubuntuにマウントする。

```
usbipd wsl attach --busid 3-1
```

# Ubuntuでの操作

SPIKE プライムが接続しているかどうか確認する。
```
sudo dfu-util --list
```
ファームウェアを読み出す。
```
sudo dfu-util --alt 0 --dfuse-address 0x08000000:1048576 --upload ~/firmware.bin
```

Take ownership of the file created by the dfu-util program.
```
sudo chown $(whoami) ~/firmware.bin
```
Remove the first 0x8000 bytes, as these are before the firmware starts.
```
fallocate -c -o 0 -l 32768 ~/firmware.bin
```
Remove the trailing bytes that have the value 0xFF, as these are unnecessary.
```
sed -i '$ s/\xFF*$//' ~/firmware.bin
```
Rename the firmware to the md5 hash of itself.
```
mv ~/firmware.bin ~/$(md5sum ~/firmware.bin | awk '{ print $1 }').bin
```
printStackTrace

throwable classのメソッドprintStackTrace

```java
public class Outer {
    public static void main(String[] args) {
       String s = null;
       try {
            s.charAt(0);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}
```
```
java.lang.NullPointerException
	at com.mycompany.mavenproject1.Outer.main(Outer.java:23)
```
【JavaScript】ハンバーガーメニューの作成

# 1日1UI投稿

かなり時間が空きましたが、本日久しぶりに投稿します。

## ハンバーガーメニュー

最初のころに作った[ハンバーガーメニュー](https://qiita.com/ri-tama/items/134a406d510434693b0a)とは違うハンバーガーメニューを作成しました。

以下完成品です。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="zYLdaQq" data-user="ri-tama" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ri-tama/pen/zYLdaQq">
  ハンバーガーメニュー2</a> by ri-tama (<a href="https://codepen.io/ri-tama">@ri-tama</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 躓いたポイントを整理

## CSS

```CSS
.overlay{
    position: fixed; 
    top:0;
    right:0;
    bottom:0;
    left:0;
    width:100%;
    height:100%;
    background-color:rgba(255,255,255,.8);
    opacity: 0;
    pointer-events: none;
    transition:opacity .6s;
}
```

今回ハンバーガーメニューをクリックすると
画面全体が透明な白になり、そこにMenuが3つ並ぶというUIを作成しました。

画面全体へのフィルター設定の仕方を失念しておりました。
position:fixed;と上下左右の0で画面全体に配置することが可能です。


## JavaScript
    
JSに関してはかなり単純なものだと思いますが、1点だけ。

```javascript
open.addEventListener('click',()=>{
      open.classList.add("show");
      overlay.classList.add("show");
    });
```
openをクリックしたときに、openとoverlayにshowというクラスを加える
というのが上記のコードですが
この時加えるクラスの(show)は(.show)では動作しません。

DOMを取得するときは...と考えてみると

```javascript
  const overlay=document.querySelector(".overlay");
```

上記コードについては

https://developer.mozilla.org/ja/docs/Web/API/Document/querySelector

こちらで言及されている通り

>Document の querySelector() メソッドは、指定されたセレクターまたはセレクター群に一致する、文書内の最初の Element を返します。一致するものが見つからない場合は null を返します。

とされているので、一致するという意味で.overlayを取得して動作できているのでしょう。

最初の問題に戻ります。
classlistに(show)を追加してね！
という単純な命令をしており、ここにCSSの書き方である.クラス名と書いても
HTMLの方に追加されない！ということなんですね。
追加してね！って言っているのは、(show)であって(.show)ではないのですから。




というわけで本日は別バージョンのハンバーガーメニューの作成でした。
またアウトプットができるよう勉強していきます。
またDockerの勉強を始めましたので、そちらもアウトプットしていきたいと思います。

読んでいただきありがとうございました。
VBSでPowerShell起動

## 概要
ps1をダブルクリックすると実行されずに開いてしまうので、ダブルクリックで実行出来るようにするためVBSを起動ファイルとして使用する

## 実装
```vb:vbs
'====================================
' ps1の起動用スクリプト
'====================================
Option Explicit

'FileSystemObject、ShellObject
Dim fileSystemObj
Dim WshShell

'VBSパス、VBS格納フォルダ、ps1パス
Dim vbsPath
Dim vbsFolder
Dim ps1Path

'オブジェクト参照
Set fileSystemObj = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")

'VBSパス
vbsPath = Wscript.ScriptFullName
'VBS格納フォルダ
vbsFolder = fileSystemObj.GetFile(vbsPath).ParentFolder
'ps1パス
ps1Path = vbsFolder & "\TEST.ps1"

'.ps1が存在するかを確認
If fileSystemObj.FileExists(ps1Path) Then
    'ps1起動オプション
    Const OPT = "Powershell -ExecutionPolicy Unrestricted -NoExit "
    'ps1起動
    WshShell.Run OPT & ps1Path,[※1],true 
ELSE
    msgbox ps1Path,,"NotFileExists"
End If

'オブジェクト解放
Set fileSystemObj = Nothing
Set WshShell = Nothing
Wscript.Quit

```

:::note info
[※1]
1 = 表示
0 = 非表示
:::


`
上記だとフォルダ名に空白、()などがあった時にパスが読み取れなくなるので以下のようにエスケープさせる
`

```vb:vbs

'====================================
' ps1の起動用スクリプト
'====================================
Option Explicit

'FileSystemObject、ShellObject
Dim fileSystemObj
Dim WshShell

'VBSパス、VBS格納フォルダ、ps1パス
Dim vbsPath
Dim vbsFolder
Dim ps1Path

'オブジェクト参照
Set fileSystemObj = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")

'VBSパス
vbsPath = Wscript.ScriptFullName
'VBS格納フォルダ
vbsFolder = fileSystemObj.GetFile(vbsPath).ParentFolder
'ps1パス
ps1Path = vbsFolder & "\TEST.ps1"
```
```diff_apex
2023/1/27修正
- ps1Path = Replace(ps1Path," ","` ") 
- ps1Path = Replace(ps1Path,"(","`(")
- ps1Path = Replace(ps1Path,")","`)")
↓
+ ps1Path = Chr(34) & ps1Path & Chr(34)
```
```vb
'.ps1が存在するかを確認
If fileSystemObj.FileExists(Replace(ps1Path,"`","")) Then
    'ps1起動オプション
    Const OPT = "Powershell -ExecutionPolicy Unrestricted -NoExit "
    'ps1起動
    WshShell.Run OPT & ps1Path,[※1],true 
ELSE
    msgbox ps1Path,,"NotFileExists"
End If

'オブジェクト解放
Set fileSystemObj = Nothing
Set WshShell = Nothing
Wscript.Quit

```
scheduleAtFixedRate, schedulewithFixedDelay

   kickするのを定期的にinterval
scheduleWithFixedDelay  前の処理が終わってから定期的にinterval 

below is scheduleWithFixedDelay sample
```java
public class Outer {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
        s.scheduleWithFixedDelay(() -> {
            int interval = new Random().nextInt(10);
            try {
                System.out.print(interval);
                Thread.sleep(interval * 100);
            } catch (InterruptedException ex) {
                Logger.getLogger(Outer.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("end");
        },1,1,TimeUnit.SECONDS);
        int count = 1;
        while(true) {
            Thread.sleep(100);
            //if(s.isShutdown()) break;
            count++;
           System.out.print(">");
           if(count>100) {
               s.shutdown();
               break;
           }
        }
    }
}
```
1秒待機 initial delay
0.4秒処理
1秒待機 delay
0.4秒処理
1秒待機 delay
0.8秒処理
1秒待機 delay

```
>>>>>>>>>4>>>end
>>>>>>>>>>0end
>>>>>>>>>4>>>>end
>>>>>>>>>8>>>>>>>end
>>>>>>>>>6>>>>>>end
>>>>>>>>>1>end
>>>>>>>>>6>>>>>>end
>>>>>>>>>
```
scheduleAtFixedRateは、前の処理が時間かかりすぎるとintervalを使い果たしているので、次の処理がすぐ始まる
1秒待機 initial delay

0.5秒処理(period 1s)
0.5秒待機

0.7秒処理(period 1s)
0.3秒待機
：

```
>>>>>>>>>5>>>>end
>>>>>7>>>>>>end
>>>1>end
>>>>>>>>9>>>>>>>>end
>8>>>>>>>end
>>1>end
>>>>>>>>8>>>>>>>end
>>7>>>>>>>end
>>9>>>>>>>>>end
0end
>>>>>>>>>>
```
terraform initした際に「Error: error configuring S3 Backend: error validating provider credentials」となるときの対処

# はじめに
Terraformでインフラを記述する際に、
プロジェクトフォルダを作成したあと最初に
`terraform init`コマンドを入力して初期化します。
このときに出るエラーとして、掲題のケースがあり、
この対処について確認していきたいと思います。

# エラー内容

```
$ terraform init
Error: error configuring S3 Backend: error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid.
        status code: 403, request id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```
# 対処
結論、AWSの認証情報設定が必要になります。
〜/.aws/credentialsファイルにてアクセスキーとシークレットアクセスキーを設定します。
```
$ aws configure
(※下記については右のコマンドで確認可「$ cat ~/.aws/credentials」)
AWS Access Key ID [None]: AWSアカウントで発行したアクセスキー IDを入力
AWS Secret Access Key [None]: AWSアカウントで発行したシークレットアクセスキーを入力
(※下記については右のコマンドで確認可「$ cat ~/.aws/credentials」)
Default region name [None]: ap-northeast-1など利用したいリージョン名を入力
Default output format [None]: jsonを入力
```

問題なく初期化できました。
```
$ terraform init
Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...

〜省略〜

* hashicorp/aws: version = "~> 4.50.0"

Terraform has been successfully initialized!
```

# 終わりに
アクセスキーを発行しない方法についても今後色々と試していきたいと思います！
【Git】git clone時のデフォルトブランチの意味とは？特定のブランチを指定してクローンする方法とは

# 概要
* `git clone`とブランチの関係性について整理したので備忘録として記します。
    * そもそもデフォルトブランチとは？
    * `git clone`した時のデフォルトのブランチは？
    * ローカルブランチを最新にするには？
    * リモートから特定のブランチを指定してcloneするには？

# そもそもデフォルトブランチとは？
* 一般的に、「本番環境にデプロイ可能なコード」と見なされることが多いブランチ
* ブラウザでgitのリポジトリを開いた時に、最初に表示されている
* git clone時の対象ブランチ・プルリクエスト作成時の標準のマージ先ブランチ
* 参考記事：[git コマンドでデフォルトブランチ名を取得する](https://qiita.com/ymm1x/items/b22bddc9fbc192ae1a70)
* デフォルトブランチは変更することもできます。変更方法は公式サイトの以下リンクをご参考ください。
    * [デフォルトブランチを変更する](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/changing-the-default-branch)

# `git clone`した時のデフォルトのブランチは？
* cloneしたらデフォルトではmainになっています
    * ちなみに、2020年10月より前はデフォルトブランチ名は「master」でした。ただし、これはmaster(主人)とslave(奴隷)を連想させる単語として、使われないことになりました。
* デフォルトの設定ではmainになっていますが、他のブランチが含まれていない、というわけではありません。リポジトリ内全てのブランチを含んでいます。main以外のブランチにいきたい場合は、目的のブランチにチェックアウトする必要があります。
    * clone直後、developブランチにしたい場合は、以下のコードを実行します
    * `git checkout -b develop`


# ローカルブランチを最新にするには？
* 上記のように、`git clone`した後にdevelopブランチに切り替えた場合、そのブランチをリモートにある最新のものにする必要があります。その場合は以下のコマンドを実行します。
    * `git pull`もしくは`git pull origin develop`
* これにより、リモート情報を取り込むことができますが、以下のコメントが出てくることがあります。

```terminal
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> develop
```

* これは、ローカルで新規作成されたブランチと「どこのリモートのブランチに紐づいているのか分かりません」と言われているためです。なので、紐づけてあげるには、記載されている通り、以下コマンドの実行が必要です。

```terminal
git branch --set-upstream-to=origin/develop develop
```

* 以下が返されたら、ちゃんと紐づけが完了しています。

```terminal
branch 'develop' set up to track 'origin/develop'.
```

# リモートから特定のブランチを指定してcloneするには？
* 最初から特定のブランチを指定してcloneしたい場合もあるでしょう。その場合は、以下のコマンドで可能です。
    * `git clone -b [ブランチ名][リポジトリのアドレス]`