OmniAICreator/Qiita-1.07M huggingface dataset:
RailsでITF規格のバーコードを作ろうとした話

# 結論
~~できなかった。（何か方法やライブラリがあれば教えてください。。。~~



### 経緯
- 業務の中でITF規格のバーコードの生成が必要になった
- 色々調べてみたところ`Barby`というライブラリを使うとバーコード生成が簡単にできる
- 流通する国や商品の種類などによってバーコード自体の規格も違うことが分かった
- ~~残念ながら`Barby`だと今回必要なITF規格のバーコードが生成できないことが分かった~~

## 代替案
- JavaScriptで実装する

バックエンドでの生成はいったん諦めて[JsBarcode](https://github.com/lindell/JsBarcode)というJavaScriptのライブラリを使用して実装することに決めた。
### 実装
npmコマンドを実行
```
npm install jsbarcode --save
```

```erb:sample.erb
<img id="barcode"/>
<%= hidden_field_tag 'barcode_number', @barcode_number ||= nil %>

<script>
  barcode_number = document.getElementById("barcode_number").value;
  JsBarcode("#barcode", barcode_number, {
  format: "ITF",
  width:40,
  height:1200,
  displayValue: false
});
</script>
```
### 解説
本来であればRails側で画像のURLを生成し`erb`で描画したいところではあったが、
今回は上手くいかなかったので
- controllerから値だけ受け取る
- `JavaScript`で取得
- `JsBarcode`を実行する

結構簡単に実装できました。
optionでバーコードの大きさや見た目を調整することができ、formatで規格も指定することができる。
`displayValue`設定することでバーコード自体の下にバーコードから読み取れる値を表示することもできる。

## 最後に
バーコードってややこしい。。。
Railsを用いてITF規格のバーコードを生成する方法をご存じの方がいらっしゃいましたら教えていただけますと幸いです

追記 2022/11/28
実装可能なことがわかりました、また別記事で紹介します
AWSのEC2でdocker-composeを使う

# 概要
初めての本番環境構築。
AWSのfargateで立ち上げようとしたが、本番環境もAWSもほぼ未経験なので途中でつまった。とりあえずEC2で立ち上げることに。

ここで書かれているものは後にstart.shなどに追加しなけれなばならない。

# 環境
Frontend : Node.js 18-buster-slim  Vue.js 3.2.13
Backend : Django 4.1 Python3.10.6
Web server : Nginx 1.23.1
Database : mariaDB 10.8.3

# インストール

まずdockerとdocker-composeをインストール
gitをインストールしてからgit cloneする。

# インバウンドルールの変更

セキュリティグループ　→ インバウンドルールで
カスタムTCPでfrontのポート番号を追加する。
webサーバのポート番号も同様に追加。

# Frontend (vue)
## パーミッションの変更

以下のようなエラーがでたら

```
Syntax Error: Error: EACCES: permission denied, mkdir '/code/node_modules/.cache'
```

`chmod`でパーミッションを変更する

```
chmod 700 /code/node_modules
```

## ajax通信

デフォルトでajax通信すると以下のようなエラーが出る

```
POST http://localhost:8000/api/v1/auth/jwt/create net::ERR_CONNECTION_REFUSED
```

localhostではなくパブリックIPにする。
(もっといい方法がありそうな気がする?)

```vue:src/main.js:
axios.defaults.baseURL = "http://3.112.56.45:8000/api/v1/";
```

# Backend (django)

```python:config/settings.py
# 本番環境はFalseにする
DEBUG = False

# 本番では'*'にする
# 運用するサーバーが決まれば、hogehoge.com や '100.100.100.100' などを入力する
ALLOWED_HOSTS = ['*']
```
Lens Protocol🌿とは？

# Lens Protocolとは？🌿

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/c9f06a87-de4b-7d25-9ba7-7b0ba2a5d66a.png)

## イントロダクション
Lens Protocolは、Polygon Proof-of-Stake ブロックチェーン上のWeb3ソーシャルグラフプロトコルです。 クリエイターが自分自身とコミュニティの間のリンクを所有できるように設計されており、完全に構成可能なユーザー所有のソーシャルグラフを形成します。

## Lens Protocolは既存のソーシャルグラフと比べてどのように違うのか？
Web2では全て独自のデータベースからデータを読み取ります。よって、プロフィールやFollow・Follower、投稿などのコンテンツは特定のネットワークの中のみで存在することができます。
Lens Protocolでは全てのデータをユーザーが所有するオープンなソーシャルグラフを作成することが可能です。ユーザーは自分のデータを所有しているため、Lens Protocol上に構築されたアプリケーションにデータを持ち込むことができます。

# 主要コンセプト

## Profile
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/8cb9e802-6099-0826-8152-cee9ef46ebd4.png)
Profile NFTは、Lens Protocolの主要なオブジェクトです。 自分のコンテンツをコントロールできるのは、このNFTに対する所有権です。 個々のアドレスはProfileNFTを所有し、アドレスには複数のProfileNFTを含めることができます。Profile NFTには、すべての投稿、ミラー、コメント、およびその他の作成したコンテンツの履歴が含まれています。

## Publication
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/da8658c8-9970-6337-b1ef-0d6b3e3df7d9.png)
クリエイター、キュレーター、およびユーザーによって作成されたオリジナルのコンテンツ、コメント、およびミラーのすべてのことです。Publicationには、投稿、コメント、ミラーの3つの主要なタイプがあります。

## Comment
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/8e7a138d-3cd9-3084-caf9-991184475631.png)
Commentは他のユーザーのPublicationにコメントをする機能です。Publicationと同様にCommentはユーザーのProfile NFTに存在するため、ユーザーが完全に所有しています。

## Mirror
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/57e526cf-9c1a-6993-1b51-1a3b4e41899e.png)
Mirrorは他のユーザーのPublicationを拡散したり、再投稿したりする機能です。

## Collect
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/b1d81fc8-0115-a932-4bc0-ffc85c50c91a.png)
クリエイターはLens Protocolを介してコンテンツを所有しているため、フォロワーがそのコンテンツを購入できるようにすることができます。

## Follow
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987391/e6723226-4f89-c3e4-7bfd-974326630206.png)
Lens Protocolでの「フォロー」は、Web2ソーシャルアプリケーションでのフォローとは異なります。 ユーザーがLens ProtocolのProfileをフォローすると、クリエイターやコミュニティが追加の価値を付与したFollow NFTが与えられます。

# 最後に
![Frame 9 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/87f2a488-c5cd-549d-f07f-01b44a1317b8.png)
<b>Veroo</b>は、Blockchain技術を活用した「想いの巡るグルメSNSアプリ」です。食に対する熱量、例えばラーメンがめちゃくちゃ好きで年間400杯食べているとか、変態的に具材にこだわった中華料理を作っているなどのような、今まで直接お金にはならなかった食に対する情熱や熱量、その裏側にある想いがトークンを使うことで巡る世界。自分のラーメンに費やす熱量がコミュニティに承認される。自分がほんとにいいと思って作った食べ物がコミュニティで広まる。Verooは単なるSNSアプリではなく、クリエイターたちの想いが紡がれるソーシャルグルメアプリです。

##### Homepage: https://veroo.xyz/
##### Discord URL：https://t.co/VoT0gpsflA
モチベーションが落ちた時の対処法

# はじめに
みなさんはモチベーション管理に関して普段何かされていることはありますでしょうか？
人それぞれモチベーションの上下は必ず存在しており、想定と違う事象が発生した場合や仕事上のミス、私情によるトラブルなどモチベーションの低下につながる出来事というのは多岐多様に渡りますよね。
本日は普段と少し趣向を変えて、モチベーションが落ちた際に私が行っている習慣をご紹介したいと思います。
※あくまで私自身が現状最善だと思う習慣ですので、参考程度に参照いただけますと幸いです。

# 習慣その１：本を読む
私がモチベーションが落ちたと感じた際に必ず行っている事の1つ目は、本をとにかく読む事です。
悩んだ時に本を読む、悲しい時に本を読む、辛い時に本を読む。
生きていれば日々選択の毎日ですが、本を読む事でこの繰り返される日常的な選択肢を広げることができる最も簡単な手段の一つです。
選択肢の多さは間違いなく現在、並びに未来の自分を助けてくれます。
繰り返しになりますが、悩んだ時、悲しい時、辛い時など負のスパイラルから抜け出す為に、とにかく本を読む事をおすすめします。

# 習慣その２：散歩する
次にモチベーションが落ちた際に行っている事は、散歩です。
散歩のタイミングは朝起きてすぐの早朝だったり、ランチタイムだったりと時間はまばらです。
閉鎖的な空間にずっと身を寄せていると気分も落ち込みがちですよね。
また、ひとつの事に集中することももちろん大切なのですが、根を詰めすぎた結果柔軟な発想を見失いがちだったりもします。
そんなタイミングで外の空気を取り入れ一度思考をリセットすることで、モチベーションの回復にもつながりますし、直面している問題への打開策や現状の感情に対しての気付きなど、柔軟な発想を取り戻すことに繋がると思います。
もし外出が難しいようでしたら、窓を空け、外の空気を取り入れるだけでも違うかもしれません。
短い時間でも良いと思いますので、一度リセットする為に外の空気を積極的に取り入れてみてはいかがでしょうか。

