OmniAICreator/Qiita-1.07M huggingface dataset:
1,3,3,7の四則演算で10を作る回答

回答を逆ポーランド記法で出力

```kotlin
class FindAnswer {

    fun findAnswer(list: List<Double>, answer: Double): List<String>? {
        for (i in list.indices) {
            if (list.size == 1) {
                return if (list.first() == answer) {
                    listOf("${list.first()}")
                } else {
                    null
                }
            }
            val remains = list.slice(0 until i) + list.slice(i + 1 until list.size)
            val targetNum = list[i]
            findAnswer(remains, targetNum * answer).also {
                if (it != null) {
                    return it + listOf("$targetNum", "/")
                }
            }
            findAnswer(remains, answer + targetNum).also {
                if (it != null) {
                    return it + listOf("$targetNum", "-")
                }
            }
            findAnswer(remains, answer - targetNum).also {
                if (it != null) {
                    return it + listOf("$targetNum", "+")
                }
            }
            findAnswer(remains, targetNum - answer).also {
                if (it != null) {
                    return listOf("$targetNum") + it + listOf("+")
                }
            }
            findAnswer(remains, answer / targetNum).also {
                if (it != null) {
                    return it + listOf("$targetNum", "*")
                }
            }
            findAnswer(remains, targetNum / answer).also {
                if (it != null) {
                    return listOf("$targetNum") + it + listOf("/")
                }
            }
        }
        return null
    }
}

fun main() {
    val ans = FindAnswer().findAnswer(listOf(1.0, 3.0, 3.0, 7.0), 10.0)
    println(ans) // [7.0, 3.0, /, 1.0, +, 3.0, *]
}
```
windowsでiverilog その120

#概要　

windowsでiverilogやってみた。
練習問題やってみた。

#練習問題

ステッピングモーターを回せ。

#サンプルコード

```

module step(input stp, input cw, output reg a, output reg b, output c, output d);
	reg stp_i,
		stp_ii;
	assign c = !a;
	assign d = !b;
	initial
	begin
		stp_i <= 0;
		stp_ii <= 0;
		a <= 0;
		b <= 0;
	end
	always @(*)
	begin
		stp_i <= stp;
		stp_ii <= stp_i;
		if (stp_i == 1 && stp_ii == 0)
		begin
			a <= (cw) ? !b : b;
			b <= (cw) ? a : !a;
		end
	end
endmodule

module test;
	reg stp;
	reg cw;
	wire a,
		b,
		c,
		d;
	step u(.stp(stp), .cw(cw), .a(a), .b(b), .c(c), .d(d));
	initial
	begin
		$monitor("%d %h %h %h %h %h", stp, cw, a, b, c, d);
	end
	initial
	begin
		stp = 0;
		cw = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
			cw = 1;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#10
			stp = 1;
		#10
			stp = 0;
		#1000
			$finish;
	end
endmodule





```

#結果

```
0 0 0 0 1 1
1 0 0 1 1 0
0 0 0 1 1 0
1 0 1 1 0 0
0 0 1 1 0 0
1 0 1 0 0 1
0 0 1 0 0 1
1 0 0 0 1 1
0 0 0 0 1 1
1 0 0 1 1 0
0 1 0 1 1 0
1 1 0 0 1 1
0 1 0 0 1 1
1 1 1 0 0 1
0 1 1 0 0 1
1 1 1 1 0 0
0 1 1 1 0 0

```

以上。
windowsでiverilog その119

#概要　

windowsでiverilogやってみた。
picやってみた。

#参考にしたページ。

https://kikb.web.fc2.com/pic16/index.html

#アセンブラ

```
ORG 0
	BSF   	STATUS, RP0
	CLRF  	TRISA
	CLRF  	TRISB
	MOVLW 	B'00000001'
	MOVWF 	PORTB
	BCF   	STATUS, RP0
LOOP
	MOVLW 	B'00000000'
	MOVWF 	H'05'
	MOVLW 	B'00000001'
	MOVWF 	H'05'
	goto 	LOOP
	END


```

#サンプルコード

```
module PrgRom(clk, romaddr, romout);
	input clk;
	input [12:0] romaddr;
	output [13:0] romout;
	function [13:0] rom;
		input [12:0] addr;
		case (addr)
		13'h0000: rom = 14'h1683;
		13'h0001: rom = 14'h0185;
		13'h0002: rom = 14'h0186;
		13'h0003: rom = 14'h3001;
		13'h0004: rom = 14'h0086;
		13'h0005: rom = 14'h1283;
		13'h0006: rom = 14'h3000;
		13'h0007: rom = 14'h0085;
		13'h0008: rom = 14'h3001;
		13'h0009: rom = 14'h0085;
		13'h000A: rom = 14'h2806;
		13'h000B: rom = 14'h3400;
		13'h000C: rom = 14'h3400;
		13'h000D: rom = 14'h3fff;
		13'h000E: rom = 14'h3fff;
		13'h000F: rom = 14'h3fff;
		default: rom = 14'h3FFF;
		endcase
	endfunction
	reg [13:0] r_RomOut;
	assign romout = r_RomOut;
	always @(negedge clk)
	begin
		r_RomOut <= rom(romaddr);
	end
endmodule

module Top;
	parameter STEP = 1;
	reg r_Clk;
	reg r_Reset;
	reg r_RxD;
	wire w_RxD;
	wire [3:0] w_RA;
	wire [7:0] w_RB;
	wire [12:0] PC = tm.w_PC;
	wire [13:0] Inst = tm.w_Inst;
	wire [8:0] RamAddr = tm.w_RamAddr;
	wire RamWE = tm.w_RamWE;
	wire [5:0] RA = tm.r_RA;
	wire [7:0] RB = tm.r_RB;
	wire [7:0] RC = tm.w_RC;
	wire [7:0] PicDataIn = tm.w_PicDataIn;
	wire [7:0] PicDataOut = tm.w_PicDataOut;
	wire T0I = tm.r_T0I;
	wire [4:0] ST = tm.pic.r_ST;
	wire [13:0] I = tm.pic.r_I;
	wire [7:0] W = tm.pic.r_W;
	wire [2:0] SP = tm.pic.r_SP;
	wire [7:0] STATUS = tm.pic.r_STATUS;
	wire [7:0] FSR = tm.pic.r_FSR;
	wire [4:0] PCLATH = tm.pic.r_PCLATH;
	wire [7:0] INTCON = tm.pic.r_INTCON;
	wire [7:0] DataIn = tm.pic.r_DataIn;
	wire [7:0] AluOut = tm.pic.w_AluOut;
	wire CF = tm.pic.w_AluCF;
	wire DC = tm.pic.w_AluDC;
	wire ZF = tm.pic.w_AluZF;
	wire IncPC = tm.pic.w_IncPC;
	wire [15:0] TMR0 = tm.r_TMR0;
	wire [7:0] OPTION = tm.r_OPTION;
	wire w_branch = tm.pic.w_branch;
	TestModule tm(r_Clk, r_Reset, r_RxD, w_RxD, w_RA, w_RB);
	always
		#(STEP)
			r_Clk <= ~r_Clk;
	initial
	begin
		//$dumpfile("wave.vcd");
		//$dumpvars(1, Top);
		$monitor("%d %h %h %h", PC, RA, RB, RC);
		r_RxD = 1;
		r_Reset = 1;
		r_Clk = 1;
		#3
			r_Reset = 0;
		#(STEP * 200)
			$finish;
	end
endmodule

```

#結果

```
   0 00 00 00
   1 00 00 00
   2 00 00 00
   3 00 00 00
   4 00 00 00
   5 00 00 00
   6 00 00 00
   7 00 00 00
   8 00 00 00
   9 00 00 00
  10 00 00 00
  11 01 00 00
   6 01 00 00
   7 01 00 00
   8 01 00 00
   9 00 00 00
  10 00 00 00
  11 01 00 00
   6 01 00 00
   7 01 00 00
   8 01 00 00
   9 00 00 00
  10 00 00 00
  11 01 00 00
   6 01 00 00
   7 01 00 00
   8 01 00 00
   9 00 00 00
  10 00 00 00

```