# 習慣その３：お茶を入れる
三つ目にご紹介するのはお茶を入れるという事です。
これは弊社の社員にも紹介したことがあるのですが、すれ違いにより感情の起伏が激しくなったり、気分が落ち込んだ場合にはお茶を入れることをおすすめします。
この時入れるお茶というのはなんでも大丈夫だと思います、香りの高い紅茶を入れてもいいと思いますし、緑茶でも良いかと思います。
とにかくお茶を入れるということが大切です。
概念は散歩と似ているのですが、負の感情が自身を支配していると感じた時、自分自身を客観的に見る為にその場を離れる必要があると思います。
ですが業務中などタイミングによっては長い間離れるのは難しいですよね。
ではお茶を入れるだけであればどうでしょう、たかだか3分ほど離れるだけで済むというわけです。
この3分が非常に重要で、一見短いようにも感じますが、3分もあれば自身の状況を一度客観的に見る為には十分な時間と言えます。
お茶を入れるという手軽さも含め、中々ご自身の状況を整理することができないという方は取り入れてみてはいかがでしょうか。

# 習慣その４：自分の状況を第三者にぶつける
さいごにご紹介するのは自分の状況を第三者にぶつけてみるという事です。
これは親しい間柄でないと難しいかもしれませんが、自分の状況を客観的に評価する為には誰かに状況をぶつけてみることも重要です。
モチベーションや気持ちが落ちた原因を必ずしも一人で考える必要はないはずです。
親しい友人や家族、同僚など相談ができる状況であれば、日常的に自身の悩みや問題をぶつけ一緒に考えてもらうことができれば、これほど頼もしい事はありません。
是非モチベーションが落ちて辛い際には選択肢の一つに入れてみてはいかがでしょうか。

# さいごに
いかがでしたでしょうか、私自身もよくモチベーションが落ちることがあります。
そんな時は上記方法でモチベーションの回復に努めますが、是非みなさんが普段からやられているモチベーションの対処法をコメント等で教えていただけると嬉しく思います。
jestのソースコード見てたら何じゃと思った話


https://github.com/facebook/jest/blob/main/packages/jest-each/src/__tests__/template.test.ts#L81

jestのソースコードに


> ʅ(ツ)ʃ 

とか

> ☝(ʕ⊙ḕ⊙ʔ)☝  

とか

> (๑ఠ‿ఠ๑)

とかある。

なんでかよく調べてみたら
[もともとjestはマルチバイト文字でコケていたらしい](https://github.com/facebook/jest/pull/11575)
直してくれて感謝です。(*´▽`人)
twitter stream apiで遊ぶ

# 概要
　twitter stream apiでワールドカップのtweetをpostgreに格納してみた。

# 準備
　nodeは必須。
  npm i twitter-api-sdk
  npm i pg
  で、postgresqlは11だが、これは設定してあるのが前提
　table名はtweetで設定、id[serial],created_at[timestamp],author_id[varchar],text[varchar]
　ここまであれば、以下のファイルを次のコマンドで動かすだけ
　node pgst.js

# source
```pgst.js
Tw = require('twitter-api-sdk');
client = new Tw.Client(process.env.twitter_bearer_TOKEN);
const pg = require('pg');
pgclient = new pg.Client({database: 'yourdbname'});

async function main() {
  await client.tweets.addOrDeleteRules(
    {
      delete: {
         ids: ['1595343805821358081' ,
              '1595372533401866241' ]
      }
    }
  );
  const rules = await client.tweets.getRules();
  console.log(rules);
  const stream = client.tweets.searchStream({
    "tweet.fields": ["author_id", "geo","created_at"],
  });
    let cc = 0;
    const sql ="INSERT INTO tweet (created_at, author_id, text) VALUES ($1, $2, $3)"
    await pgclient.connect();
  for await (const tweet of stream) {

      msg = tweet.data.text.replace(/\n/g,"");
      tm = tweet.data.created_at;
      aid = tweet.data.author_id;
      let values = [tm,aid,msg];
      //console.log("----- insert start--")
      const res =await pgclient.query(sql,values);
      process.stdout.write("count="+cc+" "+msg.substring(0,80)+"\r");
      cc = cc+1;
  }
}

main();
```

# 動作に関する条件
　最初にclient.tweets.addOrDeleteRulesでルールを設定してあると、2回目に実行する場合はそれを再利用する。このため、上のコマンドではdeleteしているが最初は
　add:[
  { value:'ワールドカップ -is:retweet'},
  { value:'コスタリカ戦 -is:retweet'}
  ]
 で、設定してその後はそのまま使うということだ。

　数分で1000tweetを集めたが、そんなに集めても仕方がないので、時々走らせて様子をみるが、
ABEMAと思われるauthor_idが山ほどtweetを出していて、これを削除するruleはどうするのかなあ？と思っているところ。author_idからscreen_nameを取得するのはまたapiで確認するよていだが、これを取得するように設定することもできるはずである。
【個人用】Go言語チートシート

# はじめに
本記事はGo言語再履修用に作成した

# 本文
## 関数
### main
```main.go
package main

func main() {
	println("Hello")
}
```
### 自作関数
``` main.go
package main

func main() {
	println(testfunc(1, 2))
}

func testfunc(a, b int) int {
	ans := a + b
	return ans
}
```
### 自作関数（戻値複数）
```main.go
package main

func main() {
	res1, res2 := testfunc(2, 1)
	println(res1, res2)
}

func testfunc(a, b int) (int,int) {
	ans1 := a + b
	ans2 := a - b
	return ans1, ans2
}
```
## 配列（for文）
### 既知
```main.go
package main

func main() {
	arr := []int{1, 2, 3}

	for i := 0; i < len(arr); i ++ {
		println(arr[i])
	}
}
```
### 未知
```main.go
package main

func main() {
	arr := make([]int, 3)
	arr[0] = 1
	arr[1] = 2
	arr[2] = 3

	for i := 0; i < len(arr); i ++ {
		println(arr[i])
	}
}
```
### 結合
```main.go
package main

func main() {
	arr1 := []int{1, 2, 3}
	arr2 := []int{4, 5, 6}
	arr := append(arr1, arr2...)

	for i := 0; i < len(arr); i ++ {
		println(arr[i])
	}
}
```
## 文字操作
### 文字→数値（Atoi）
```main.go
package main

import "strconv"

func main() {
	str := "123"
	num, _ := strconv.Atoi(str)

	println(num)
}
```
### 文字→数値（ParseInt）（16進、2進）
```main.go
package main

import "strconv"

func main() {
	str1 := "0x123"
	str2 := "0b101"
	num1, _ := strconv.ParseInt(str1, 0, 32)
	num2, _ := strconv.ParseInt(str2, 0, 32)

	println(num1, num2)
}
```
### 数値→文字
```main.go
package main

import "fmt"

func main() {
	num := 123
	str := fmt.Sprintf("%d", num)

	println(str)
}
```
### 文字列分割
```main.go
package main

import "strings"

func main() {
	str := "123,aiueo"
	arr := strings.Split(str, ",")

	for i := 0; i < len(arr); i++ {
		println(arr[i])
	}
}
```
### 文字結合
```main.go
package main

func main() {
	str1 := "123"
	str2 := "aiueo"
	strs := str1 + str2

	println(strs)
}
```
## 機能群
### CSVリード
```main.go
package main

import (
	"bufio"
	"os"
	"strings"
)

func main() {
	res := readcsv("test.csv")

	for i := 0; i < len(res); i++ {
		for a := 0; a < len(res[i]); a++ {
			print(res[i][a] + ",")
		}
		println()
	}
}

func readcsv(fn string) [][]string {
	res := make([][]string, 0)

	fp, err := os.Open(fn)
	if err != nil {
		println("FILE OPEN ERROR")
	}
	defer fp.Close()

	sc := bufio.NewScanner(fp)
	for sc.Scan() {
		rescache := make([][]string, 1)
		rescache[0] = strings.Split(sc.Text(), ",")
		res = append(res, rescache...)
	}

	return res
}
```
### ファイル出力
```main.go
package main

import "os"

func main() {
	writeLine("test.txt", []string{"hoge", "fuga"})
}

func writeLine(fn string, strs []string) {
	fp, err := os.Create(fn)
	if err != nil {
		println("FILE ERROR")
	}
	defer fp.Close()

	for i := 0; i < len(strs); i++ {
		fp.WriteString(strs[i])
		fp.WriteString("\n")
	}
}
```
### コマンドライン入力
```main.go
package main

import "os"

func main() {
	println(os.Args[1])
}
```
[Houdini] Parameterの変更箇所だけを一発で表示するツール

# はじめに

しゃんぺんです。こんにちは。

Houdiniの勉強をしていると、サンプルのhipを見ながら写経をすることがあると思います。
写経をしていると、ノードのパラメタの中で、変更箇所だけを確認したいというケースが多々ありますが、ワンタッチで表示する方法が見つからなかったので、ツールを作りました。

https://github.com/thinpedelica/showNonDefaultParam/blob/master/showNonDefaultParam.Py


# パラメタの変更箇所の表示方法(手動)

まず、パラメタの変更箇所を手動で表示する方法を説明します。

##### ムシメガネをクリックする
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/8e476f58-bfe0-2ed5-7176-14502cf067b8.png)


##### [Search All]をクリックする
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/19b49ec4-ada7-f8ed-f15e-134863c4a793.png)


##### [Parameter with Non-Default Values]を選択する
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/49a487e4-bba7-dedf-ac36-fffbb24c8866.png)

これでデフォルトから変更されているパラメタだけが表示されるようになります。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/483aa1c6-0c45-4855-9c22-89a656047201.png)


# カンタン表示ツールの設定方法

つづいて、上記をショートカットで出来るようにするための設定方法を説明します。

##### Shelfで右クリック -> New Tool
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/a38d5e07-03bf-0b86-0b0d-7cf8bb5b129f.png)


##### Scriptタブにコードをコピペ
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/f28bbc58-2f86-df36-d063-19431f3949ea.png)


##### Optionsタブで適当に名前をつける
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/fa979eaf-8f97-b552-ed33-39adc9370a2b.png)


##### HotKeysタブで適当にキーを割り当てる
[Double-click here to add mapping]というところを押して、キー割り当てを行います。  
自分はAlt+d にしました。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/0eb46f04-b1f6-4161-96fa-84f48e38a883.png)


# カンタン表示ツールの使用方法
ノードを選択した状態で、指定したHotKeyを打つと、ParameterエリアのSearchModeが[Search Non-Default]になり、デフォルト値から変更されたパラメタだけが表示されるようになります。
もう一度打つと、[Search All]に切り替わります。


# おわりに
実はこのツールは去年(2021年)に作ったのですが、とあるツイートを見て[Non-Default Values]を知らない人も多いのかなと思い、人目に付くところに記事を置いておきたいと思い、アドベントカレンダーに参加しました。

もりもり写経して、ステップアップしていきたいですね！
型推論しない場合の関数定義について調べてみた

# 型推論とは


# なぜ調べようと思ったか

・何が省略できて、何が省略できないのか分からない
・各フレームワーク、ライブラリのドキュメントに記載の型指定が分からない
・ReactのFunctionコンポーネントで関数定義をするので関数の型指定の基礎を学びたい
# これ以上ないくらいの型指定

アロー関数の場合
例えば以下のような関数があったとき。
```tsx
//引数の型に応じて戻り値を変える関数
const arrowFunc = (param1, param2) => {
  if ((typeof param1 === "number") & (typeof param2 === "number")) {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};
```

この書き方が型がフル指定の型の書き方
ただ、関数定義のときと、引数と戻り値にそれぞれ指定をしていて、重複するので無駄のようです。

```tsx
type funcType = {
  (param1: string | number, param2: string | number): string | number;
};

type paramType = string|number;

//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType = (param1:paramType, param2:paramType) :string|number => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};
```

なので以下いずれかで書くのが良い

```tsx
type funcType = {
  (param1: string | number, param2: string | number): string | number;
};

type paramType = string|number;

//シンボルの方に型指定
const arrowFunc1: funcType = (param1, param2) => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};

//関数定義の中で型指定
const arrowFunc2 = (param1:paramType, param2:paramType) :string|number => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};
```

# ジェネリック型
型定義を抽象化していくために使う。
事前に必要な型を把握しておくことは困難なので、以下のように<T>を使うと抽象化できる。

```tsx
type funcType = {
  <T>(param1: T, param2: T): string | number;
};

//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType = (param1, param2): string | number => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};
```
上記だと、引数を持った関数が呼ばれるときに都度型が変わる。
一方、以下の形だと、関数定義をするときに型を定義もしなければならない。
こっちの手法の方がよく見かける気がする
```tsx
type funcType<T> = {
  (param1: T, param2: T): string | number;
};

//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType<string | number> = (param1, param2) => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};
```

```tsx:省略記法
type funcType<T> = (param1: T, param2: T)=>string | number;

//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType<string | number> = (param1, param2) => {
  if (typeof param1 === "number" && typeof param2 === "number") {
    return param1 + param2;
  } else {
    return `${param1}${param2}`;
  }
};

```


# 参考記事

https://qiita.com/uehaj/items/79c277301f89d109c11d

https://qiita.com/poch/items/c92cba15be3f6a1b29a6

非常に参考になった記事。
結果的に、上記記事の内容とほぼ重複しているが、備忘録の意味も含めて投稿します。
Figmaで簡単にOGPのテンプレートを作って使い回す方法

## これは何

[Figmaを使った制作効率アップの方法 by Figma Advent Calendar 2022](https://qiita.com/advent-calendar/2022/figma2)の参加記事です！

FigmaのComponent機能を使って、簡単に使いまわせるOGP画像を作る方法について解説しています。

## 作り方

まずはOGPサイズの`1200x630`のFrameを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/b9a6496f-17b8-0598-2314-803ea3c8a7ca.png)

バリエーションを出せるように、入れ替えられるイラストを用意します。

今回は [ソコスト](https://soco-st.com/) さんのイラストをお借りしてパターンを複数用意しました。
もちろん用意した画像以外にも後からイラストを追加することはできます。

画像をダウンロードしたら、Figmaに配置し、`Create multiple component`でコンポーネント化します。
（今回は後から使いやすいようにイラストのサイズとアスペクト比を揃えました。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/b4f17f16-7938-f1df-4a38-8656bac57e80.png)

コンポーネント化したら、右側の`Components`タブで`Combine as variants`を選択してコンポーネントを`Variants`でまとめます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/aba5581d-f169-a5ef-bc4a-3bc4adfcc776.png)

Variantsを作成したら、好きなコンポーネントを一つコピーして最初に作った`1200x630`のFrameの中にペーストします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/6eac9875-79b0-a75d-0505-40a1b3e23f9c.png)

これで、まずは画像内のイラストを入れ替えられるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/cbdd3093-31f5-221a-4702-60ea49a6ed88.png)

次に、Frame内にテキストボックスを配置します。
この時、あらかじめMAXの文字数がどれくらいになりそうかを想定してイラストに被らないようにボックスのサイズや位置を決めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/098f4fae-a9d7-a253-035e-f081a5593165.png)

テキストボックスを配置したら、`Command + Option + K`でFrameをコンポーネント化すれば完了です！

コンポーネントをコピーすればテンプレートのデザインはそのままに、テキストを入れ替えて様々なパターンのOGPを作成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/e5e4cf90-3cce-564c-49e5-bf2d6dce51d7.png)

コンポーネントにしておくことで、編集している間にうっかり触ってデザインが変わってしまったりすることを防げるほか、デザインを変更するときにMaster componentをいじれは作成した全てのInstanse（コンポーネントのコピー）にも変更を反映できるので便利です！

応用すれば名前入りのZoom背景やパターン出しをしたいバナー広告なども簡単に作成することができます。
Helmで数字を入れようとすると勝手に指数に変換される現象

## はじめに
kubernatesでサービスを運用していたのですが、イメージを下記のような命名規則でレポジトリにあげていました
```text:イメージ名
サービス名:Gitのコミットハッシュ7桁
```
この命名規則の都合上、helmを使ってvaluesからコミットハッシュを読み込む必要があったのですが、その時にハマった話です。

# 困ったこと
- helmでvaluesからgitのrevisionを呼び出したかった
  - ほとんど場合特に問題なくvaluesの値をyamlに適応できた
  - ただコミットハッシュが**数字のみの場合は勝手に指数に変換されてうまくyamlに適応できなかった**
    - `42c53f2`みたいな英数字の場合は問題なし
    - `4502345`のように数字のみの場合に`4.502345e+06`と勝手に変換される
    - また`45023e5`のよう場合も勝手に`4.5023e+09`のように変換される

## 例
**なんのこっちゃよくわからないと思うので例を挙げます。**
```text:ディレクトリ構成 (わかりやすくするために色々省略)
test
┣━ .helmignore
┣━ Chart.yaml
┣━ charts
┣━ templates
┃    ┗━ hoge.yaml
┗━ values.yaml
```

```yaml:values.yaml
revision: 4c4f198
```

```yaml:template/hoge.yaml
git_revision: {{ .Values.revision }} # ここにValuesで設定したgitのrevisionを入れたい
```

### 対象のvalueの値が英数字のみの場合
全く問題なくvalueが適用される
```yaml:values.yaml
revision: 4c4f198
```

```terminal:実行結果
$ helm template . -f values.yaml
---
# Source: test/templates/hoge.yaml
git_revision: 4c4f198  ← Valuesの値がそのまま入った
```

### 対象のvalueの値が数字のみの場合
```yaml:values.yaml
revision: 5304952
```
このように指数に勝手に変換されます
```terminal:実行結果
$ helm template . -f values.yaml
---
# Source: test/templates/hoge.yaml
git_revision: 5.304952e+06 ←5304952ってそのまま入れてくれればいいのに、、
```

### 対象のvalueの値がたまたま指数形式になってしまった場合
```yaml:values.yaml
revision: 53049e2
```
この場合も、eが指数のeと判断されて変換がかかる
```terminal:実行結果
$ helm template . -f values.yaml
---
# Source: test/templates/hoge.yaml
git_revision: 5.3049e+06 ←😡
```


# 原因
お察しの通りhelmで文字列が数値型として認識されて、~~ありがた迷惑なことに~~ 勝手に変換される模様。issueにもいくつか上がってる。
[参考]https://github.com/helm/helm/issues/1707


# 解決方法
単純にvaluesにダブルクオーテーションつければOKです
```yaml:values.yaml
revision: "5304952"
```
```terminal:実行結果
$ helm template . -f values.yaml
---
# Source: test/templates/hoge.yaml
git_revision: 5304952 
```

またはvaluesのところに`!!string`をつけてもいけます
https://helm.sh/ja/docs/chart_best_practices/values/
```yaml:values.yaml
revision: !!string 5304952
```
```terminal:実行結果
$ helm template . -f values.yaml
---
# Source: test/templates/hoge.yaml
git_revision: 5304952
```

## おまけ：values.yamlの作成に`yq`コマンドを使ってる場合
values.yamlの作成をyqコマンドで環境変数からgit_revisionを読み込んで入れるように設定していたので、`strenv`で読み込むことで対応しました。

```terminal
＃ strenv使うとダブルクオーテーションで括ってくれる
$ export GIT_REVISION=1234567
$ yq eval -i '.revision=strenv(GIT_REVISION)' values.yaml
$ cat values.yaml
revision: "1234567" 
```
※ `env`や`strenv`はGo製のyq(macではbrewでインストールできるやつ)でないと使えなさそう

# 最後に
gitのコミットハッシュは16進数なので、a-f0-9(16種類)のうち0-9(10種類)が、7桁全てが数字で入る確率は以下のようになります。

(10/16)^7 * 100 = **3.725(%)**

低確率ではありますが、起こり得ない確率ではないので気付けてよかったなと思います
【Java SE11 Gold】入社3ヶ月でJava Gold合格した勉強法

# 初めに
こんにちは、名古屋勤務1年目のエンジニアです。

1ヶ月でJava Silverを取り少し間をあけ、1ヶ月でJava Goldを取りました。

Silverの時の勉強法は以前にも投稿していますので、そちらを参考にしてください。

今回はどのようにJava Goldを取得したのか、Silverの時と何が違ったのかについて解説します。

:::note info
ちなみに今回は合格点63点のところ77点という結果となりました。
:::

# 勉強方法
Silverの時の勉強方法を見ていただいた方はご存知かもしれませんが、Java Silverの時は黒本を3周して合格することができました。Goldはどれくらい勉強すればいいんでしょうか？

勉強時間ですが、平日はJavaの講義を受けており一日8時間みっちり勉強後2時間はスタバで資格勉強をしました。土日も合わせて5時間以上は確保するようにしていました。

__結論Goldも黒本３周しとけば大丈夫です！__
（２周目で一つの章につき2周連続で実施して問題文を覚えていたので実質４周ですが...）

とは言っても、合格できるか不安が大きかったので、会社にあった紫本を使って復習しました。

しかし、黒本で正解率90パーセントは超えるレベルまで来たのに、紫本の教材で模試をすると20-30%しか取れませんでした。「今までの頑張りはなんだったんだ？」「ここまできてJava Goldの難しさを思い知るとは...」なんて思ってすごく不安の中試験に挑みましたが、結局出てきたのは頑張って勉強してきた黒本の内容ばかり。

「やっぱり黒本さえやっておけば大丈夫なんだ！」と改めて思いました。

なぜ、会社にあった紫本がそこまで難しく試験にあまり役に立たなかったのか、

一つは私が受けるJava SE11ではなく、Java SE9（確か）の攻略本だったからです。考えてみりゃわかることではありますが、情報が古いので、回答が異なるなんて問題もありました。Java SE11の試験受けるならJava SE11の黒本を買いましょう！

あとは、単純に自分に合っていませんでした。黒本は回答の中にたくさんの解説が含まれていて、なぜその問題の回答がこうなのかを詳しく説明してくれていましたが、紫本の場合は最初に解説されて後で問題が出題されるので、回答に解説が詳しく載っておらず、その理由を調べるために解説ページから探したり、ネットで調べる必要があります。そのもどかしさが自分に合っていないと思いました。


# 勉強のコツ
実は今回少しだけ勉強のやり方を変えました。
より時間を効率的に使えるようにアップグレードしたのです。それは、、、

__Googleのスプレッドシートを効率的に使う！__

ことです！！

前回からgoogleのスプレッドシートを使ってはいましたが、今回は関数や非表示機能などを使ってもっと効率的に勉強ができるように工夫しました。
これから勉強に取り組む人が参考になるように今回はそのスプレッドシートを公開します！

そのスプレッドシートがこんな感じ↓↓

![](https://i.gyazo.com/1ff0638e47014bb1a6427f4f42764c73.jpg)

#### 工夫したポイント①

google docの非表示機能をうまく使って、試験用紙を使い回す！！

今までは、模擬試験を行うたびに新しいシートを作成したり紙に書いていったりしました。
そうすると、採点は毎回ひとつひとつ行うことになり、時間の無駄です。さらに、間違えた箇所について、前回にも同様に間違えたのか？など分析ができるようになったので、異なるアプローチから知識の定着化を図ることができます。

模擬試験を行うときは以下のようなシートになってます。

![](https://i.gyazo.com/6c11b9851c6cf515f4d21adbeb14634b.png)
そして試験が終了し、非表示にしている列を再度表示すると...
![](https://i.gyazo.com/78e39943678c7e60bdbcce369d0d64f2.png)
開いた瞬間に採点が完了しており、前回の回答状況とも比較できるので答え合わせと分析の時間を大幅に節約することができます。
判定のところにも色をつけることで一瞬でどこが間違えているのか見える化しました。
色付けは条件付き書式で設定しました、色々いじってるとできると思うので、やってみてください。

#### 工夫したポイント②
理解度とmemoを追加した

先ほどの写真でもでてきたようにこのシートには理解度とmemoがあります。

例えば、２周目問題を解いていて、６割正解したとします。

４割しか間違ってないのに全ての問題の解説を見ていくのは大変ですよね？

かといって間違っている問題だけ解説を見ているとある問題が発生します。それはまぐれで正解した問題もちゃんと分かっていて正解した問題と同等に扱われることで、復習されずにわからないまま終わってしまうことです。

それは逆に、分かっているのに問題を読み間違えた時にも言えることです。

これを解決するために、理解度の項目を追加しました。一周目で全ての問題の理解度を記入しておき、２周目以降はそれを参考にしつつ、update後の理解度を記入していく。そうすることで、どの問題の理解度が低いのか一目瞭然なので勉強する際に非常に便利です。

memoは、解説を読んでまとめた内容を書いたり、自分の調べた内容をアウトプットすることでより定着させていくという側面と、２周目以降解説を読むのではなく、memoを読むだけで自分の記憶の引き出しにアクセスして効率的に勉強することができます。


# 終わりに
読みにくい文章を最後まで読んでいただきありがとうございました。

これからJava Gold受ける人、頑張ってください！プログラミング歴半年以内、入社3ヶ月の私でも取れたので、取れないなんてことはないと思います。

当たり前ですがただ一つ言えるのは、勉強しなかったら取れません。

しっかりと勉強時間を確保して計画的に資格取得に向けて取り組みましょう！！
【Salesforce】参照関係項目の検索結果リストの表示項目の設定方法

最近ちょっとハマったので備忘録

# VF画面の参照関係項目の結果リストの表示項目を変更したい
サンプルで作ったVFの取引先責任者登録画面です↓
虫眼鏡マークを押したときに出る、結果リストの表示項目を変えるのがやりたいことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/0ab57ff4-9e4f-608f-2807-528d2484d0da.png)

# 検索レイアウトやろ？？

取引先責任者の取引先名の項目ということで
取引先の検索レイアウトだと思ったのですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/ebdc9112-4680-358a-efbe-9b5f24f373d0.png)

ありませんでした。
※標準画面の検索結果ダイアログのリスト表示項目はこちらで設定できます。

# 正解はClassicの検索レイアウト
もしやと思ってClassicで取引先の検索レイアウトの設定画面を開くとそれらしきものが、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/6459b676-49a5-8c30-16de-0e7fa37ce258.png)

編集すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/3b30b853-d774-8154-3001-c188956ea7de.png)

無事に変更できました！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/9804623a-0664-133f-2f54-dca62b01853f.png)

Classic画面に対してよそよそしい気持ちになってしまうLightningネイティブのぴえでした((+_+))
【JS】Swiperjsとは

# Swiperjsとは
Webサイトで少しでも画面に華を持たせたい場合、JsやCSSでスライドを作成すると思うが、それだけでもお腹いっぱいになってしまう人がいるのではないだろうか？Swiperjsはscriptタグを挿入し、公式サイトにある参考コードをコピペするだけでスライド作成ができてしまう。
今回は自前のワードプレスサイトのアピールエリアに画像を挿入し、それをぐるぐる回したかったので使用したいと思う。しかし、対応していないブラウザもあるらしく、IEではつかえないんだとさ（これを書いている時はもうIEはWindowsから消滅しいた）
現在はv8.4.5まで実装されている。

### 注意
scriptタグを挿入する場所はbody終了タグの直前に書く。headタグに書いた場合、動かないパターンがあった。

公式サイト [Swiperjs](https://swiperjs.com/)
INMO AIRの開発者向けオプションを有効にする

INMO AIRは、それ単体で動作するスマートグラスの中でも軽量で普通のメガネの見た目にかなり近く、一般的なメガネ屋さん(筆者はメガネスーパーを利用しました)で処方レンズに変えることができるデバイスです。
通常のAndroidの機能は隠蔽されていますが、開発者向けオプション(Developer options)を有効にすることで、(非公式ですが)通常のAndroid 10デバイスのように開発することが可能です。

![処方レンズを取り付けたINMO AIR](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/65a38c51-a1cc-ad24-b7bc-74206a36335f.jpeg)

## 注意事項

本手順は、公式に提供されているものではなく、操作ミスなどにより通常の機能が利用できなくなる可能性があります。何らかの不具合が発生しても対応できませんので、自己責任で操作を行ってください。また、開発元や販売元に問い合わせることもご遠慮ください。

## 手順

1. まず、本体の言語を英語に変更します。途中文字列を入力する必要があるのですが、言語が日本語のままでは先に進めなくなります。
2. アプリケーション終了時にAndroidの画面が出てくる場合があるので、色々なアプリケーションの終了操作をしてみてこのようなダイアログが出るまでがんばります。タイミング等がうまくいくと表示されます。表示されたら、首を動かすと丸いカーソルが表示されるので、App info にカーソルを合わせてタップします。
![アプリケーションの終了時にこのようなAndroidのダイアログが表示されることがあります](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/d709140e-8812-ad2c-c476-7f00c9157d2a.png)
3. 2.の操作で App info の詳細が表示されます。右上にある虫眼鏡のマークをタップすると、検索ウィンドウが表示されるので、Settings と入力します。入力には首を動かしたり、タップを駆使して行います。検索できると、以下のようにいくつかの項目が表示されますが、歯車のアイコンのSettingsをタップします。 ここで、1.で書いたように言語設定が日本語になっている場合は、Settings と検索しても目的のものが表示されないことに注意してください。言語設定が日本語の場合は、ここで"Settings"の代わりに"設定"と入力する必要がありますが、この画面では日本語入力ができず先に進むことができなくなります。
![Settingsというキーワードで検索](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/f55ba1df-2f47-c28d-3ddf-5d3f3ac006c2.png)
4. OPENをタップします
![Settingsを開く](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/dd71394e-4aef-66d9-b731-428f2db8b902.png)
5. 下のほうまでスクロールすると、About device という項目があるのでこれをタップします(この項目は開発者オプションを有効にすると表示されなくなります)
![Settingsの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/aee10470-e6cb-1d38-8020-a7971ba6546f.png)
6. 下のほうにある Build number を7回タップすると開発者オプションが有効になりそのメッセージが表示されます。画面上の ← をタップして戻ります
![2022-11-27-16-13-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/2161dd2d-762f-1066-1f21-99ac7b2da753.png)
7. System をタップすると、一番下に Developer options という項目が追加される(6の操作を完了するまでこの項目は表示されません)ので、これをタップします
![開発者オプションが有効になっていることの確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/4b8e02a6-fbe6-2bad-620b-c5d899673d39.png)
8. USB debugging を有効にします。これで、PCに接続して開発が行えるようになります。
![USBデバッグの有効化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/8ba00cef-537e-6e5c-07bc-02fae1bf8ed4.png)

## スクリーンショットの撮影
上記で利用しているスクリーンショットは、[scrcpy](https://github.com/Genymobile/scrcpy#get-the-app)を利用して作成しています。USB debugging を有効にすると利用できるようになります。
詳しくは下記の記事などを参照してください。

- [PC/MacからAndroid端末を操作できるツール「scrcpy」、HID/OTGをサポート](https://forest.watch.impress.co.jp/docs/news/1390881.html)
インスタンスの属性で並び替える

# sort_by
```rb
sort_by {|item| ... } -> [object]
```
## 出典
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/sort_by.html

# Sorting an array of objects in Ruby by object attribute?
サイトを見つけた時のタイトルです。
自分が見つけたいものがあるような単語が並んでいたのでサイトを開いてみました。

```rb
objects.sort_by {|obj| obj.attribute}
```
## できた
これで属性で並び替えることができた。

### 出典
https://gorails.com/forum/sorting-an-array-of-objects-in-ruby-by-object-attribute

# 感想
英語のサイトを見て問題が解決できたので、何か気持ちがいいです。
制御オプション EXPROPTS(*ALWBLANKNUM)

制御オプション `EXPROPTS(*ALWBLANKNUM)`は、~~**V7R5**~~  **V7R3** から使用可能になっているオプション。（※[IBM i 7.5 での変更点](https://www.ibm.com/docs/ja/i/7.5?topic=ssw_ibm_i_75/rzasd/rpgrelv7r5.html#rpgrelv7r5)にありますが、TR等のPTFでV7R3以降使える様です）
外部（Webやインタフェースのアップロード）とのやりとりをする場合、受け取るフィールドが数値タイプでも、相手のDBがOpne系だとNULL値（≒空文字）だったりする事はよくある話。
そこで出番となるのは`%DEC関数` で数値変換をするのだが、今まで `*BLANK` を渡すとエラーになって `*ZERO` に置き換えてから実行しないとエラーになっていた。しかし、制御オプション `EXPROPTS(*ALWBLANKNUM)` を **H仕様書** に記述すれば、無問題！ゼロの結果を返してくれます。

以下、使用例

```rpgle:QII0170R.rpgle
H*-  ブランクを数値変換の引数として許可する
H EXPROPTS(*ALWBLANKNUM)
D*- ---<< 変数定義    >>-----*
D STR1            S             63A
D DEC1            S              9S 0
D MSG             S             40A
C*- ***************************************************************
C*- *  メインロジック                                            **
C*- ***************************************************************
C                   MONITOR
C*-  数値変換
C                   EVAL      STR1        = *BLANK
C                   EVAL      DEC1        = %DEC(STR1 : 63 :15 )
C                   EVAL      MSG         = ' 数値１… '
C                                         + %EDITC(DEC1 : '3')
C     MSG           DSPLY
C                   ON-ERROR  *ALL
C                   EVAL      MSG         = '[ERROR:*ALL]'
C                                         + %CHAR(%STATUS)
C                                         + '*ALL 監視エラー '
C     MSG           DSPLY
C                   ENDMON
C*
C                   SETON                                        LR
C                   RETURN