以上。
ros画像トピックのデータを見る

ROSの画像トピックのデータがどのようになっているのか気になり,`rostopic echo`で見やすいように,サイズは`2x3`の画像のトピックを見てみました。
結果はGIF動画のようになりました。上が`sensor_msgs/Image`タイプのトピックで,下が圧縮データの`sensor_msgs/CompressedImage`タイプのトピックです。

![topic_watch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/7542f812-688f-458f-8280-83ecfda13467.gif)

確かに圧縮データの方は,変化部分が少なくデータを小さく扱えているような感じがします。
ImageBuilderによって生成されたサーバの公開鍵が消えてデプロイできずめちゃ冷や汗をかいた話

# 1.はじめに

SREエンジニアのkakepiです
10/25（月）に弊社の管理している全てのサーバに対してデプロイできない問題が発生いたしました。
本記事は当時の状況と、判明した原因、対応策について記載したいと思います。
AWSサービスがいくつか登場し、それらの知識が若干必要かもしれませんがご了承ください🙏

# 2.背景

10/25（月）の朝方アプリケーションエンジニアからデプロイできないという問い合わせがありました
その後も各方面からデプロイできないという問い合わせが相次ぐという状況でした

前提として、弊社のデプロイはJenkinsサーバからデプロイ対象のサーバに対してssh接続し、ごにょごにょするのですが
Jenkinsの実行ログを見るとssh接続ができず、エラーになっていることがわかりました（Net::SSH::AuthenticationFailed: Authentication failed）
さらに接続できていない原因を探ると接続時ユーザの公開鍵（authorized_keys）が存在していないことがわかりました。

# 3.原因特定
公開鍵が存在しなくなった原因を探っていきました

公開鍵はansibleの実装によって作成しています。直近公開鍵まわりのansibleの変更はなかったものの、まずはここを疑い
任意のサーバに対してansibleを実行しましたが、問題なく公開鍵は生成されていました。

次にAWSのサービス周りを疑いました
前提知識として、弊社のサーバ群はAutoscalingを利用しており、そこではLaunchTemplateを使ってImageBuilderによって生成されるAMIを指定します。
さらに、ImageBuilderによってAMIを生成する作業は毎日行なっており、バージョン管理も可能となっています。

そこで、前のバージョンのAMIを起動してみるなどを試してみると、バージョンによっては公開鍵が存在していたので
特定のバージョン以降から公開鍵が存在していないということがわかりました。

ImageBuilerを含めたAWSリソースまわりも直近変更していなかったので、
ここまでくるともうお手上げで、何らかの変更がAWS側にあったに違いないという仮説を立てて問い合わせを行い
暫定対応としてAMI起動後にもう一度公開鍵を生成するという処理を加えて一旦解決しました。

# 3.問い合わせ結果

数日して問い合わせ結果が返ってきました。以下原文ママ

> EC2 Image Builder では最近、インスタンスで実行されるクリーンアッププロセスにいくつかの変更を加えました。
クリーンアッププロセスの一環として、サービスはすべてのユーザー (root と ec2-user 以外を含む) の ssh キーを削除するようになりました。
これは、Ubuntu、SUSE などを含むすべてのオペレーティングシステムの出力イメージのセキュリティを向上させるために行われます。
もし承認されたSSHキーを保持する必要がある場合、コンポーネントを介してワーキングディレクトリにファイルskip_cleanup_ssh_filesを作成するよう設定してください。これによってクリーンアッププロセスでは、インスタンスからのSSHキーのクリーンアップがスキップされます。

簡単にいうと、 **最近の変更によって現状すべてのユーザーの authorized_keys が削除される仕様になった** という回答でした。。

さらには
>ご参照されているドキュメントとは現在の動作が異なっており、担当部署にてドキュメントの更新に取り組んでいる状況でございます。

とのことでした。それはわからない泣

# 4.対応策

対応策は問い合わせ結果に記載されていた内容のままで
 **ワーキングディレクトリ**というImagebuilderで指定する項目（その名の通り生成するAMIに対してファイルを生成するなどの処理するときに使うディレクトリ）でそこに中身が空の **skip_cleanup_ssh_files** と名のファイルを生成しておけば良いみたいです。


# 5.さいごに
障害発覚から原因特定〜暫定対応〜問い合わせまでのプロセス自体は、割とスムーズにできたのではないかと思います。

しかしながら、公開鍵を使ってsshするなど割と最近のベストプラクティスには沿っていない仕組みを構築していると
こういった形で影響を受けることも知ったので、構築の際には十分に気をつけたいところです。
[AWS Well-Architected](https://aws.amazon.com/jp/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&wa-lens-whitepapers.sort-order=desc)のベストプラクティスの沿っていないと結構バッサリと切り捨てられる印象を持ちましたw

また、AWSに問い合わせてみると、回答は早いですし内容も丁寧なので
原因特定に悩んだら割とスピーディに問い合わせてしまうなど、今後も積極的も活用させていただこうと思います。
【初見殺し】アラインメント

本題解説の前に、簡単なクイズを出します。
メモリを意識する言語やDBを扱ったことがある方なら、なんとなくで答えられるはずです。
実行環境はVisual Studio2019を使用し、64bitでビルドしています。

# 問題1
①「char」のサイズは何バイトでしょう？
②「wchar_t」のサイズは何バイトでしょう？
③「int」のサイズは何バイトでしょう？
④「unsigned long long」のサイズは何バイトでしょう？

```C:問題1
#include <stdio.h>
 
#define DISPLAY_VARIABLE_SIZE(variable) printf(#variable " is %zu byte\n", sizeof(variable))
 
int main()
{
    DISPLAY_VARIABLE_SIZE(char);
    DISPLAY_VARIABLE_SIZE(wchar_t);
    DISPLAY_VARIABLE_SIZE(int);
    DISPLAY_VARIABLE_SIZE(unsigned long long);
 
    return 0;
}
```
# 回答
① charは1byte
② whar_tは2byte
③ intは4byte
④unsigned long longは8byte

ですね。簡単でしたか？

```
char is 1 byte
wchar_t is 2 byte
int is 4 byte
unsigned long long is 8 byte
```

# 問題2
では第二問です。こちらの構造体のサイズはいくつでしょうか。

```C:問題2
#include <stdio.h>
 
int main()
{
    struct _tag
    {
        char                A;
        wchar_t             B;
        int                 C;
        unsigned long long  D;
    } ST;
 
    printf("%zu \n", sizeof(ST));
 
    return 0;
}
```

# 回答2
1+2+4+8で正解は

```
ST is 16 byte
```

！？

これが、**アラインメント**による影響です。

# アラインメント(alignment)

このような挙動は、上級言語を扱う現代人にはあまり影響がありませんが、ちょっとメモリ管理をかじった人だと「余計なことをしてくれるな。オフセットがズレて把握しにくいし、スタックやメモリを余計に食うじゃないか」という文句が飛んできても仕方ありません。

しかし、このアラインメントは実際にメモリアクセス効率を考えたものになります。
厳密な説明は[MSDN](https://docs.microsoft.com/en-us/cpp/cpp/alignment-cpp-declarations?view=msvc-160)を参照してください。

要約すると「各要素は2の累乗(1を除く)境界に整列(alignment)されていると、アクセス効率がよい」というものです。
よって、2のべき乗に満たないものにはパディングが行われます。
Cやアセンブラなど、ネイティブなデータの受け渡しを行った際、構造体が崩れる。などの原因になりえます。

一つのソリューションやプロジェクトで完結している場合は、同じ定義同じコンパイラを使うので意識しなくても問題ありませんが、生データをガシガシやり取りするPOSレジの通信などでは、落とし穴になることがあるようです。

#回避策
では、このアラインメントに抗うことはできないのでしょうか。

アクセス効率の理想に取りつかれたアラインメントですが、昨今のマシンパワーを考えれば、そんな爪に火を灯すようなことをしなくても、十分やっていけると思います。
やり方はいろいろありますが、今回は以下を使って解決してみたいと思います。

```C:
#include <stdio.h>
 
int main()
{
#pragma pack(push,1)
    struct _tag
    {
        char                A;
        wchar_t             B;
        int                 C;
        unsigned long long  D;
    } ST;
#pragma pack(pop)
 
    printf("ST is %zu byte\n", sizeof(ST));
 
    return 0;
}
```

**#pragma pack**　ここで1,2,4,8,16いずれかを設定することで、設定したbyte数でアラインメントが設定されます。設定を解除するためには**pop**を使用します。
##結果
```C:
ST is 15 byte
```
1byteでアラインメントされた結果です。

#まとめ
どの言語においても、初見殺しの仕様は最初躓くとイラっとしますよね。

しかしおじさんからすると、ネイティブな言語は歴史的な背景やメモリ効率、CPU効率が考えられていて、嫌いになり切れません。

ﾉｼ
【SQL】GROUP BY

#はじめに
GROUP BYを使ってテーブルをグループ化してみます。

#GROUP BY
テーブルshoppingのpriceの合計値を同じdateをまとめて求めたいと思います。
![ScreenShot 2021-11-14 9.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/0d01bbe6-5a79-f480-faf7-1a1e2e5a445f.png)

```SQL
SELECT SUM(price), date
FROM shopping
GROUP BY date;
```

![ScreenShot 2021-11-14 9.56.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/c60b4f44-7f6f-2b82-3b3d-8698bf96030e.png)

日付によってpriceの合計値が求められました。

#GROUP BY (複数)
次に、複数バージョンを見ていきましょう。

こちらのshoppingテーブルの誰がいついくら使ったのかをグループ化したいとします。

![ScreenShot 2021-11-14 9.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/ad5cac32-4cd7-015a-c189-5a2544cfa3e2.png)

先ほどのSQLコードとほとんど変わりません。カラムの指定を増やすだけです。

```SQL
SELECT SUM(price), date, name
FROM shopping
GROUP BY date, name;
```

![ScreenShot 2021-11-14 10.26.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/64771c54-9280-e15e-1b16-9f1faab985a2.png)


#GROUP BY (WHERE)
次に、条件式WHEREとGROUP BYを使う方法を見ていきます。

categoryが食費で誰がいついくら使ったのかをグループ化してみます。

![ScreenShot 2021-11-14 10.10.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/6f3cd5a5-5e52-0d7d-1bce-f760ba503481.png)

```SQL
SELECT SUM(price), date, name
FROM shopping
WHERE category = "食費"
GROUP BY date, name;
```

![ScreenShot 2021-11-14 10.27.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/5aecf68b-4489-c2b2-1d19-c6a5063176f7.png)

注意点としては、GROUP BYをWHEREの後に書かないと正しいデータがグループ化されません。


#GROUP BY (HAVING)

グループ化した後に何か条件をつけたい時に使います。

実行優先度は以下のようになります。

WHERE > GROUP BY > SUMなどの関数 > HAVING

よって、WHEREとHAVINGの違いはGROUP BYされる前と後に実行されるかです。

以下のテーブルでpriceが300以上のものだけ抜き出してみましょう。
![ScreenShot 2021-11-14 10.29.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/3a85fdd3-cd1a-0668-ed30-0849c7ac9b9f.png)

まず、HAVINGを使う前まで書くと以下のようになります。

```SQL
SELECT SUM(price), date
FROM shopping
GROUP BY date
```

![ScreenShot 2021-11-14 10.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/6d7c6a6f-4e24-3773-d49c-9500be862272.png)

ここでHAVINGを使ってpriceの合計値が300以上のものを抜き出します。

```SQL
SELECT SUM(price), date
FROM shopping
GROUP BY date
HAVING SUM(price) >= 300;
```

![ScreenShot 2021-11-14 10.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/753dc87e-ae19-9b0a-5243-99a2fc25568e.png)

HAVINGは関数やGROUP BYの後に実行されるので、グループ化して関数を使って合計値を求めてその後何か条件をつけたい時に使えますね。


#おわりに
GROUP BYを使ってテーブルをグループ化してみました。
pic 命令

#概要

picの命令、調べてみた。

#命令一覧

|命令|機能|影響を受けるフラグ|命令サイクル数|
|:--|:--|:--|:--|
|ADDWF f, d|加算 W + f → W か f へ格納|C, DC, Z|1|
|ANDWF f, d|論理積 W & f → W か f へ格納|Z|1|
|CLRF f|f をゼロ|Z|1|
|CLRW|W をゼロ|Z|1|
|COMF f, d|f の 0,1 反転 → W か f へ格納|Z|1|
|DECF f, d|f - 1 → W か f へ格納|Z|1|
|DECFSZ f, d|f - 1 → W か f 結果ゼロなら次命令スキップ|なし|1(2)|
|INCF f, d|f + 1 → W か f へ格納|Z|1|
|INCFSZ f, d|f + 1 → W か f 結果ゼロなら次命令スキップ|なし|1(2)|
|IORWF f, d|論理和 W or f → W か f へ格納|Z|1|
|MOVF f, d|移動 f から W または f 自身へ格納|Z|1|
|MOVWF f|移動 W から f へ格納|なし|1|
|NOP|何もしない|なし|1|
|RLF f, d|1ビット左へシフト → W か f へ格納|C|1|
|RRF f, d|1ビット右へシフト → W か f へ格納|C|1|
|SUBWF f, d|減算 f - W → W か f へ格納|C, DC, Z|1|
|SWAPF f, d|f の上位と下位を入れ替え → W か f へ格納|なし|1|
|XORWF f, d|排他的論理和 W ^ f → W か f へ格納|Z|1|
|BCF f, b|f の b ビット目をゼロにする|なし|1|
|BSF f, b|f の b ビット目を1にセットする。|なし|1|
|BTFSC f, b|f の b ビット目がゼロだったら次命令スキップ|なし|1(2)|
|BTFSS f, b|f の b ビット目が1だったら次命令スキップ|なし|1(2)|
|ADDLW k|定数加算 W + k → W へ格納|C, DC, Z|1|
|ANDLW k|定数論理積 W & k → W へ格納|Z|1|
|IORLW k|定数論理和 W or k → W へ格納|Z|1|
|MOVLW k|定数移動 k → W へ格納|なし|1|
|SUBLW k|定数減算 k - W → W へ格納|Z|1|
|XORLW k|排他的論理和 W ^ k → W へ格納|Z|1|
|CALL k|サブルーチン k へジャンプ|なし|2|
|GOTO k|k 番地へジャンプ|なし|2|
|RETFIE|割り込み許可で戻る|なし|2|
|RETLW k|W に k を格納して戻る|なし|2|
|RETURN|サブルーチンから戻る|なし|2|
|CLRWDT|ウォッチドックタイマ、クリア|なし|1|
|SLEEP|スリープモードにする|なし|1|

以上。
ArgoCDでJobがPreSync状態でwaiting for completionが永遠に終わらない時の対処

対象のジョブにはおそらく `TTLAfterFinished` が設定されていて、ジョブ実行後にジョブが削除されるようになっている。ArgoCDではJobが削除されてしまうと実行が完了しているかどうか検出できなくなるためSyncが永遠に終わらなくなるようだ。なので`TTLAfterFinished`を削除すればよい。

Job履歴が大量にあると困り、削除しなければならないような動的なジョブはArgoCDの管理外から外すとよいと思う。
Salesforceの多要素認証必須化

#多要素認証(MFA)への対応のお願い
2021年3月15日にSalesforce社より下記の発表がありました。
> Salesforce は 2022 年 2 月 1 日より、Salesforce 製品 へのアクセスには MFA の使用を必須条件とすることを決定しました。
> 
> https://help.salesforce.com/s/articleView?id=000356005&type=1

フィッシングやアカウント乗っ取りの脅威からビジネスやデータを保護するための施策として、 SalesforceのMFA対応を必須化するというものです。対象となるのはSaas環境でSalesforceのログイン画面で内部ユーザーのIDとパスワードを入力して利用しているほとんどの企業です。


#多要素認証(MFA)とは
MFAはこれまでのパスワード認証に比べて、本人以外による不正利用リスクを低減する仕組みです。パスワード認証はユーザーIDとパスワードの正しい組み合わせを知っていることで本人であることを確認しますが、ログイン情報が漏れた場合に本人以外によるアクセスが容易に可能になります。そこでMFAはこれに加え本人が持っているデバイスや生体情報を使って、より厳密に本人確認を行います。


https://help.salesforce.com/s/articleView?id=000352937&type=1


https://www.ipa.go.jp/security/anshin/account_security.html#3_2stepsevs


#放置するとどうなるか

パスワード認証のみでSalesforceを利用しているユーザーは2月1日より利用することができなくなります。どのように利用できなくなるかについては明記されていませんが、下記のような記載があります。

> 2022 年 2 月 1 日までに MFA を有効にしていないお客様は、契約上の義務を遵守していないことになります。法務部門と相談のうえ、要件の期日までに MFA を有効化しないことによる帰結について理解しておくことをお勧めします。


#取り急ぎ必要となる処置
Salesforceの機能を利用してMFAを実現することができます。追加費用を掛けずに対応することができますが、一定の移行期間が必要になります。また基本的には利用者ごとにMFA機器としてモバイルデバイスまたは、ハードウェアトークンが必要となります。

https://successjp.salesforce.com/article/NAI-000213

新たな機器を導入することなくMFAを導入するにはWinauthによる多要素認証の設定を行うことも可能です。

https://qiita.com/talomina/items/73172fa2c23af155d650

#将来を見据えた施策
サードパーティのIDプロバイダとSalesforceと連携させることにより、MFAを実現することもできます。併せてSSOによるIDの統合を行うことにより利用者の利便性を高めながら社内のID管理を一元化しすることができます。

#参考文献

https://www.salesforce.com/content/dam/web/en_us/www/documents/guides/mfa-quick-admin-guide-ja.pdf
[Python] 3.10.0


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/f6f5fd80-52e6-9e3f-5484-3a03fcbc6e54.png)

Major new features of the 3.10 series, compared to 3.9
Among the new major new features and changes so far:

PEP 623 -- Deprecate and prepare for the removal of the wstr member in PyUnicodeObject.
PEP 604 -- Allow writing union types as X | Y
PEP 612 -- Parameter Specification Variables
PEP 626 -- Precise line numbers for debugging and other tools.
PEP 618 -- Add Optional Length-Checking To zip.
bpo-12782: Parenthesized context managers are now officially allowed.
PEP 632 -- Deprecate distutils module.
PEP 613 -- Explicit Type Aliases
PEP 634 -- Structural Pattern Matching: Specification
PEP 635 -- Structural Pattern Matching: Motivation and Rationale
PEP 636 -- Structural Pattern Matching: Tutorial
PEP 644 -- Require OpenSSL 1.1.1 or newer
PEP 624 -- Remove Py_UNICODE encoder APIs
PEP 597 -- Add optional EncodingWarning
bpo-38605: from __future__ import annotations (PEP 563) used to be on this list in previous pre-releases but it has been postponed to Python 3.11 due to some compatibility concerns. You can read the Steering Council communication about it here to learn more.

bpo-44828: A change in the newly released macOS 12 Monterey caused file open and save windows in IDLE and other tkinter applications to be unusable. As of 2021-11-03, the macOS 64-bit universal2 installer file for this release was updated to include a fix in the third-party Tk library for this problem. All other files are unchanged from the original 3.10.0 installer. If you have already installed 3.10.0 from here and encounter this problem on macOS 12 Monterey, download and run the updated installer linked below.

## source
- https://www.python.org/downloads/release/python-3100/
PythonでExcel操作：フォルダ内の日付付き特定ファイルの取得と更新

#### 活用シーン
- Excelファイルを何度も修正していく必要があるケース(Ver.00~20など)。
- 修正前後で内容が大きく変わり、修正前のVerに戻る可能性があるため、ある一定期間、修正前後のファイルを保存しておく必要があるケース。
- 格納しているフォルダ内には特定ファイル以外の色んなファイルが保存されているケース

#### 方針

- 日付で指定すると、他の日付付きファイルのコンタミするので、あくまでも**<font color="red">「特定ファイル」のファイル名をキー</font>**として、まず**<font color="red">「特定ファイル_日付」だけ抽出したリスト</font>**を作成し、そこからソートし、新しい日付のファイルだけを取ってくる。
日付関数などを無理に使う必要もなく抽出できます。

#### 開発環境
　Jupyter lab
　Python3.9.6
　Windows

#### 実施内容

以下イメージ写真の通り、Book1という特定の日付ファイルがフォルダに入っており、
この中から、**一番新しい"Book1_2021-11-13.xlsx"**のファイルを取得して、
編集作業を行った後、**更新した日付(本日)："Book1_2021-11-14.xlsx"で保存**するということを実施した。
<font color="red">補足：コードでは更新後、一番古いファイルを削除する例も入っている。</font>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1980655/3322587e-c3c3-c8f9-d4d3-950d775ca31f.png)