```

実行のスクリーンショット。これも便利で良いですな。
![2022-11-27_164355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/1394b33b-146c-3274-a153-c78d4a650d4e.png)
OR・IEと業務分析

# 問題１
### 機会損失はいくらか？
#### 機会損失とは？
```営業や販売等の機会を逃す```ことで、本来得られたはずの利益を失うという「```未来的な損失```」を指しています。
##### 出典
https://www.10so6.com/colums/lost_opportunity_causes_and_countermeasures#:~:text=%E5%96%B6%E6%A5%AD%E3%82%84%E8%B2%A9%E5%A3%B2%E7%AD%89%E3%81%AE%E6%A9%9F%E4%BC%9A%E3%82%92%E9%80%83%E3%81%99%E3%81%93%E3%81%A8%E3%81%A7%E3%80%81%E6%9C%AC%E6%9D%A5%E5%BE%97%E3%82%89%E3%82%8C%E3%81%9F%E3%81%AF%E3%81%9A%E3%81%AE%E5%88%A9%E7%9B%8A%E3%82%92%E5%A4%B1%E3%81%86%E3%81%A8%E3%81%84%E3%81%86%E3%80%8C%E6%9C%AA%E6%9D%A5%E7%9A%84%E3%81%AA%E6%90%8D%E5%A4%B1%E3%80%8D%E3%82%92%E6%8C%87%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

# 問題２
### 会議におけるファシリテータの役割として、適切なものはどれか？
#### ファシリテータとは？
会議などの場で、参加者に発言を促したり、話の流れを整理するなど、```話し合いを活性化・効率化させるための支援を行う役割を持つ人```のこと。

# 問題３
### マクシミン戦略をとった場合の利得はどれか？
#### マクシミン戦略とは？
行動を選択する基準の一つで、各選択肢から得られる利得を考え、```最悪の場合の利得が最も大きくなる選択肢を選ぶ```こと。ゲーム理論で用いられる概念。

##### 出典
https://e-words.jp/w/%E3%83%9E%E3%82%AF%E3%82%B7%E3%83%9F%E3%83%B3%E5%8E%9F%E7%90%86.html

# 問題４
### 以下の手順の未来予測に用いられる予測技法はどれか？
* 複数の専門家を回答者として選定
* 質問に対する回答結果を集約してフィードバックし、サイド質問を行う。
* 回答結果を統計的に処理し、分布とともに回答結果を示す。

#### デルファイ法とは？
同一の質問に対する複数の対象者の回答を収集し、その結果を対象者にフィードバックして改めて回答を求める。その結果を```統計的な手法で集計```することで、回答の精度を高めるアンケートの手法。主に、```未来予測```などに用いられる。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
napariでPointを配置した輝点を２次元ガウシアンでフィッティングする

# やりたいこと
輝点画像にPointを配置して、その輝点を２次元ガウシアンでフィッティングして、輝点の座標を出力したい。

# コード
```fit_signal_with_gaussian.py
import glob
import math
import napari
import numpy as np