```python:特定日付付きファイルの取得と更新
#必要ライブラリのインポート
from pathlib import Path
import os.path
dir_path=Path("~~~Excelファイルが格納されているフォルダを指定してください~~~")
#ファイルリストの作成
files=list(dir_path.glob("*.xlsx"))
#フォルダに格納されているExcelファイルの名前をリスト化
list_date=[]
for i in range(len(files)):
        file_name, ext = os.path.splitext(files[i].name)
        #タイトルに"Book1"がない場合はリストに入れない
        if "Book1" not in file_name:
            continue
        list_date.append(file_name)
#print(list_date)
#日付順の新しいソートし、要素０番目に指定
list_date_new=sorted(list_date,reverse=True)[0]

#新しい日付ファイルの読込み
os.chdir("~~~Excelファイルが格納されているフォルダを指定してください~~~")
import openpyxl as px
wb = px.load_workbook(f"{list_date_new}.xlsx")
#シートの指定
ws = wb["Sheet1"]

#----編集作業を実施----省略----#

#そのまま上書き保存
#wb.close()
#wb.save(f"{list_date_new}.xlsx")

#最新の日付に更新して保存
import datetime as dt
#更新した日の日付を取って保存
#例) 2021-11-14
dt_now = dt.date.today()
wb.save("Book1_"+f"{str(dt_now)}.xlsx")

#更新後に一番古いファイルを削除する。#Falseにしただけ
import os
list_date_old=sorted(list_date,reverse=False)[0]
os.remove(f"{list_date_old}.xlsx")
```

#### 解説

- フォルダ内のExcelファイル名をos.path.splitextで取得してリスト化する
- リストをsorted()でreverse=True/Falseで指定すると新しい順/古い順に並ぶ
- 先頭のリストを指定すれば所望(新しい日付)のファイルだけ取得できる
- 更新日付はdt.date.today()で取得した日付をファイル名に埋め込めばOK
Reactを基本からまとめてみた【16】【超基礎JSXの記法】

##JSXとは

- JavaScriptの拡張言語　≠　テンプレート言語
- HTMLライクな記述　+ JavaScriptの構文が使える
- jsxは最終的にReact要素を生成する

##なぜJSXを使うか

- React.createElementはReact要素を生成する式
- ２つの構文は等価 = 同じ結果となる

```sample.js

React.createElement(
  'button',
{className: 'btn-blue'},
  'click me!'
)

//jsxを使うとHTMLライクに書ける
<button className={'btn-blue'}>Click me!</button>
```
##JSXは何をしているのか

- コンパイル時

　　1.JSX ⇨ React.createElementの式に変換
　　2.React要素を生成

- React.createElementを使った構文は直感的ではない　<br>⇨ jsxを使うことで楽に記述ができる

```sample.js

<button className={'btn-blue'}>Click me!</button>
　　　　　　　⬇︎ 
　　　　　コンパイラ
　　　　　　　⬇︎ 
React.createElement(
  'button',
{className: 'btn-blue'},
  'click me!'
)
```
####コンパイルとは
コンパイルとは、プログラミング言語で記述されたソフトウェアの設計図（ソースコード）を、コンピュータが実行可能な形式（オブジェクトコード）に変換する作業のこと。

##JSXの基礎文法①
1.Reactライブラリをimportする
2.return分の中がjsxの構文