from scipy.optimize import curve_fit
from skimage import io


dir_name = "./data"
file_names = glob.glob(dir_name + "/*.tif")
stack = np.array([io.imread(file_name) for file_name in file_names])

viewer = napari.view_image(stack)
points_layer = viewer.add_points(ndim=3)

ws = 9
def gaussian_2d(x, a, b, c, d):
    return a * np.exp(-(b * ((x % ws - c) ** 2 + ((x / ws).astype(int) - d) ** 2)))

@viewer.bind_key('f')
def fit_gaussian(viewer):
    for point in points_layer.data:
        frame = round(point[0])
        xc = round(point[2])
        yc = round(point[1])

        x0 = xc - int(ws / 2)
        y0 = yc - int(ws / 2)
        
        # Get signals around the specified point
        x = np.array([i for i in range(ws * ws)])
        s = np.array([stack[frame, y0 + int(i / ws), x0 + i % ws] for i in range(ws * ws)])

        # Estimate reciprocal variance for the fitting initial parameter
        v_sum = 0.0
        s_sum = 0.0
        for i in range(ws * ws):
            x_tmp = x0 + i % ws
            y_tmp = y0 + i / ws
            s_tmp = stack[frame, y0 + int(i / ws), x0 + i % ws]
            v_sum += s_tmp * ((x_tmp - xc) ** 2 + (y_tmp - yc) ** 2)
            s_sum += s_tmp 
        rv = s_sum / v_sum
        
        # Fitting
        popt, pcov = curve_fit(gaussian_2d, x, s, p0=[stack[frame, yc, xc],
                                                      rv,
                                                      math.floor(ws / 2),
                                                      math.floor(ws / 2)])
        
        # Output        
        x_fit = x0 + popt[2]
        y_fit = y0 + popt[3]
        print(f"frame, x, y: {frame}, {x_fit}, {y_fit}")
    