```sample.js
import React from 'react';

const BlueButton = () => {
  return (
   <button className={'btn-blue'}>
    Click me!
   </button>
  )
}
export defalut BlueButton;
```
##JSXの基礎文法②

1.キャメルケースで記述する
2.{}内で変数を扱える
3.閉じタグが必要

```sample.js
import React from 'react';

const Thumbnail = () => {
　　const caption = '写真'
   const caption = '/img/sample.png'
  
　return (
   <div>
     <p>{caption}</p>
     <img src={imagePath} alt={'写真'}
   </div>
  )
}
export defalut Thumbnail;
```
##特殊なJSXの構文

1.jsxは必ず改装構造　　最上位コンポーネントは並列にできない
2.React.Fragmentで囲む　HTMLタグとして出力されない
3.React.Fragmentで囲は省略形で書ける

```error.js
return (
  <p>React入門</p>
  <p>jsxの基礎文法</p>
)
```
```ok.js
return (
　<>
  <p>React入門</p>
  <p>jsxの基礎文法</p>
  </>
)
```


##ReactでのイベントやStyleの扱い

```App.jsx
import React from 'react';

const App = () => {
//ボタンをクリックした時の関数を書く
  const onClickButton = () => alert();
  const contentStyle = {
    color: 'blue',
    fontSize: '18px'
 };
  return (
    <>
     <h1 style={{color:'red'}}>こんにちは</h1>
     <p style={contentStyle}>お元気ですか?<p>
//波カッコの中に関数名を書く
     <button onClick={onClickButton}>ボタン</button>
    </>
  );
};
export default App;
```