napari.run()
```

# 出力
Pointを配置して、「F」を押すと、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23570/176d2357-dc75-af40-22b6-304dfecec956.png)

フィッティングした座標が出力された！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23570/6245d5c5-5ee8-f573-ea91-cb6686f90741.png)

# ポイント
## フィッティング領域の切り出し
指定したPointの周りの領域の輝度を抽出。Fittingのために1次元化している。
```python
s = np.array([stack[frame, y0 + int(i / ws), x0 + i % ws] for i in range(ws * ws)])
```

## フィッティング
初期値を与えてscipyのcurve_fitでフィッティングする。
```python
popt, pcov = curve_fit(gaussian_2d, x, s, p0=[stack[frame, yc, xc],
                                              rv,
                                              math.floor(ws / 2),
                                              math.floor(ws / 2)])
```

## 2次元ガウシアン関数
簡単のために、X方向とY方向のvarianceは等しいと仮定。
```python
def gaussian_2d(x, a, b, c, d):
    return a * np.exp(-b * ((x % ws - c) ** 2 + ((x / ws).astype(int) - d) ** 2))
```
【Salesforce】カスタムメタデータ型とレコードのリリース

カスタムメタデータ型とレコードを
他環境にリリースしたいときの方法です。

# カスタムメタデータとレコードを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/a9c39da4-9502-44e9-e035-d9cc19340e0f.png)
通常通り作成します。
今回は「かすたむめた」というカスタムメタデータ型に「record1」「record2」レコードを作成しました。

# 変更セットでリリースできる
変更セットを作成し、コンポーネントの種類：カスタムメタデータ型で対象のカスタムメタデータ型を追加する
→「かすたむめた」を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/bb9cf8a7-8cf5-1a84-95ea-b76454ed69bc.png)

作成したカスタムメタデータ型をコンポーネントの種類で選ぶ
→「かすたむめた」を選択
レコードを追加する
→「record1」「record2」を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/535c3391-0584-4f7f-4014-0700e70ff9d5.png)

以上です！簡単ですね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/58c47fbd-0ccb-7d51-79ee-7466be3b2061.png)
AWS Lambda for Python 用に cryptography を同梱する

# はじめに

Lambda 関数デプロイ時に JWT デコードに利用する cryptography を同梱してデプロイしたかった。
そのため、cryptography を含む AWS Lambda Layer を作成 or 再利用しようとしたのだが、[Lambda@Edge 用の関数は Layer を利用できないという制約がある](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html)。

最初は local で pip でインストールしようとしたのだが、 cryptography のライブラリ自体が pip でインストールする時に環境依存のバイナリを入れてくるため、`pip -t .` でインストールしたモジュールをアップロードしても、基本的には動作しない。

そのための解消方法をメモする。 

が、正直、原始的なやり方であり、かなり限定的なユースケースでしかないので、代用が可能ならそちらを利用した方が良いので本当に最終手段として。


# 方法

１. AWS Lambda で利用されている Python 特定バージョンの Docker Image を選択する。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images-create.html

２. 以下の Dockerfile をビルドして、必要なライブラリをインストール

```Dockerfile
FROM public.ecr.aws/lambda/python:3.9
RUN mkdir -p /opt/export
RUN pip3 install pyjwt -t /opt/export
RUN pip3 install cryptography -t /opt/export
```

３. インストールしたファイル一式を持ち出して zip にまとめ、Lambda にアップロードする

# オチ

よくよく仕様を見ると、Lambda@Edge の最大コードサイズは 1MB であった。
ので、cryptography を使うような python コードは実質 Lambda@Edge では利用できないと考えた方がよさそう。

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/edge-functions.html

Cognito を使う場合は AWS が提供している aws-jwt-verify を使うのがよさそう。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/decode-verify-cognito-json-token/

https://github.com/awslabs/aws-jwt-verify

# 参考

https://stackoverflow.com/questions/67646196/aws-lambda-python-cryptography-cannot-open-shared-object-files
Rails concern

## Rails concernとは
Railsでアプリケーションを作ると、```controllers/concerns```, ```models/concerns```が自動的に生成されますがこのディレクトリを使ったことはありますか？ 僕はないです。

調べてみたところ、主に
- ```共通ロジックを持つときにconcernに切り出す```
- ```そのmodelやcontrollerとは異なるロジックである場合に切り出す```

の2つの使い方があるのかなと思いました。

例として、メールの送信ロジックなどをあげることができます。

特定の条件(投稿数が100に達する、フォロワーが100人に達するなど)を満たした時に、メールを送信するというロジックは、複数のモデルに適用することができますし、モデルロジックとは少し異なるロジックであると考えることができます。
このような時にmoduleとしてconcernに切り出します。
切り出されたmoduleは必要とするmodelでincludeすることによって使うことができます。

## 使い方
concernの使い方としては2つあります。

- ```concernsディレクトリ```に切り出す
- ```concerning ~~~ do```で切り出さずに使う

2つの使い方の違いは下記の記事がとてもわかりやすいです。

https://qiita.com/kasei-san/items/c016c626836da09a5a70

- **concernsディレクトリに切り出す**
=> 使い回しをすることができる

- **切り出さずにクラス内で```concerning ~~~ do```を使って定義する**
=> 使い回しをすることはできないが、異なるロジックであることを強調できる

## ActiveSupport::Concern
```extend ActiveSupport::Concern```は魔法です。
```extend ActiveSupport::Concern```をmodule内で使うことによって、簡単に書くことができるようになるので嬉しいです。
#### 使わない場合
```ruby
    module M
      def self.included(base)
        base.extend ClassMethods
        base.class_eval do
          scope :disabled, -> { where(disabled: true) }
        end
      end
    
      module ClassMethods
        ...
      end
    end
```
#### 使う場合
```ruby
    module M
      extend ActiveSupport::Concern
    
      included do
        scope :disabled, -> { where(disabled: true) }
      end
    
      class_methods do
        ...
      end
    end
```
```extend ActiveSupport::Concern```は```ActiveSupport::Concern```をmodule内にクラスメソッドとしてmixinしています。
↓ 中身はここにあります。

https://github.com/rails/rails/blob/main/activesupport/lib/active_support/concern.rb#L110

## 参考にしたサイト

https://github.com/rails/rails/blob/main/activesupport/lib/active_support/concern.rb

https://api.rubyonrails.org/v7.0.4/classes/ActiveSupport/Concern.html

https://www.akshaykhot.com/how-rails-concerns-work-and-how-to-use-them/

https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns
Pytorch LightnigでGPUを指定する方法

# Pytorch LightnigでGPUを指定する方法

こんにちは、九州大学修士２年の浅海です。
Pytorch lightningで指定のGPUを使用する設定に、つまづいたのでここにメモします。

こちらの記事は、Pytorch LightnigでGPUを指定する方法 に関する以下のセッションの内容をまとめたいと思います。

## 1. pl.Trainerの引数で使用するGPUの定義
pl.Trainerの引数にて、__gpus=[使用したいGPUの番号]__　とすることで、GPUを指定出来ます。

```python
trainer = pl.Trainer(
                    accelerator="gpu",
                    gpus=[使用したいGPUの番号],
                    )
```

ここで注意！！
必ずGPUを指定したい場合は __リスト形式 []__ で括る必要があります。

**gpus=[1]** とすることで、以下の画像のように一つの指定したGPUを使用することが出来ました。
![Screenshot from 2022-11-27 17-10-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986237/61912e01-154b-baa3-c68e-b0c173ef7dfa.png)


## 2. よくある間違い！！
**gpus=使用したいGPUの番号**、として整数を与えてしまうと問題が生じます。

例としてgpus=2とした場合を考えます。この引数を与えると、GPU=0, 1, 2を使用する設定になります。整数で与えると、その番号以下のGPUを全て使用することになるのでご注意ください。
```python
# GPUの指定に失敗する例
trainer = pl.Trainer(
                    accelerator="gpu",
                    gpus=2,
                    )
```

## まとめ
以上が、Pytorch lightningで指定のGPUを設定する方法です。
これからも気になった点をまとめていこうと思います！
TerraformでAWSリソースをデプロイしてみる

お仕事で使う機会があったのでメモ📝
# 1.AWS環境の設定
AWS環境へのデプロイなので、端末の下準備が必要です。

**①CLIインストール**
端末でAWSのコマンドが通るように設定します。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

**②profileの設定**
クレデンシャルがTerraformコードに内に直書きにならないよう、
AWSアカウントを端末側に設定します。

今回はqiita-deployというprofile名で設定します。
```
aws configure --profile qiita-deploy
```
この後対話形式になるので、クレデンシャルを登録していきましょう。
リージョンはap-northeast-1、formatは空欄のままでOKです。

■proflie確認コマンド
・profile一覧
```
aws configure list-profiles
```
・該当profile確認
```
aws sts get-caller-identity --profile qiita-deploy
```

# 2.Terraformでのデプロイ
**①Terraformインストール**
brewでインストールします。

※brewが導入されてない人はこちらへ。
https://brew.sh/index_ja

```
brew install terraform
```

**②デプロイ用ファイルの作成**
下記３ファイルを作成します。

1.デプロイ対象ファイルの作成
とりあえずEC2だけデプロイするので、EC2に関する記述だけ記載します。
他にも指定したい項目がある場合は適宜追加してください。
```qiita-deploy.tf 
resource "aws_instance" "qiita-deploy" {
    ami = "ami-XXXXXXXXXX"
    instance_type = "t1.micro"
}
```

2.provider.tfの作成
デプロイ先（AWS）の取得情報を記載します。

```provider.tf
variable "aws_shared_credentials_file" {
  type = string
}
variable "aws_profile" {
  type = string
}
variable "aws_region" {
  type = string
}