##参考サイト
[モダンJavaScriptの基礎から始める挫折しないためのReact入門]
(https://www.udemy.com/course/modern_javascipt_react_beginner/learn/lecture/22332614#overview)
[#02 新・日本一わかりやすいReact入門【基礎編】JSXの記法]
(https://www.youtube.com/watch?v=gLbTluYSb_U&t=539s)
Grbl_Esp32 --> FluidNC

Grbl_Esp32がFluidNCにリニューアル。

インストールがとっても簡単に。

1．ESP32をUSBでPCに接続。
2．GithubのFluidNCのリリースから、最新版をダウンロード
　　https://github.com/bdring/FluidNC/releases
3．解凍して、使いたい接続方法（wifi/bluetooth）のフォルダからバッチファイルを起動
　（ここではwifiを使います）
4. 自動的にESP32にファームをインストール（簡単！）
5. wifiでアクセスポイント「fluidnc」を見つけて、パスワード「12345678」を入力
6. あとは設定画面で接続方法を設定（必要な場合）

マシンの設定（config設定）は、また後ほど
パブリックプレビューの Azure Container Apps を試してみた

## 背景と目的

Azure でコンテナーを使うサービスは色々とありますが、新たに Azure Container Apps というサービスが追加されたので Azure CLI で試してみました。

## 前提条件

コマンドの実施環境は、Mac + Azure CLI です。

```bash
$ sw_vers
ProductName:    macOS
ProductVersion: 12.0.1
BuildVersion:   21A559

$ az version
{
  "azure-cli": "2.30.0",
  "azure-cli-core": "2.30.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}
```

## Container Apps 用のエクステンションを Azure CLI に追加

```bash
az extension add \
  --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.0-py2.py3-none-any.whl
```

エクステンションの追加後は、このようになりました。

```bash
az version
{
  "azure-cli": "2.30.0",
  "azure-cli-core": "2.30.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {
    "containerapp": "0.2.0"
  }
}
```

## Container Apps を作成

公式ドキュメント内に利用可能なリージョンの記述を見つけられませんでしたが、トライアンドエラーの結果私の環境では以下のリージョンが利用可能なようでした。

* eastus
* northeurope
* canadacentral

```bash
# 環境変数をセットします
region=eastus
prefix=mnrcapp

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region

# Log Analytics を作成します
az monitor log-analytics workspace create \
  --resource-group ${prefix}-rg \
  --workspace-name ${prefix}-logs

# Container Apps 環境を作成します
az containerapp env create \
  --name ${prefix}-env \
  --resource-group ${prefix}-rg \
  --logs-workspace-id $(az monitor log-analytics workspace show \
  --resource-group ${prefix}-rg \
  --workspace-name ${prefix}-logs \
  --query customerId \
  --output tsv) \
  --logs-workspace-key $(az monitor log-analytics workspace get-shared-keys \
  --resource-group ${prefix}-rg \
  --workspace-name ${prefix}-logs \
  --query primarySharedKey \
  --output tsv)

# コンテナーを Azure Container Apps にデプロイします
az containerapp create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --environment ${prefix}-env \
  --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \
  --target-port 80 \
  --ingress external
```

ここで以下のメッセージが表示される場合は、コマンドを追加してから再度デプロイします。

```bash
MissingRegistrationForLocation: The subscription is not registered for the resource type 'containerApps' in the location 'eastus'. Please re-register for this provider in order to have access to this location.

# containerApps リソースタイプにロケーション情報を登録します
az provider register \
  --namespace Microsoft.Web
```

コンテナーアプリの FQDN を表示して、ブラウザでアクセスします。

```bash
# コンテナーアプリの FQDN を表示します
az containerapp show \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --query configuration.ingress.fqdn \
  --output tsv
```

## 参考

作成したリソースを削除します。

```bash:bash
# リソースグループを削除します
az group delete \
  --name ${prefix}-rg
```

参考サイトです。

https://azure.microsoft.com/ja-jp/updates/public-preview-azure-container-apps/

https://docs.microsoft.com/ja-jp/azure/container-apps/get-started?tabs=bash
ROS 処理速度を測る

ROS C++で処理速度を計測するときは以下のように書きます。

```c++:
ros::init(argc, argv, "delay");
ros::NodeHandle node_handle = new ros::NodeHandle();

ros::Time start = ros::Time::now();

/* 計測したい処理 */

ros::Time finish = ros::Time::now();

double delay = (finish - start).toSec();

std::cout << "Delay[/s]:" << delay << std::endl;
```

また,topicの遅延や周期などを測る場合は,`rostopic delay`や`rostopic hz`を使用します。
Go言語のテンプレートでテンプレート構文を無視する

Go言語のテンプレートはHelmやHugoなどで使われています。

テンプレートの中でテンプレート構文が使われているときに、たとえば下記のようになっている場合です。このとき、シングルクォート内の`{{.Request.Method}}`は無視したいものとします。

通常何もしないとテンプレートのレンダリング時にテンプレートとして解釈されてしまいます。

```
logging: '{{.Request.Method}}'
```

その部分を無視したいときには下記のようにします。

```
logging: '{{"{{"}}.Request.Method{{"}}"}}'
```

こうすることによって、初回のレンダリング時には`{{"{{"}}`が解釈され、結果`{{`が出力されます。`}}`部分も同様です。
シェルの種類 備忘録

#目的
シェルの種類 備忘録

#結論
3種類あった。
《sh》
《bash》
《zsh》

```shell:《sh》
　●もっとも古いシェル
　● ほぼ全てのUnixで利用できる標準的なシェル
　●機能は少ない。
```

```shell:《bash》
　● shを基本として機能を拡張したシェル
　● Linux環境でデフォルトのログインシェル
　●学習で使うならbashがオススメ
```

```shell:《zsh》
　● bashの機能を取り込み、 独自の拡張も追加
　●機能の豊富なシェル
　●講師はzshを使用
```

参照：もう怖くないlinuxコマンド。手を動かしながらlinuxコマンドラインを5日間で身に付けよう
Xamarinのアンドロイドアプリで、サービスからアプリを起動するとApplication.Currentがnullになる

Xamarinのアンドロイドアプリで、サービスからアプリを起動するとApplication.Currentがnullになる現象が発生し、以下の情報から、サービスのOnCreate時、以下の2行を

```
Forms.Init(this, bundle);
Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
```

で動作するようになった

情報元
https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/platform/native-forms


以下も参考にさせていただきました。

https://qiita.com/MizoTake/items/c69e5f060a0094ebe1ca
[WIP] Linux Tips

# sudoの初期設定
- [参考: sudoers覚え書き](https://qiita.com/progrhyme/items/6f936033b9d23efb1741)
- [参考: sudoのインストール](https://tkm2.hatenablog.com/entry/2019/02/15/201418)
- [参考: sudoの権限を設定するvisudoコマンド【Linuxコマンド集】](https://eng-entrance.com/linux-command-visudo)
- [参考: sudo のパスワードを入力なしで使うには](https://qiita.com/RyodoTanaka/items/e9b15d579d17651650b7)
- [参考: [Ubuntu]rootでログインできるようにする](https://tech-drive.net/pc/2018062701/)

# WSLのUbuntu環境で「apt」コマンドを使ってパッケージを更新／管理する
- [参考: WSLのUbuntu環境で「apt」コマンドを使ってパッケージを更新／管理する](https://atmarkit.itmedia.co.jp/ait/articles/1806/15/news048.html)
STM32L010F4P6と液晶、ACM1602K-NLW-BBWでHello Worldを表示 HAL(Mbed)


x 原因は、わからないが液晶がちらつく場合は、ウェートを調整してね!!


STM32L010F4P6でmbedを使い16文字2行液晶に
Hello Worldを表示するプログラム

74hc164シフトレジスターを使用した。
液晶とのピン数を節約した。信号線10本から
信号線3本に減らした。

1 CLK クロック端子(緑)
2 RSDATA RS端子とデータの共有端子(黄)
3 E 読み込み書き込み同期信号(青)

x 初心者コロシのVSCのcubeideに行く予定　いきなりドラゴンが出てくる


```c++



#include "mbed.h"

#define swdclk GPIO_PIN_5   //A4
#define swdio  GPIO_PIN_7   //A6
#define en     GPIO_PIN_4   //A3

#define DW(AAA,BBB)  HAL_GPIO_WritePin(GPIOA,AAA,BBB)

GPIO_PinState bi1[]={GPIO_PIN_RESET,GPIO_PIN_SET};

void seg1(char v,int rs)
{
    for(int jj=0;jj<8;jj++){
        if( (v<<jj) & 0x80 ){
                DW(swdio,GPIO_PIN_SET);   //ビットが1 
        } else {
                DW(swdio,GPIO_PIN_RESET); //ビットが0
        }//endif
        DW(swdclk,GPIO_PIN_SET);DW(swdclk,GPIO_PIN_RESET); //clk
    }//for
    DW(swdio, bi1[rs] );
    DW(en,GPIO_PIN_SET);   HAL_Delay(1); //ビットが1 
    DW(en,GPIO_PIN_RESET);               //ビットが0      
}//seg1

//文字列の表示 nana_seg
int ns_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        seg1( *str1 ++ , 1  );

    } //while

    //戻り値
    return(0);
}//ns_printf

//GPIOの初期化
void GPIO_INIT1() {

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}//GPIO_INIT1

int lcd_int[]={
  0x30,0x30,0x30,0x38,0x08,0x01,0x06,0x08+0x04
};//lcd_init

//メイン関数
int main() {

    //クロックの初期化
    HAL_RCC_DeInit();

    //CPUへの電圧の設定
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//1.8V

    // 32mz
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;
    RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);

    //GPIOの初期化
    GPIO_INIT1();

    //GPIOの初期化
    DW(en,GPIO_PIN_RESET);     //ビットが0 
    DW(swdclk,GPIO_PIN_RESET); //ビットが0 

    //液晶の初期化
    for(int ii=0;ii<8;ii++){ 
        seg1( lcd_int[ii] , 0);HAL_Delay(2);
    }//for

    //画面クリア
    seg1(   0x01  , 0  ); 
    HAL_Delay(1000);

    seg1( 0x80+0x00 , 0  ); //1ライン目にカーソルを移動
    ns_printf("Hello World !");HAL_Delay(500); //debug

    //無限ループ
    while(1){
    }//while

}//main





```
DevRel Japan CONFERENCE 2021を覗いたので、その感想

https://devrel.tokyo/japan-2021/

https://devrel.tokyo/japan-2021/view/

> DevRel/Japan CONFERENCEはDevRel Meetup in Tokyoによるコミュニティ主催のカンファレンスです。日本語セッションのみで開催されます。
DevRel Meetup in Tokyoは2015年9月よりはじまった日本唯一のDevRel（Developer Relations）に関するコミュニティです。DevRelに関する情報共有、認知度向上を目指して活動しています。

ということで覗いたセッションのメモです。

## トークテーマ：ライティング (BLOG / DOC)

https://twitter.com/devrelTokyo/status/1459367086967312389?s=20

https://togetter.com/li/1802976



- 採用目的ではなく「技術力もあるんだから、知見を外部に共有して業界全体を良くしていこう」

- 「会社が知られててもその会社の働く環境が知られているかは別。こういう人と働きたい、みたいな情報がないとエンジニアの気持ちは動かないと思う。」

- クラスメソッドは書きたい人が書いているが、エンジニアにブログを書いてもらうために？
    - 「なぜブログをウチがやっているか、目的を整理、浸透させるカルチャー醸成＋マネージャーに、どれくらいの量、露出したいか、具体的なムーブをつくる」
    - 他アドカレみたいな企画特集。盛り上がる月間

- 効果測定とか、モチベーションは:
    - 全員が書かなくてよい、全体の2~3割。でも、その人達に、評価にも自分だけでない会社、業界へのプレゼンスが入ってくるので、成果になるようにする。



業務時間に書けるのはもう大事。3万本はすごい。誰かだけじゃなくて何人も毎日書かれてるっていうのは本当に浸透しているのだろうなあという感想。
備忘録。通常業務やってて残していくナレッジをただ書いているだけで意味あるよなという気持ち。


## 女性開発者のキャリアパスとしてのエバンジェリストのススメ

- 「恩返し」
    - 自分も学びと恩返しのサイクルつくりたい
- 「推し」
- 「沼」
- 「(褒め言葉の)変態」
    - 私も「芸人」目指したい...
- 「これからエバンジェリスト目指すには？」
    - コミュニティ行ってみる入ってみるが最短
    - 自分が推しの中で貢献できるところふやしたい
- こどもの安全と健康を考えながら想定できることを想定。
    - 考えたくないけど、ありえる。「こどもが熱出す」vs「大事な登壇」。普段からホント大事
- 「納豆は大豆に戻れない」(腐女子になったらもう戻れないという話。= エバンジェリスト的沼はもう抜けられない)
    - 名言


## 各Track

### TrackA
<iframe width="860" height="484" src="https://www.youtube.com/embed/ZNfqeU-uqp0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### TrackB
<iframe width="860" height="484" src="https://www.youtube.com/embed/ZkTSLFexjqo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### TrackC
<iframe width="860" height="484" src="https://www.youtube.com/embed/n7Obj5hsC6g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 他リンク

https://note.com/n0bisuke/n/n8b70402dd99d

https://note.com/keitafukui/n/n3bc85b1ca3f0

感想文まで、以上です。
ActivityResultContractのリクエストと結果の処理をより強く結びつかせる

ActivityResultContractsの仕組み、個人的にちょっとどうかな？と思っているところがあります。
それは、リクエスト内容と、結果の処理の結びつきが弱く、余計な自由度が残されてしまうところです。

例えばパーミッションのリクエストの場合、以下のように記述します。

```kotlin
private val launcher =
    registerForActivityResult(RequestPermission()) {
         // 結果の処理
    }
...
// リクエスト
launcher.launch(Manifest.permission.CAMERA)
```

ここで、リクエストしているパーミッションと、その結果の処理は紐付いています。にもかかわらず、コールバックの登録時点でリクエストするパーミッションは決まっておらず、lauchをコールする時点で自由度が残されています。ここで間違って異なるパーミッションを指定してしまうと意図した動作となりません。
registerをコールした時点でこの対応関係が固定できないところがちょっとモヤモヤします。

もちろん、リクエスト内容が動的に変わりうるなど、自由度がないと困るケースもあるので、そちらに倒されているのだとは思いますが、もうちょっとうまいやり方はないものかと思ってしまいます。

# 解消する拡張関数

ActivityとFragmentそれぞれに拡張関数を作ってしまえば良いでしょう。

前述のパーミッションリクエストの例で言えば

```kotlin
private val launcher =
    registerForActivityResultWrapper(RequestPermission(), Manifest.permission.CAMERA) {
         // 結果の処理
    }
...
// リクエスト
launcher.launch()
```

このように、リクエストとその結果の処理の対応関係を固定してしまうことができます。
余計な自由度がなくなりシンプルにすることができます。

実装は以下

```kotlin
fun <I, O> Fragment.registerForActivityResultWrapper(
    contract: ActivityResultContract<I, O>,
    input: I,
    callback: ActivityResultCallback<O>
): ActivityResultLauncherWrapper<I> =
    ActivityResultLauncherWrapper(registerForActivityResult(contract, callback), input)

fun <I, O> Fragment.registerForActivityResultWrapper(
    contract: ActivityResultContract<I, O>,
    registry: ActivityResultRegistry,
    input: I,
    callback: ActivityResultCallback<O>
): ActivityResultLauncherWrapper<I> =
    ActivityResultLauncherWrapper(registerForActivityResult(contract, registry, callback), input)

fun <I, O> FragmentActivity.registerForActivityResultWrapper(
    contract: ActivityResultContract<I, O>,
    input: I,
    callback: ActivityResultCallback<O>
): ActivityResultLauncherWrapper<I> =
    ActivityResultLauncherWrapper(registerForActivityResult(contract, callback), input)

fun <I, O> FragmentActivity.registerForActivityResultWrapper(
    contract: ActivityResultContract<I, O>,
    registry: ActivityResultRegistry,
    input: I,
    callback: ActivityResultCallback<O>
): ActivityResultLauncherWrapper<I> =
    ActivityResultLauncherWrapper(registerForActivityResult(contract, registry, callback), input)

class ActivityResultLauncherWrapper<I>(
    private val launcher: ActivityResultLauncher<I>,
    private val input: I
) {
    fun launch() = launcher.launch(input)
    fun launch(options: ActivityOptionsCompat) = launcher.launch(input, options)
    fun unregister() = launcher.unregister()
    fun getContract(): ActivityResultContract<I, *> = launcher.contract
}
```

拡張関数をつくってすっきり、と言いたいところですが、今度はWrapperはないだろうとモヤモヤし始めました。
良い名前があれば教えてください。
CentOS7で「lspciコマンド」と「lsusbコマンド」が使えない時の対処法

###概要
CentOS7を最小構成でインストールすると「lspci」と「lsusb」が使えないらしい。

###捜索
とりあえず`yum search `で探してみることに...

```bash
$ yum search lspci
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: mirrors.nipa.cloud
 * extras: ftp.riken.jp
 * remi-php73: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
警告: 一致するものが見つかりません: lspci
No matches found
```
無かったので、`yum provides`で調べてみます。

```bash
$ yum provides lspci
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: mirrors.nipa.cloud
 * extras: ftp.riken.jp
 * remi-php73: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
pciutils-3.5.1-3.el7.x86_64 : PCI bus related utilities
リポジトリー        : base
一致          :
ファイル名    : /usr/sbin/lspci
```
ありました。
`pciutils`←これですね。

###pciutilsのインストール

```bash
$ yum install -y pciutils
インストール:
  pciutils.x86_64 0:3.5.1-3.el7

完了しました!
```

###lscpiの実行
```bash
$ lspci
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
00:02.0 VGA compatible controller: VMware SVGA II Adapter
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01)
00:06.0 USB controller: Apple Inc. KeyLargo/Intrepid USB
00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)
```

成功。続いて`lsusb`を`yum provides`で検索

```bash
$ yum provides lsusb
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: mirrors.nipa.cloud
 * extras: ftp.riken.jp
 * remi-php73: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
usbutils-007-5.el7.x86_64 : Linux USB utilities
リポジトリー        : base
一致          :
ファイル名    : /usr/bin/lsusb
```
###usbutilsのインストール
```bash
$ yum install -y usbutils
インストール:
  usbutils.x86_64 0:007-5.el7

完了しました!
```

### lsusbの実行
```bash
$ lsusb
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
```

###参照
https://web-memori.hatenablog.jp/entry/linux-lspci-comannd
Virtualbox Host-only Adapter 使えるIPレンジが制限されるようになっていてハマった話

# Virtual Boxの更新をしたら、、、
導入時に単発でdebファイルを落としてくる方法をつかっていた関係で、手元環境で使っているVirtualBoxが6.0系のままだったことに気が付きまして。
これはまずいと6.1に更新したのですが、、、ターミナルからのSSH受付用に仮想マシンに用意していたHost-only Adapter(10.0.0.0/24)が使えなくなりました。。

# 何が起こったの？
https://www.virtualbox.org/manual/ch06.html#network_hostonly
https://www.virtualbox.org/ticket/20626
https://www.virtualbox.org/ticket/20636

結論としては、最近のアップデートで、Host-only Adapterに指定して良いアドレスが、192.168.56.0/21に限定されたんだそうです。。

私の症状としては、アップデート後にホスト側でip addrを叩いてもvboxnet0がアドレスを取れていない、Virtual BoxでHost Only Adapterのアドレスをいじろうとすると”E_ACCESSDENIED (0x80070005)”というアラートだけ出る、というものでした。
結局上記を調べ、以下のファイルを追加したら再度10.0.0.0/24を使わせてもらえるようになりました。

```
# cat /etc/vbox/networks.conf
* 10.0.0.0/8 192.168.0.0/16 172.16.0.0/16
```

これ、頭に "\*"をつけるのが正しい書式らしいです。
allowが"\*" 、denyが"#"なんだそうで。
マニュアルに書いてあるのですが、最初  "*"は箇条書きか何かだと思って無視して記載していて、通らないな、、とハマってました。。

# とりあえず
これだけの話ではあります。
別の迂回作として、物理IFに対して「ブリッジ」でつなぐ手もあるのですが、現状NATで使っているIFを置き換えるとGW周りのIP体系と干渉してしまうし、使ってない空きIFがあればそれ使う手もあったのですがあいにくなく、と。
dummy interfaceやbridgeインタフェースを作成してそれを使う方法も試行錯誤しましたが、結局まっとうに動く方法は組めませんでした。
Host-only Adapterは唯一無二の機能なんだなぁと再認識した今日この頃でした。
MRTK Standard Shader で ArgumentException: Could not find MaterialProperty: '_InstancedColor' が発生した場合の対処法

# はじめに
MRTK ( Mixed Reality Toolkit for Unity ) を使用して開発をしていたところ、Unity Editor 上で Shader のプロパティが編集ができない事象が発生しました。以下、画像のように Unity Editor の Inspector 上で Shader プロパティを展開しようとしても何も表示されない状況です。

<img width="1000" alt="image.png (17.7 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2021/11/14/10862/0403a34b-3114-412d-b004-2c856962f6a4.png">

# 開発環境
- Unity 2019.4.11f1
- MRTK v2.5.1 ( Installed By Mixed Reality Feature Tool )

# エラー内容

コンソールタブを見てみると、以下エラーが発生していることが判明しました。

> ArgumentException: Could not find MaterialProperty: '_InstancedColor'

<img width="1000" alt="image.png (114.2 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2021/11/14/10862/92410299-9f6c-458b-a031-53572878e279.png">

MRTK の GitHub Issue を検索してみると、MRTK Standard Shader の instanced color property は  _Color で _InstancedColor ではないので、エラーが発生しているようです。

# 解決策

MRTK Code 内でエラーが発生している場合は、FindProperty("_InstancedColor") を FindProperty("_Color") に置き換えると良いと書いてありました。

> <img width="1000" alt="image.png (104.8 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2021/11/14/10862/8db2e77a-d0d2-47fc-a064-6dbd67aa6e4e.png">
>
> https://github.com/microsoft/MixedRealityToolkit-Unity/issues/4188#issuecomment-872952279

エラーを見ると、以下ファイルが呼び出し元になっています。

> Library/PackageCache/com.microsoft.mixedreality.toolkit.foundation@3093b5b13b68-1636644842558/Core/Inspectors/MixedRealityStandardShaderGUI.cs:212


FindProperty メソッドが呼び出されていますが、引数には変数が入っています。

```
212 : instancedColor = FindProperty(Styles.instancedColorName, props);
```

変数の宣言元を確認すると、32行目に対象コードを発見しました。

```
protected static class Styles
{
    public static string instancedColorName = "_InstancedColor";
```

こちらのソースコードを以下内容に変更します.

```
protected static class Styles
{
    public static string instancedColorName = "_Color";
```

上書き保存し、Unity Editor に戻ってみるとエラーが解消し、Shader のプロパティ値を確認することができました。

<img width="1000" alt="image.png (147.5 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2021/11/14/10862/c0db51df-4c9e-4d3d-9996-e9dfc6395f0f.png">

今回のプロジェクトでは MRTK パッケージを Mixed Reality Feature Tool を用いてインポートしているため、``Library/PackageCache`` がクリアされるたびに編集が必要になりますが、一時対応策としてメモしておきます。
Kotlin coroutineのasync/awaitとwithContextについて

## 経緯
coroutineを使用していてなんとなく疑問に思っていたのが、
async/awaitとwithContextの違いについてでした。
少し調べてみましたが、かなり不足のある記事になると思うので、加筆前提で投稿しようと思います。

## coroutineとは
非同期処理のできるスレッドのようなもので、中断・再開などができます。
軽量な点がかなり嬉しいですね。
余談ですが昔Unity C#で開発していた時にもcoroutineを頻繁に使用していました。
あちらは次フレームまでの待機などでしたが。

## サンプル

```kotlin
fun sample(){
    GlobalScope.launch {
        asyncTest()
        withContextTest()
    }
}

// 1秒待ってから1 <= n <= 99 のn：Intを返却する
private fun getRandomNum(): Int {
    Thread.sleep(1000)
    return (1..99).random()
}

private suspend fun asyncTest(){
    Log.d("test", "asyncTest start.")

    val hoge = GlobalScope.async(Dispatchers.Default) {
        getRandomNum()
    }.await()

    Log.d("test", "asyncTest finish. num is $hoge.")
}

private suspend fun withContextTest() {
    Log.d("test", "withContextTest start.")

    val hoge = withContext(Dispatchers.Default) {
        getRandomNum()
    }

    Log.d("test", "withContextTest finish. num is $hoge.")
}

```

上記のサンプルを実行した場合、
asyncTest()、withContextTest()の出力結果（順）に違いはほとんど見られません。
withContextの方が少しパフォーマンスが良い感じでしょうか。

```
2021-11-14 10:46:29.211 9618-9645/com.example.testapplication D/test: asyncTest start.
2021-11-14 10:46:30.217 9618-9646/com.example.testapplication D/test: asyncTest finish. num is 53.
2021-11-14 10:46:30.217 9618-9646/com.example.testapplication D/test: withContextTest start.
2021-11-14 10:46:31.222 9618-9646/com.example.testapplication D/test: withContextTest finish. num is 76.
```

## 違いについて
ここで思い出したのが、以下の違い。

async
・新規コルーチンを開始する

withContext
・スレッドを切り替えるよう指示ができる

参考：[コルーチンを開始する](https://developer.android.com/kotlin/coroutines-adv?hl=ja#start)、[withContext() のパフォーマンス](https://developer.android.com/kotlin/coroutines-adv?hl=ja#perf)

asyncは新たにコルーチンを開始し別のスレッドで処理を行い
withContextはコルーチンを作成せずスレッドを切り替えて処理を行う
ということですね。

asyncはawait()を呼ぶことで処理を実行し結果を得ることができます。
withContextの場合はその場で処理を待つイメージでしょうか。

サンプルを少しいじるとわかりやすいかも。

```kotlin
private suspend fun asyncTest() {
    Log.d("test", "asyncTest start.")

    val hoge = GlobalScope.async(Dispatchers.Default) {
        getRandomNum()
    }

    val fuga = GlobalScope.async(Dispatchers.Default) {
        getRandomNum()
    }

    val totalNum = hoge.await() + fuga.await()
    Log.d("test", "asyncTest finish. totalNum is $totalNum.")
}

private suspend fun withContextTest() {
    Log.d("test", "withContextTest start.")

    val hoge = withContext(Dispatchers.Default) {
        getRandomNum()
    }

    val fuga = withContext(Dispatchers.Default) {
        getRandomNum()
    }

    val totalNum = hoge + fuga
    Log.d("test", "withContextTest finish. totalNum is $totalNum.")
}

```

```
2021-11-14 11:44:08.527 13859-13884/com.example.testapplication D/test: asyncTest start.
2021-11-14 11:44:09.531 13859-13885/com.example.testapplication D/test: asyncTest finish. totalNum is 71.
2021-11-14 11:44:09.531 13859-13885/com.example.testapplication D/test: withContextTest start.
2021-11-14 11:44:11.537 13859-13885/com.example.testapplication D/test: withContextTest finish. totalNum is 117.
```
asyncはおよそ1秒で実行されていますね。並列。withContextはおよそ2秒なので直列ですね。

## 結論
並列処理を必要とする場合はasync/await、そうでない場合はwithContextを使用するのが良さそうです。
少しスッキリしました。
wslのkali linuxでCTFできる環境を作る

覚書き程度なのでとても適当

# 前提

- WSL2を使う

##### 1. Windows Store からkali linuxを入れます

https://www.microsoft.com/store/productId/9PKR34TNCV07

##### 2. 諸々のupdateとかをします

wslの初期設定のメモっぽいものは過去に書いたのでよかったらどうぞ。

https://qiita.com/U1F419/items/bc3f8b45668f39492416

##### 3. kali-linux-default を入れます

https://www.kali.org/docs/general-use/metapackages/

##### 4. wslgを有効化してGUIアプリが動かせるようにする（場合によってはいらない）

`xeyes` や `wireshark` などのGUIアプリが動くか確認し、動かなったら↓の手順をもとにwslgを有効化する。

これまではXサーバーを入れてうんにゃかしないといけなかったけど、WSLがすごい強くなっていたので、何もしなくても動くようになっているかも。（Windows Insiderに入っていたらなっていそう）

https://github.com/microsoft/wslg#installing-wslg

筆者は管理者権限のcmdで `wsl --update` を実行したら動くようになりました。↓これ

https://github.com/microsoft/wslg#install-instructions-existing-wsl-install
NuxtでModule Error

#Module Error
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034987/c4d23366-1be5-f372-f565-7d548a2923b9.png)

#解決方法

```
npx prettier --write "**/*.{vue,js}"  /*linting folders in nuxt */
```
kotlinでAndroidアプリの画面遷移


備忘録としてkotlinメモ

結論を言えば、Insertを使えば画面遷移が実現可能で、対象のコードだけで言えば以下2行です。

```
val intent = Intent(this,SecondActivity::class.java)
startActivity(intent)
```

## ファイル作成の手順、マニフェストファイル　メモ
まず画面を準備

画面１

```MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // viewの取得
        val btnStart :Button = findViewById(R.id.btnStart)

        // ボタン押下で次の画面へ
        btnStart.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }
    }
}


```

画面２

```SecondActivity.kt
package com.example.sampleintent

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        // View取得
        val btnBack : Button = findViewById(R.id.btn)

        //　タップアクション
        btnBack.setOnClickListener {
            finish() // 元画面に戻る（画面のスタックしている状態を外すメソッド）
        }
    }
}
```

ファイルの作成方法は、Fileタブから生成

![スクリーンショット 2021-11-14 1.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174952/dbeaea18-e3ec-6877-d90f-8caaf403315a.png "スクリーンショット 
2021-11-14 1.15.18.png")


上記方法で作成していれば自動生成されるので特に気にする必要はないのですが、リネームなどした場合には以下のようにAndroidManifest.xmlには手動で追加、修正する必要がある

```<activity android:name=".画面のクラス名"></activity>```　<= これの追加が必要

以下実際のソース

```AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.sampleintent">

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.SampleIntent">
        <activity android:name=".SecondActivity"> // 画面２のクラス
        </activity>
        <activity android:name=".MainActivity">　// 画面１のクラス
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
```