provider "aws" {
  shared_credentials_file = var.aws_shared_credentials_file
  profile                 = var.aws_profile
  region                  = var.aws_region
}
```

3.terraform.tfvars
2.の取得先になる変数ファイルを作成します。
```terraform.tfvars
aws_shared_credentials_file = "~/.aws/credentials"
aws_profile  = "qiita-deploy"
aws_region  = "ap-northeast-1"
```

**③デプロイ**
1.ワークスペースの初期化
```
terraform init
```

2.デプロイの事前確認
applyが正しくできるか確認します。
```
terraform plan
```

※ここで下記Warning（属性の非推奨）が出る場合がありますが、次へ進んでOKです。
・Warning: Argument is deprecated
・Warning: Attribute Deprecated

おそらくcredentialsという文字列に反応してくれてるのではないかと思います。

3.デプロイ
ここでAWSへ②-1で記載したインスタンスがデプロイされます。
```
terraform apply
```

※削除する場合
```
terraform destroy
```

以上です:relaxed:
%TIMESTAMP追加機能（*UNIQUE 注意？

%TIMESTAMP追加機能。 **V7R5** 又は **PTF適用済み V7R3以上** で使用可能。

機能追加は以下
- マイクロ秒精度を戻す
- ユニーク・タイムスタンプを戻す。※注意？

以下は、使用例

```RPGLE:QII0150R.rpgle
D*- ---<< 変数定義    >>-----*
D TS1             S             26Z
D TS2             S             32A
D MSG             S             40A
C*- ***************************************************************
C*- *  メインロジック                                            **
C*- ***************************************************************
C*-  Ｖ７Ｒ５よりマイクロ秒で取得される
C                   EVAL      TS1         = %TIMESTAMP()
C                   EVAL      MSG         = ' マイクロ秒 '
C                                         + %CHAR(TS1)
C     MSG           DSPLY
C*
C*-  ユニーク・タイムスタンプ取得
C                   EVAL      TS2         = %CHAR(
C                                            %TIMESTAMP(*UNIQUE)
C                                           )
C                   EVAL      MSG         = 'U-TS.'
C                                         + %CHAR(TS2)
C     MSG           DSPLY
C*
C                   SETON                                        LR
C                   RETURN
```

## 本当にユニーク・タイムスタンプ？
但し、現時点で上記を実行すると、**「本当にユニーク・タイムスタンプ？」** と疑問が湧く。なぜなら以下が実行結果のスクリーンショットだからだ。ユニークになる筈の下６桁は常に「**000244**」。

■ 複数回実行しても常に固有値部分が同じ
![2022-11-27_160223.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/513c744b-dfee-66b3-8a60-60a2e20dee95.png)

■ 異なるユーザー・ジョブで実行しても常に固有値部分が同じ
![2022-11-27_161144.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/4a4d9e6e-56ff-46d2-194d-d3674fe71b2b.png)

因みにマニュアルの例での出力も「**000244**」となっている

***以下マニュアルより引用***

>最初のパラメーターが *UNIQUE の場合、%TIMESTAMP は現在のシステム・タイム・スタンプをマイクロ
秒単位の精度で戻します。 タイム・スタンプの小数部の最初の 6 桁には、タイム・スタンプのマイクロ秒
の部分が設定されます。 残りの 6 桁の小数秒に値に設定され、この値によって、結果として生成されるタ
イム・スタンプが固有になります。 ただし、その残りの 6 桁の小数秒によって、タイム・スタンプの精度
が上がることはありません。

```
dsply (%timestamp(*UNIQUE);
// It displays 2014-06-27-01.02.03.923481000244
```

これは、**「*UNIQUE」** に関しては、少し様子見ですね。時間がある時に、SWMA で聞いてみましょうかね。
Debianでログインしたあとに画面が真っ暗でGNOMEが起動しない

Debianでログインしてもデスクトップが表示されない問題。
#### 環境
- Debian 11.5 (bullseye)
=> Debian 12 (bookworm)でも同じ問題が発生する

#### 対処法その1
- NVIDIAドライバを消す
=> 多分これが一番速い。ただしNouveauカーネルドライバに戻るためパフォーマンスが下がる。
`Ctrl+Alt+F5`でターミナルに入り次のコマンドを実行する。

```
~# apt purge nvidia-*
~# reboot
```

#### 対処法その2
- デスクトップ環境を変える
=> NVIDIAドライバは残るがSnapやVLCなどの一部ソフトは再インストールする必要がある
gnomeを消した後、`tasksel`で別のデスクトップ環境をインストールする。

```
~# apt purge gnome*
~# tasksel
~# reboot
```

#### 対処法その3
- Debianを再インストールする
=> データが消えるがこれが一番？
【TidalCycles】onceをサイクルと同期して実行させる

# はじめに

[TidalCycles](https://tidalcycles.org/)は通常、実行したリズムパターンを永遠に繰り返します。

https://qiita.com/mynkit/items/620082b82a4bbe475823

ただ、指定したリズムパターンを1サイクルだけ実行するonce関数というものがあります。

https://tidalcycles.org/docs/reference/patterns#doing-things-once

たとえば次のような簡単なハイハットが鳴るだけのリズムパターンを考えます。

```haskell
d1 $ s "808oh*4" # speed "2 1 1 1"
```

このリズムが鳴っているときに、以下を実行すると、`bd`(バスドラ)が一度だけ再生されると思います。


```haskell
once $ s "bd"
```

しかし、これを実行してから実際に`bd`が再生されるまでにはレーテンシーが発生しますし、次のような音数が多いパターンなどになるとサイクルと無関係に再生されてしまうのは不便かと思います。

```haskell
once $ s "[~bd]*4 ~"
```

そのため、実行したあと、次のサイクルの頭に再生してくれる機能が欲しくなります。

# once'関数の実装

同じこと考えているひとがいないか、Tidalのコミュニティ[TidalClub](https://club.tidalcycles.org/)で探してみたところ、ドンピシャなものが見つかりました。

https://club.tidalcycles.org/t/once-at-beginning-of-cycle/3345

これによると、以下のようにしてonce'関数を実装してみれば良いらしいです

```haskell
seqC x y pt= (p x . (|< orbit (x-1))) $ qtrigger x $ seqP [(0, y, pt)]
once' x = seqC x 1
```

ただ実行してみるとわかる通り、これは以下のエラーが出ます。(動作環境: macOS, TidalCycles 1.7.10)

```
t> 

    • Couldn't match expected type ‘Pattern Int’
                  with actual type ‘Sound.Tidal.ID.ID’
    • In the first argument of ‘orbit’, namely ‘(x - 1)’
      In the second argument of ‘(|<)’, namely ‘orbit (x - 1)’
      In the second argument of ‘(.)’, namely ‘(|< orbit (x - 1))’
```

これは`p x`のxの型がIDであり、他のxはPattern Intとして扱われているために起こるエラーです。残念ながら自分ではIDとPattern Intの変換関数を見つけることができなかったので、あまり使わない`d16`チャンネルをonce'関数用のチャンネルとして使うことにしました。

最終的なコードはこちらで、これを`BootTidal.hs`に追記すればonce'関数が使えるようになっていると思います。

```haskell
:{
seqC :: Time -> Pattern ValueMap -> IO ()
seqC y pt= (p 16 . (|< orbit 15)) $ qtrigger 16 $ seqP [(0, y, pt)]

once' :: Pattern ValueMap -> IO ()
once' = seqC 1
:}
```

BootTidal.hsへの追記方法はこちらが参考になるかと思います

https://qiita.com/mynkit/items/10c32ff7cac1ed8a636d

# テスト

試しにonce'関数を動かしてみましょう。


```haskell
d1 $ s "808oh*4" # speed "2 1 1 1"

once' $ s "[~bd]*4 ~" # orbit 1
```

まずd1の方を動かしてから、once'のほうを動かしてみてください。
once'を実行した、次のサイクルの頭に指定したリズムパターン`s "[~bd]*4 ~"`が一度だけ再生されるのを確認できるかと思います。

ちなみに`# orbit 1`をつけているのは明示的にどのチャンネルとして音を出したいかを指定するためで、例えば以下のようにd1にリバーブをかけた状態だで`# orbit 0`を指定すると、`bd`にもリバーブがかかってしまいます。

```haskell
d1 $ s "808oh*4" # speed "2 1 1 1" # room 0.7

once' $ s "[~bd]*4 ~" # orbit 0
```

これは`d1→orbit 0`, `d2→orbit 1`, `d3→orbit 2`, ... とデフォルトで各dnに対してorbitが割り振られているためで、once'のorbitを1にしてあげればd1のリバーブが掛からずにすみます。
contabo VPSにxrdpをインストールしてみた

参照サイト
https://www.youtube.com/watch?v=OEK86061KEU
https://novicengineering.com/ubuntu_mozc_install/

contabo VPSにxrdpをインストールしてみた。
Youtube動画のコマンドをそのまま入力して構築できた。

```
sudo apt-get update 
 sudo apt-get upgrade
 sudo apt-get install ubuntu-desktop
 sudo apt install gnome-software
 sudo apt-get install xrdp htop  

 sudo rm /usr/share/polkit-1/actions/org.freedesktop.color.policy
 sudo adduser remote
 sudo usermod -aG sudo,adm remote 
 sudo reboot
```

日本語環境をインストール
```
$ sudo apt install ibus-mozc 
$ ibus restart 
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'jp'), ('ibus', 'mozc-jp')]"
```
Route53①-名前解決

# 本記事の内容

この記事では３回目のANS-C01を受けるにあたって勉強した内容を整理するための記事です。
今回はRoute53の名前解決の部分についての**第1回目**となります。

# Route53とは
Route53とはAWSサービスにおける以下の内容を管理するためのサービスです。
今回「1．ドメイン登録機能」について書いていきます。
1.  ドメイン登録機能
    - AWSサービス内のドメイン名の管理を行います。
1.  ドメインのリソースへのインターネットトラフィックのルーティング
    - Route53で管理しているドメインに関するDNSクエリのルーティングを行います。
1.  リソースの正常性のチェック
    - ウェブサーバーへの正常性確認を行います。

# そもそもドメインとは

一言でいうとドメインは **「サーバーの名前」** です。
各サーバーにはIPアドレスが割り振られていますが、IPアドレスに対してドメインという名前が割り振られています。
ドメインとIPアドレスの関係は **DNSサーバー** で管理されており、DNSサーバーにアクセスしてドメインからIPアドレスを導出することを **名前解決** といいます。
DNSサーバーへのアクセスを行うためのサーバーとして **キャッシュDNSサーバー** がありユーザはまずキャッシュDNSサーバーにアクセスをします。

キャッシュDNSサーバーからDNSサーバーにアクセスして名前解決すれば終わりではありますが、世の中にはたくさんのドメインがあふれています。そのためDNSサーバーはそれぞれのサーバーの責任範囲を区切っていくつも存在しています。
ドメインの責任を持っているDNSのことを **権威DNSサーバー** といい、DNSサーバーから権威DNSサーバーに名前解決をゆだねることを **委任** と呼びます。

詳しい図は[こちら](https://domainname.jp/report/dns)を参照してください。

Route53のドメイン登録機能ではこの内、

- 権威DNSサーバー
- 委任元DNSサーバー

としての機能を担います。
また、DNSサーバーの責任範囲はドメイン名の.(ドット)の区切りで分かれています。
例えば、_**haru.qiita.com**_ というドメイン名があった場合
_**com**_ （トップレベルドメイン）の責任を負うサーバー、
_**qiita.com**_ （ドメイン）の責任を負うサーバー、
_**haru.qiita.com**_ （サブドメイン）の責任を負うDNSサーバーが存在します。

サブドメインは複数階層可（_**haru2.haru.qiita.com**_ とか）ですが、
目的のドメインと一致するドメイン名のことを _**FQDN**_ と呼びます。

以下の説明では目的のドメイン名を _**haru.qiita.com**_ として記載していきます。

# 権威DNSサーバーとしてのRoute53
権威サーバーは以下3種類のレコードを持っているDNSサーバーを指します。
- _**haru.qiita.com**_ の管理情報を記載したレコード（**SOAレコード**）
- _**haru.qiita.com**_ のIPアドレスを管理しているネームサーバーを記載したレコード(**NSレコード**)
- 責任分割を行わないサブドメイン（_**haru2.haru.qiita.com**_ 等）のIPアドレス情報(IPv4ならAレコード/IPv6ならAAAAレコード)

権威サーバーとして管理しているドメインを**ゾーン**とも呼びます。
Route53で管理するゾーンには、**パブリックゾーン**と**プライベートゾーン**が存在します。
**パブリックゾーン**の場合はインターネット上での名前解決となりますが、
**プライベートゾーン**の場合は自身のネットワーク環境内でのみ名前解決が出来ます。

# 委任元DNSサーバーとしてのRoute53
委任元サーバーは以下のレコードを持っているDNSサーバーを指します。
- 責任分割を行い、別ゾーンとして管理されているサブドメイン（_**haru2.haru.qiita.com**_ 等）のネームサーバー情報(NSレコード)

# DNSの暗号化（DNSSEC）
参考は[こちら](https://www.nic.ad.jp/ja/newsletter/No43/0800.html)

上記までの説明のように、Route53はDNSサーバーとしての役割を持ちます。
DNSサーバーは名前解決のリクエスト（DNSクエリ）があるとそれに対応した情報を返しますが、返ってきたドメイン情報の正当性が検証されていません。
そのためにドメイン情報の正当性を担保するための仕組みを**DNSSEC**といいます。
DNSSECではドメイン電子署名を利用し検証が行われます。


# オンプレミス環境との名前解決について
Route53 Resolverを使用することでプライベートホストゾーンでもオンプレ環境との名前解決が可能である。
Route53 Resolverはエンドポイントを設置することで使用可能

- インバウンドエンドポイント
    - オンプレからAWS内の名前解決を行う際に使用
- アウトバウンドエンドポイント
    - AWS内からオンプレの名前解決を行う際に使用