OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】半角カタカナ、全角カタカナ、ひらがなへの変換


```javascript:
const HALF_KATA = [
	'ｧ','ｱ','ｨ','ｲ','ｩ','ｳ','ｪ','ｴ','ｫ','ｵ',
	'ｶ','ｶﾞ','ｷ','ｷﾞ','ｸ','ｸﾞ','ｹ','ｹﾞ','ｺ','ｺﾞ',
	'ｻ','ｻﾞ','ｼ','ｼﾞ','ｽ','ｽﾞ','ｾ','ｾﾞ','ｿ','ｿﾞ',
	'ﾀ','ﾀﾞ','ﾁ','ﾁﾞ','ｯ','ﾂ','ﾂﾞ','ﾃ','ﾃﾞ','ﾄ','ﾄﾞ',
	'ﾅ','ﾆ','ﾇ','ﾈ','ﾉ',
	'ﾊ','ﾊﾞ','ﾊﾟ','ﾋ','ﾋﾞ','ﾋﾟ','ﾌ','ﾌﾞ','ﾌﾟ','ﾍ','ﾍﾞ','ﾍﾟ','ﾎ','ﾎﾞ','ﾎﾟ',
	'ﾏ','ﾐ','ﾑ','ﾒ','ﾓ',
	'ｬ','ﾔ','ｭ','ﾕ','ｮ','ﾖ',
	'ﾗ','ﾘ','ﾙ','ﾚ','ﾛ',
	'ヮ','ﾜ','ヰ','ヱ','ｦ','ﾝ','ｳﾞ','ヵ','ヶ','ﾜﾞ','ｲﾞ','ｴﾞ','ｦﾞ'
]

const halfKataToWide = (text, hira=false) => {
	const firstCharCode = hira === true ? 12353 : 12449
	return text.replace(/[ﾜｲｴｦ]ﾞ/g, m => 
			'ヷヸヹヺ'.charAt('ﾜﾞｲﾞｴﾞｦﾞ'.indexOf(m) / 2)
		).replace(/([ｦ-ｯｱｲｴｵﾅ-ﾉﾏ-ﾝ]|[ｳｶ-ﾄ]ﾞ?|[ﾊ-ﾎ][ﾞﾟ]?)/g, m => 
			String.fromCharCode(HALF_KATA.indexOf(m) + firstCharCode)
		).replace(/[ﾞﾟｰ｡｢｣､･]/g, m => 
			'゛゜ー。「」、・'.charAt('ﾞﾟｰ｡｢｣､･'.indexOf(m))
		)
}

const toHira = (text) => 
	halfKataToWide(text, true).replace(/[ァ-ヶ]/g, m => String.fromCharCode(m.charCodeAt(0) - 0x60))

const toWideKata = (text) => 
	halfKataToWide(text).replace(/[ぁ-ゖ]/g, m => String.fromCharCode(m.charCodeAt(0) + 0x60))

const toHalfKata = (text) => 
	text.replace(/[ァ-ヺ]/g, m => HALF_KATA[m.charCodeAt(0) - 12449])
		.replace(/[ぁ-ゖ]/g, m => HALF_KATA[m.charCodeAt(0) - 12353])
		.replace(/[゛゜ー。「」、・]/g, m => 'ﾞﾟｰ｡｢｣､･'.charAt('゛゜ー。「」、・'.indexOf(m)))


const str = 'ひびぴヒビピﾋﾋﾞﾋﾟゐゑをんゔゕゖﾝﾞﾟｦﾞﾟｰ｡｢｣､･゛゜ー。「」、・'
console.log(toHira(str))
			//ひびぴひびぴひびぴゐゑをんゔゕゖん゛゜ヺ゜ー。「」、・゛゜ー。「」、・
console.log(toWideKata(str))
			//ヒビピヒビピヒビピヰヱヲンヴヵヶン゛゜ヺ゜ー。「」、・゛゜ー。「」、・
console.log(toHalfKata(str))
			//ﾋﾋﾞﾋﾟﾋﾋﾞﾋﾟﾋﾋﾞﾋﾟヰヱｦﾝｳﾞヵヶﾝﾞﾟｦﾞﾟｰ｡｢｣､･ﾞﾟｰ｡｢｣､･
```

自分でまとめた変換用のclass構文からメソッドを抜き出して再構築したものです。
Webエンジニアなら知っておきたい基礎用語

#はじめに
エンジニアは日々様々な専門用語飛び交う開発現場で作業を行います。
ベテランのエンジニアの方であれば母国語のごとく無意識に扱うことのできる用語たちも駆け出しエンジニアにとってはまるで魔法か異国後かといったように聞こえることも多々あることではないかと思います。

今回はエンジニアとして活動を始めて3ヶ月経過した私が特によく耳にする、もしくは知っておいた方がいいだろうと判断した『Webサイト制作・改善』に関する用語を解説も交えながら紹介していこうと思います。
なお今回紹介する用語はこちらの[『支持される　Webデザイン事例集』](https://www.amazon.co.jp/2%E4%B8%87%E5%9B%9E%E3%81%AEA-B%E3%83%86%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%81%A3%E3%81%9F-%E6%94%AF%E6%8C%81%E3%81%95%E3%82%8C%E3%82%8BWeb%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E4%BA%8B%E4%BE%8B%E9%9B%86-%E9%AC%BC%E7%9F%B3-%E7%9C%9F%E8%A3%95/dp/4774199389) を参考にさせていただきました。

#対象者
・最近Web業界に参入したばかりの駆け出しエンジニアの方
・個人でWebサイトやブログを運営している方
・将来的にWebエンジニアになりたいと思っている方
・単純にWebサイトに関連するワードを知りたい方

#Webサイト　関連用語

###トラッキング
日本語で『追跡』という意味の単語。Webサイト上の様々な情報を数値をもとに追跡できるようにすることを指す。

###LP(ランディングページ)
ユーザーがサイトにアクセスした際に最初に表示されるページのこと。
もしくは広告などからユーザーがランディング(アクセス)した際に、特定のアクションをしてもらうことのみを目的として制作されたサイト

###ファーストビュー
PC/スマホでサイトにアクセスした際に最初に見える画面のこと。各ページにおいて最もみられる最重要エリア。

###グロースハック
様々なサイト改善手法を用いて効率的に効果を出すこと。
グロースハックを実施する人たちを『グロースハッカー』と呼ぶ。

###CPA
『Cost Per Acquisition』の略称。『顧客獲得単価』のこと。
1人の新規顧客を獲得するのにかかる費用(広告費・人件費等)を指す。

###CVR
『Conversion Rate』の略称。『獲得率』のこと。
特定のページにおいて運営側が期待するアクションを、ユーザーが行う率のことを指す。(会員登録ボタンのクリックなど)

###LTV
『Life Time Value』の略称。『顧客生涯価値』のこと。
1人のユーザーが1サービスに対して支払う総金額の平均値のこと。

###UI
『User Interface』の略称。『製品(サービス)とユーザー(利用者)の接点』のこと。
Webサイト・スマホアプリにおいて『見た目・使いやすさ』を指す単語として使用されることが多い。

###UX
『User Experience』の略称。『顧客体験』のこと。
『サービスを通じて得られる全てのユーザー体験』を指す。

###UIとUXの違い
UXは『1つのサービス(商品)全体を通して得られる体験』のこと。
例：高級ブランドの時計を身につけることにより得られる幸福感や満足感。
UIは『サービス(商品)の見た目や使いやすさ』のこと。
例：説明書を読まなくても使い方がわかる扱いやすさ。伝えたいことが1目でわかるWebサイト。

###DMP
『Data Management Platform』の略称。
顧客に関する様々な情報を活用し、広告配信やサイト改善などの効率化に利用できる機能を持つプラットフォーム・サービスのこと。

###CRM
『Customer Relationship Management』の略称。
顧客との継続的な関係を築くために、顧客情報や関係性を管理しより強固な関係性作りのための施策を実施するマネジメント手法の総称。

###KPI
『Key Performance Indicator』の略称。『重要業績評価指標』のこと。
企業やチーム・個人の取り組みを評価するために設定される目標のこと。

###KGI
『Key Goal Indicator』の略称。『重要目標評価指標』のこと。
企業の掲げる目標・目的を達成するために設定される指標のこと。

###EC
『Electronic Commerce』の略称。『電子商取引』のこと。
インターネット上で行われる全ての商品やサービスの売買を指す。

###SPA
『Single Page Application』の略称。
単一のWebページでコンテンツ切り替えを行うことで、ページ遷移の必要がなく、ブラウザの挙動に縛られないWeb表現を可能にする設計構造の名称。

###UU
『Unique User』の略称。『ユニークユーザー』のこと。
サイトに訪れた『本当のユーザー数』を指す点がPV数やセッション数と異なる点。
具体例：1人のユーザーがあるサイトを1日にスマホで5ページ、PCで10ページ閲覧した場合
PV数　＝　15
セッション数　＝　2
日間UU ＝　1

###SEO
『Search Engine Optimize』の略称。『検索エンジン最適化』のこと。
検索エンジン(Google・Yahoo)で検索した際に、検索結果画面の上位に表示される為に行う様々な施策を指す。

#まとめ
エンジニアは特に覚えなければならない用語が多く、新しい用語も次から次に出てくるので言葉を覚えるのが非常に大変です。
しかし多くの用語を正しい理解で記憶することが出来れば、エンジニアとして仕事をしていくための武器を増やすことにつながります。

まずは自分なりの覚えやすい方法で少しずつ知識の引き出しと中身を増やし、様々な状況に対応できる強いエンジニアを目指しましょう！
特にアルファベット3文字の用語は多すぎてわけが分からなくなるので、略される前の英単語とその意味で記憶するのが覚えやすいそうです。
#参考文献
この記事は以下の情報を参考にして執筆しました。
[『支持される　Webデザイン事例集』](https://www.amazon.co.jp/2%E4%B8%87%E5%9B%9E%E3%81%AEA-B%E3%83%86%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%81%A3%E3%81%9F-%E6%94%AF%E6%8C%81%E3%81%95%E3%82%8C%E3%82%8BWeb%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E4%BA%8B%E4%BE%8B%E9%9B%86-%E9%AC%BC%E7%9F%B3-%E7%9C%9F%E8%A3%95/dp/4774199389)
Linux　標準入出力について

## リダイレクト
リダイレクトとは入出力先を変更する機能
標準入力＝０
標準出力＝１
標準エラー出力＝２

- 入力のダイレクト＝キーボードの代わりにファイルから入力できる

```
// etc/hostsファイルを入力元にcatコマンドを実行
cat < etc/hosts
```

- 出力のリダイレクト＝コマンドの実行結果をファイルに保存する機能

```
// lsコマンドの出力先をtest.txtに保存
ls > test.txt
```

- エラー出力のリダイレクト＝エラー結果をファイルに保存する機能
２をつける

```
// lsコマンドの出力先をtest.txtに保存
ls /hoge 2> test.txt
```

※まとめる場合には最後に「2>&1」とかく
※「>」は上書き、「>>」は追記

## /dev/nullとは
入力先として指定しても何も返さず、出力先として指定するとデータが消える
出力のメッセージとかだしたくないときにつかう

## パイプラインとは
「|」ってかき、複数コマンドをつなげる事ができる
リモートブランチをローカルにコピーする方法

# 目的
自分向けにgithubのすぐ忘れるcommandをメモする。

```
$ git fetch
$ git checkout -b myBranch origin/myBranch
```

`git fetch`でリモートリポジトリを追跡する。
`git checkout`でfetchした内容からブランチを作成する。


# これまでは
いつも今いるブランチをcheckoutして新しくブランチを作ってから git pullしていた。
この方法だと今いるブランチから新しいブランチが切られて、pull元のブランチとマージされる扱いになるのでバグってしまう。
【JavaScript】関数とオブジェクト㉒　チェーンメソッド



#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/1f19e2fdc364522f8d71

#目的

* 関数とオブジェクトについての理解を深める

#本題
###1.チェーンメソッド

メソッドチェーンともいう？？？？
その名の通りメソッドを繋げて処理が書ける


https://note.affi-sapo-sv.com/js-mnethod-chain.php

####前提
````js
class Person {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
// それぞれメソッドを追加し、、consoleに出力できるように設定
	hello(person) {
		console.log(`${this.name} says hello ${person.name}`);
	}

	introduce() {
		console.log(`Hi, I'm ${this.name}, ${this.age} years old.`);
	}

	shakeHands(person) {
		console.log(`${this.name} shake hands with ${person.name}.`);
	}

	bye(person) {
		console.log(`Goodbye, ${person.name}.`);
	}
}

const bob = new Person('Bob', 23);
const tim = new Person('Tim', 33);

bob.hello(tim);
bob.introduce();
bob.shakeHands(tim);
bob.bye(tim);;
````

####例1

チェーンメソッドは１つのインスタンスに対して連続で処理が行えるように設定できるもの

```js
class Person {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}

	hello(person) {
		console.log(`${this.name} says hello ${person.name}`);
		// returnでthisを設定
		// このthisにはコンストラクター関数から作成したオブジェクトとなる
		return this;
	}

	introduce() {
		console.log(`Hi, I'm ${this.name}, ${this.age} years old.`);
		return this;
	}

	shakeHands(person) {
		console.log(`${this.name} shake hands with ${person.name}.`);
		return this;
	}

	bye(person) {
		console.log(`Goodbye, ${person.name}.`);
		return this;
	}
}

const bob = new Person('Bob', 23);
const tim = new Person('Tim', 33);

// return thisを設定すると,
// introduceが格納されているオブジェクトのインスタンスをメソッドで返してやることによって続けて書くことができる
bob.hello(tim)
.introduce()
.shakeHands(tim)
.bye(tim);;
`````

出力結果

```
Bob says hello Tim
Hi, I'm Bob, 23 years old.
Bob shake hands with Tim.
Goodbye, Tim.
```



今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
* [【JavaScript】 メソッドチェーンを本質的に理解する](https://note.affi-sapo-sv.com/js-mnethod-chain.php)
Pandasのread_fwfで固定長のデータを変換（震度データ）

# 参考

日本の地震データを加工してわかりやすくしてみた
https://qiita.com/T_programming/items/2dae8f40941ff3581036

# read_fwfで固定長のデータを変換

https://pandas.pydata.org/docs/reference/api/pandas.read_fwf.html

+ read_fwfだと全角文字を１文字と認識してしまうためずれてしまう
+ 「震央地名」が全角文字のためずれる
+ 「震央地名」以降を一旦全部取得後に分離する

# ダウンロード

```
!wget https://www.data.jma.go.jp/svd/eqev/data/bulletin/data/shindo/i2019.zip
```

# プログラム

```python
import pandas as pd

widths = [1, 4, 2, 2, 2, 2, 4, 4, 3, 4, 4, 4, 4, 4, 5, 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 28]

names = [
    "ヘッダー",
    "西暦",
    "月",
    "日",
    "時",
    "分",
    "秒",
    "標準誤差(秒)",
    "緯度(度)",
    "緯度(分)",
    "緯度標準誤差(分)",
    "経度(度)",
    "経度(分)",
    "経度標準誤差(分)",
    "深さ(km)",
    "標準誤差(km)",
    "マグニチュード１",
    "マグニチュード１種別",
    "マグニチュード２",
    "マグニチュード２種別",
    "使用走時表",
    "震源評価",
    "震源補助情報",
    "最大震度",
    "被害規模",
    "津波規模",
    "大地域区分番号",
    "小地域区分番号",
    "震央地名",
]

df = pd.read_fwf(
    "i2019.zip",
    encoding="cp932",
    header=None,
    widths=widths,
    names=names,
)

# 抽出

df1 = df[df["ヘッダー"].isin(["A", "B", "D"])].copy().reset_index(drop=True)

# 震央地名から「観測点数」と「震源決定フラグ」を分離

df1["観測点数"] = pd.to_numeric(df1["震央地名"].str[-6:-1].str.strip()).astype("Int64")
df1["震源決定フラグ"] = df1["震央地名"].str[-1]
df1["震央地名"] = df1["震央地名"].str[:-6].str.strip()

# 単位調整

df1["秒"] = df1["秒"].astype(float) / 100
df1["標準誤差(秒)"] = df1["標準誤差(秒)"].astype(float) / 100

df1["緯度(分)"] = df1["緯度(分)"].astype(float) / 100
df1["緯度標準誤差(分)"] = df1["緯度標準誤差(分)"].astype(float) / 100

df1["経度(分)"] = df1["経度(分)"].astype(float) / 100
df1["経度標準誤差(分)"] = df1["経度標準誤差(分)"].astype(float) / 100

df1["標準誤差(km)"] = df1["標準誤差(km)"].astype(float) / 100

df1["マグニチュード１"] = df1["マグニチュード１"].astype(float) / 10
df1["マグニチュード２"] = df1["マグニチュード２"].astype(float) / 10

# 日付変換

df_date = (
    df1[["西暦", "月", "日", "時", "分", "秒"]]
    .copy()
    .set_axis(["year", "month", "day", "hour", "minute", "seconds"], axis=1)
)

df1["datetime"] = pd.to_datetime(df_date)

df1.to_csv("2019.csv", encoding="utf_8_sig")
```
サイト改善に役立つ『A/Bテスト』について

#はじめに
現在とある案件でWebサイトの数値改善のタスクをこなしていたのですが、思うように数値が改善されず非常に頭を抱えていました。
何かヒントをもらおうと[『支持される　Webデザイン事例集』](https://www.amazon.co.jp/2%E4%B8%87%E5%9B%9E%E3%81%AEA-B%E3%83%86%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%81%A3%E3%81%9F-%E6%94%AF%E6%8C%81%E3%81%95%E3%82%8C%E3%82%8BWeb%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E4%BA%8B%E4%BE%8B%E9%9B%86-%E9%AC%BC%E7%9F%B3-%E7%9C%9F%E8%A3%95/dp/4774199389)という本を読んでいたところ、Webサイト改善に非常に役立ちそうな『A/Bテスト』というものについて学習することができたので、今後同じような内容で頭を抱えるエンジニアを1人でも減らす為、及び備忘録として記事に残します。
#対象者
・Webサイト改善をまかされたエンジニア
・個人でWebサイトやブログを運営している人
・今後サイトを制作、運営する予定のある人


#A/Bテスト

###A/Bテストとは？
課題のあるWebページにおいて、複数のデザインのうち最も期待する効果の高いデザインを競わせるテストのこと。

##実施方法
複数のデザインを実際の本番環境でエンドユーザーに向けて、ランダムに同じ数だけ振り分けて、どのデザインが最も反応がいいかを調査する。
デザインの振り分けにはA/Bテストツールというツールを利用する。

##具体例
『A・B・C』3種類のデザインの異なる会員登録ページを用意し、サイトアクセスした3000人にそれぞれ均等に表示し登録率を計測
サイトA　→　1000人中100人が登録　＝　登録率10％
サイトB　→　1000人中150人が登録　＝　登録率15％
サイトC　→　1000人中200人が登録　＝　登録率20％
この結果からサイトCのデザインを使用することで、最も期待する効果を発揮することが出来ると分かる。

##A/Bテスト実施のメリット
①大規模なサイト改修を行う前に、その改善が本当に期待する効果があるのかを知ることができる。
②クライアントに改善を提案する際に、事実と数値を持って提案できるため納得してもらいやすい。
③検証から改善までをスピーディーに実施できるため、急速に変化するトレンドに対応しやすい。

#まとめ
Webサイト改善においてついつい個人の感性や直感で問題点にあたりをつけて即改善→リリースと動いてしまいがちですが、せっかく実装した機能がまったくの検討違いで無意味に終わってしまうのは非常に悲しいことです。
準備や慣れるまでには少し時間がかかりそうですが、ほぼ間違いなく効果が出ると自信を持てる改善を実装できることは非常に魅力的だと思いますので、ぜひ1度『A/Bテスト』を試してみてはいかがでしょうか？
#参考文献
この記事は以下の情報を参考にして執筆しました。
[『支持される　Webデザイン事例集』](https://www.amazon.co.jp/2%E4%B8%87%E5%9B%9E%E3%81%AEA-B%E3%83%86%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%81%A3%E3%81%9F-%E6%94%AF%E6%8C%81%E3%81%95%E3%82%8C%E3%82%8BWeb%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E4%BA%8B%E4%BE%8B%E9%9B%86-%E9%AC%BC%E7%9F%B3-%E7%9C%9F%E8%A3%95/dp/4774199389)
【UiPath】データテーブル操作でINを使いたい！

# なにをしたいのか
UiPathでデータテーブルを操作する際にもっとSQLを活用したい！という願望です。
今回はIN句を使って、「特定列に調べたい値が存在するのか」を調べてみます。

# どうやってやるのか
今回は下のデータテーブル（dtbFood）を例に、
「くだもの」列に「いちご」の値が存在するかをSQLのIN句を使ってみていきます。

|さかな|にく|くだもの|こめ|
|:--:|:--:|:--:|:--:|
|アジ|豚肉|ぶどう|あきたこまち|
|カツオ|鶏肉|いちご|つや姫|
|マグロ|牛肉|りんご|ゆめぴりか|
|サンマ|鹿肉|みかん|こしひかり|


使う文↓

```ruby:右辺
dtbFood.Select("[くだもの] IN ('いちご')").CopyToDataTable
```

```ruby:左辺
データテーブル名（dtbTempとか）
```
範囲を読み込みで、調べたいテーブルを「dtbFood」として出力させて、次の代入で「くだもの」列に「いちご」の値がある行を抽出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256239/18211095-345e-227e-0b15-1107964934d9.png)

↓実行してみると
dtbTempの中身には「いちご」が存在する行が抽出されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256239/fe8b80a5-68d8-4eed-6c4e-5ffd24a3d0f3.png)

↓「いちご」が存在する行は1行なので、行数を出力させると「1」と表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256239/d552c871-5282-575e-0da4-33ea4f4f71a6.png)

↓ORを使って複数条件での抽出も可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256239/581acc9d-2310-9fc2-b45f-e3297813a4ba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256239/b1d70d0f-77ea-64f7-ba18-14603772e3c9.png)



# 独り言
データテーブルをフィルタリングでも同じことが出来ますが、繰り返し処理の中でフィルタリングを多用するとなんだか処理が重い…？
SQLで実装すべくIN句を使うに至りました。
そのままコピペして使えそうな記事がなかったので（※僕調べ）備忘用記事。
もっといい方法があったら教えてください(´；ω；`)
メモ〜LoginRequiredMixinの使い方

今回のお題
-
今回はdjangoの`LoginRequeiredMixin`についてまとめます。

`LoginRequiredMixin`を用いることで、ログインしていないユーザーを特定のページにリダイレクトするという仕様を簡単に実装できるようになります。

目次
-

- Mixinとは
- LoginRequiredMixinとは
- 実装例
- 注意点

Mixinとは
-
Mixinとはdjangoのクラスベースビューに搭載されている機能の一つで、ビューに特定の機能（例えばログインしていない状態でそのページに遷移しようとするとログインページにリダイレクトされる、など）を付け加える際に使用される。

Mixinの実態は`AcccessMixin`というスーパークラス及びそのサブクラスであり、テンプレートビュークラスを定義する際にMixinを継承させることで継承元のMixinの持つ機能をビューに付加することができる。

ちなみに、`CreateView`などのいわゆる汎用ビューもMixinを継承して定義されています。

```python
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
    """
    View for creating a new object, with a response rendered by a template.
    """
    template_name_suffix = '_form'
```

LoginRequiredMixinとは
-
`LoginRequiredMixin`はMixinの一つであり、このMixinを継承することで`ログインしていないユーザーを特定のページに遷移させる`という機能を実装することができるようになります。

遷移先のurlは、`login_url`という属性値を用いて指定します。

実装例
-
では、Mixinについてわかったところで今回のお題である`LoginRequiredMinin`を用いてテンプレートに機能を追加していきます。

```python:myapp/models.html
class IndexView(LoginRequiredMixin, TemplateView):
  template_name = "myapp/index.html"
  login_url = reverse_lazy("account_login") # リダイレクト先の指定
```
`login_url`という変数を用いてリダイレクト先のurlを指定しています。

また、今回のように継承元が複数ある場合には、`Mixinが先`で`TemplateViewが後`になるので注意してください。

注意点
-
今回は遷移先のurlを、`reverse_lazy`を用いて以下のように定義しました。

```python
login_url = reverse_lazy("account_login")
```
ルーティングnameからurlを逆引きするだけであれば他に`reverse`もありますが、こちらを使うとエラーになります。

この理由に関しては、

>テンプレートビュークラスに属性値がセットされる段階では`urls.py`はまだ呼び出されていない(=プロジェクト側がルーティングnameを把握してない）ので、その段階で`reverse`を用いてルーティングnameを参照しようとするとエラーになる。

>しかし`reverse_lazy`関数であればurls.pyが読み込まれるまで処理を遅延させることができるので、クラスの属性値としてルーティングnameを参照してもエラーにならない。

>ちなみにクラスに定義した関数やメソッドが呼ばれる際にはurls.pyの読み込みは完了しているので、reverseを用いても問題はない。

とのことです。

終わりに
-

以上がLoginRequiredMixinの使い方になります。

ログイン状態の有無で処理を分けたい時は結構あるので、うまく使いこなしていきたいですね。
PacketSerialのサンプルプログラム

#概要

https://qiita.com/hideakitai/items/347985528656be03b620

こちらの方の、プログラムが素晴らしいです。
PacketSerialのサンプルプログラムが無かったのと、公式のサンプル例もいいですが
floatを送る例ではないので、載せます。

#サンプルプログラム
サンプルの動作確認では、
送信側：Arduino Mega　Serial3
受信側：esp32 , Serial2

にとして、GNDとRX,TXを接続しています。
よって、Serialの番号に関しては変更が必要です

```C:receiver
#include <PacketSerial.h>
PacketSerial myPacket;

volatile uint8_t tempBuffer[16];               //受信生データ保存配列
volatile boolean serial_update_flag = false;   //データの受信フラッグ
volatile float received_data = 0;              //受信データ

union Position
{
  struct {
    float gx;

  };
  uint8_t bin[sizeof(float) * 1];
};


void setup() {
  Serial.begin(250000);
  
  Serial2.begin(250000);
  myPacket.setStream(&Serial2);
  myPacket.setPacketHandler(&onPacketReceived);
}

void onPacketReceived(const uint8_t* buffer, size_t size) {
  serial_update_flag = true;
  for (int i = 0; i < size; i++) {
    tempBuffer[i] = buffer[i];
  }
  
  Position unconv;
  unconv.bin[3] = tempBuffer[3];
  unconv.bin[2] = tempBuffer[2];
  unconv.bin[1] = tempBuffer[1];
  unconv.bin[0] = tempBuffer[0];
  received_data = unconv.gx;
}
void loop() {
  myPacket.update();
  if (myPacket.overflow()) {
    Serial.println("over flow error");
  }
  if (serial_update_flag == true) {
    serial_update_flag = false;
    Serial.println(received_data);    
  } 
}
```

```C:sender
#include <PacketSerial.h>
PacketSerial myPacket;

volatile uint8_t tempBuffer[16];               //受信データ保存配列
volatile boolean serial_update_flag = false;   //データの受信フラッグ

union Position
{
  struct {
    float gx;
  };
  uint8_t bin[sizeof(float) * 1];
};

void setup() {
  Serial.begin(250000);
  Serial3.begin(250000);
  myPacket.setStream(&Serial3);

}
void loop() {
  Position pos;
  pos.gx = 1.0f;   //末尾のfはfloat型であることを示す
  
  myPacket.send(pos.bin, 4);   //float データは4Byte


}
```
GAS + ブックマークレットでスプレッドシートからデフォルト名のフィルタ表示を一括削除する 

## 前置き（フィルタ表示とは）

スプレッドシートを複数人で共有していると、各々が自分用のフィルタ表示を作成することがあると思います。この機能は、同時編集している人に影響を与えずにフィルタをかけることができるので便利です。

![フィルタ表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46177/6bd501ca-6583-025d-8eaf-8c1e83f849d9.png)

## 困っていたこと

いつの間にか「フィルタ 1」、「フィルタ 2」、・・・という名前のフィルタ表示が大量に作られていることがあります。（自分も含めて）誰かが使い捨てのフィルタ表示を作成し、消し忘れてしまったのだと思います。

![使い捨てのフィルタ表示が大量に存在](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46177/36251eb2-20b2-cd15-cde7-17384f559783.png)

この状態、つまりスプレッドシートのフィルタ表示一覧を開いて「おぉ・・」となった状態で、速やかにデフォルト名のフィルタ表示を一括削除できると嬉しいです。

## 解決方針

ウェブアプリとしてデプロイした GAS と、それを呼び出すためのブックマークレットを作ることにしました。

## ブックマークレット

ブックマークレットの実装です。

```javascript
javascript:(function(){
    var url = "https://script.google.com/macros/s/[デプロイID]/exec";
    url += "?url=" + encodeURIComponent(window.location.href);
    window.location.href = url;
})()
```

スプレッドシートを開いていることを前提に、現在の URL をパラメータとして GAS に渡します。

## GAS の処理

GAS の実装です。

```javascript
// NOTE: "Google Sheets API サービス" を追加する必要があります.

function doGet(event) {
  // パラメータから処理対象の Sheet を特定する.
  const spreadsheetUrl = event.parameter.url
  const sheetId = spreadsheetUrl.match(/gid=(\d+)/)[1]
  const spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl)
  const sheet = spreadsheet.getSheets().find(_ => _.getSheetId() == sheetId)

  // デフォルト名のフィルタ表示を削除する.
  const filterViews = getDefaultNameFilterViews(spreadsheet, sheet)
  removeFilterViews(spreadsheet, filterViews)

  // 元のスプレッドシートに遷移させる HTML を返す.
  const html = Utilities.formatString("<script>window.top.location.href='%s'</script>", spreadsheetUrl)
  return HtmlService.createHtmlOutput(html)
}

// デフォルト名のフィルタ表示を取得する.
function getDefaultNameFilterViews(spreadsheet, sheet) {
  const request = { dataFilters: [], includeGridData: false }
  const response = Sheets.Spreadsheets.getByDataFilter(request, spreadsheet.getId())
  const foundSheet = response.sheets.find(_ => _.properties.sheetId == sheet.getSheetId())
  const filterViews = foundSheet.filterViews || []
  return filterViews.filter(_ => _.title.match(/フィルタ \d+/))
}

// フィルタ表示を削除する.
function removeFilterViews(spreadsheet, filterViews) {
  const requests = filterViews.map(_ => {
    return { deleteFilterView: { filterId: _.filterViewId } }
  })
  if (requests.length > 0) {
    Sheets.Spreadsheets.batchUpdate({ requests: requests }, spreadsheet.getId())
  }
}
```

GAS をウェブアプリとしてデプロイすると、`doGet()` 関数がエントリポイントとなります。

パラメータから処理対象のシートを特定し、そこに含まれるデフォルト名のフィルタ表示を削除し、最後に元のスプレッドシートに遷移させる HTML を返しています。
DynamoDBをモック化する

## 背景
ローカル環境でLambdaからDynamoDBへの処理をテストをしたかったので
motoを使ってDynamoDBをモックした。
忘れないように備忘録を残す

## 前提
python がインストール済み
pytest がインストール済み

## インストール
```
pip install moto
```

## 実装

受け取ったIDをKeyとして登録データを返却する関数を実装

```src/get.py

import boto3

dynamodb = boto3.resource('dynamodb',region_name='ap-northeast-1')
table = dynamodb.Table('messages')

def get_messages(id):
   return table.get_item(Key={'id': id})

```
###テストコード

* dynamodb_messages（）にモック化するDB情報を記述する
* モック化したいテスト関数の先頭に『@mock_dynamodb2』を記述する
* dynamodb_messages（）を実行する。
* モック化したDBへの書き込み、取得が可能になる

```python
import boto3
from moto import mock_dynamodb2
import importlib


@mock_dynamodb2
def dynamodb_messages():
    dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
    table = dynamodb.create_table(
        TableName='messages',
        KeySchema=[
            {
                'AttributeName': 'id',
                'KeyType': 'HASH'
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'id',
                'AttributeType': 'S'
            },
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 10,
            'WriteCapacityUnits': 10
        }
    )
    return table


@mock_dynamodb2
def test_get_messages():

    table = dynamodb_messages()
    item = {
        'id': '1',
        'message': 'hello',
    }
    table.put_item(Item=item)
    module = importlib.import_module(".get", ".src")
    res = module.get_messages(1)

    assert item == res.get("Item")

```

ローカル上でDBのテストが可能となる。
VMworld 2021 アップデートまとめ (VMware Cloud on AWS編)

VMworld 2021のアップデートについて調べることがあったのでメモ。

# 1. そもそもVMworldって？
VMware社の年次カンファレンスです。他にもいろんな会社(例えばApple社)も自社の大型イベントで新製品や新機能の発表しているかと思います。今年USでは10/5-7にオンラインで開催されました。日本でも同イベント(VMworld 2021 Japan)は11/25-26でライブ配信されます。

https://vmworld.jp/

# 2. そういえばVMware Cloud on AWSって？
オンプレとクラウドのそれぞれに強みを持つ両社が共同開発したクラウドサービスです。Amazon EC2ベアメタルインスタンス上にVMware仮想環境が構築されています。詳解は両社の公式サイトもどうぞ。

https://www.vmware.com/jp/products/vmc-on-aws.html

https://aws.amazon.com/jp/vmware/


# 3. VMworld 2021アップデートまとめ
今年もたくさんのアップデートがあり、クラウドまわりに加えてAppまわりにも注力されていた印象です。本記事ではVMware Cloud on AWS関連のアップデートについてまとめます。

### Availability in AWS Asia Pacific (Osaka)
大阪リージョンでのVMware Cloud on AWS提供がアナウンスされました！ (2021年10月末の時点から利用できるようになったようです。)今まで日本では東京リージョンだけだったので、よりカバレッジが広がりました。

### 2-Host i3en.metal clusters
今までVMware Cloud on AWSでは本番利用はi3.metal(選べるホストタイプ、より汎用向け)を除き3ホスト構成からでしたが、今後はi3en.metal(選べるホストタイプ、より大型ワークロード向け)も2ホスト構成が可能です。これによってi3.metalとi3en.metalの両方で最小2ホスト構成から本番利用できるようになります。さらにスモールスタートで利用しやすくなりますね。

### 1-1-1 Stretched Clusters
Streched Clusterといって以前からVMware Cloud on AWSではMulti-AZ (2つのAWS Availability Zoneにまたがる冗長構成)を構成できたのですが、構成ホスト数の最小4ホスト(各AZに2ホストずつ)となっていました。そこで今回のアップデートで最小2ホスト(各AZに1ホストずつ)から利用可能になりました。どんどん利用しやすくなりますね。

### Enhancements to VMware Cloud Disaster Recovery
以前からVMware Cloud on AWS向けの災害対策SaaSソリューションとして、VMware Cloud Disaster Recovery (よくVCDRと省略される)がありました。今まで最小RPOは4時間だったのですが、さらに強化されて最小RPOが30分となりました。
ちなみにVMware Site Recoveryという、こちらもVMware Cloud on AWS向けの災害対策SaaSソリューションがあり、そちらも今回のVMworld 2021で機能強化のアップデートがありました。

### ほかにもたくさん..!
上記で抜粋した以外にもVMworld 2021の前後でたくさんのアップデートがあり、例えばAppまわりで注目のTanzuや、強力なマイグレーションツールであるVMware HCX、セキリュティまわりではVMware NSX Advanced Firewallへのadd-on追加など、まだまだアップデートが盛り沢山です。

本文は英語ですがこちらVMware社の公式ブログにもVMware Cloud on AWSについて2021年10月時点の最新アップデートがまとまっています。またVMworld Japan 2021も上記リンクから参加登録(無料)できますので、ご興味あればぜひご参加してみてください。

> [VMware Cloud on AWS: What’s New in Oct 2021 (VMware Cloud Blog)](https://blogs.vmware.com/cloud/2021/10/05/vmware-cloud-on-aws-whats-new-in-oct-2021/)

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/b0a261e0-15f5-61cb-3a3b-a26783164dbd.png)


# 4. 関連記事

https://qiita.com/sanjushi/items/ba6426b202215f39ba22
Androidアプリ　kotolin学習のためソシャゲイベントログアプリを作る01　TOP画像の設定

kotolin学習用にAndroidアプリを作成してみようと思う。
某ソシャゲ某イベントの記録アプリ。
今回はTOP画面に画像を設定するところをやってみる。

プロジェクト名：AncientBattlefield
開発ツール　　：Android Studio - Arctic Fox | 2020.3.1

##１．画像格納場所
以下フォルダ配下に保存する。
・C:\Android\project\AncientBattlefield\app\src\main\res\drawable

保存したファイル名は以下
・top.png

##２．activity_main.xmlの編集
activity_main.xmlの格納先は以下画像の通り。
青枠になっている箇所を選択してコード表示にする。
赤枠の行を追加する。
![01_code.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255947/760b092c-ba0b-7ba1-c4c9-298c61091621.jpeg)


ファイル選択後、表示がデザインとなっているので、コードに変更。

##３．設定された画面
![02_top_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255947/2ced7725-7d92-70ad-98ad-a6e7ffba518f.jpeg)
実行したところ、画面は設定されていた。
ただタイトルバーが入っている。これを消したい。

##４．タイトルバーの削除
調べたところ、以下ファイルにコードを追加することで削除できるとのこと。
修正ファイル：thems.xml

![03_titlebar_del.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255947/b2f80b35-825b-f254-ef19-99f5ad7585bd.jpeg)

```
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
```

##５．再度画面の確認
無事タイトルバー削除。
今回はここまで。
![04_top_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255947/5fcb41d0-aff0-0771-cbf5-58d35b0ad456.jpeg)
リアクティブWebアクション

アプリの開発では、サーバー上で実行するロジックと、スマートフォンやタブレットなどのクライアン
トデバイス上で実行するロジックを作成します。
サーバーアクションとクライアントアクションのロジックフローは、Service Studioでの表示が異なり
ます。キャンバスの左上に、クラウドまたはタブレットとスマートフォンのどちらかのインジケータア
イコンが表示され、現在のアクションがサーバーとモバイルデバイスのどちらで実行されるのかを示し
ます。
同じツールのツールボックスアイコンも、サーバーとクライアントとでは少し異なります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/8a6bce44-f3fe-3591-81e1-4d30e41fce09.png)
下記のアクションを作成できます。
• データアクション
• クライアントアクション
• サーバーアクション

■データアクション
たとえば、ホームバンキングのダッシュボードなどの一部の画面では、複雑な情報をデータベースやそ
の他の外部システムから取得することが必要な場合があります。モバイルアプリとリアクティブWebア
プリでは、これをデータアクションで行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/9ae26f9a-0580-0b1b-cde7-033932feb5df.png)
データアクションは、サーバー上で実行されます。データアクションを作成し、複雑なデータをデータ
ベースから取得することができます。これは、サーバー上でAggregateを1回使用しただけでは実現で
きません。また、たとえば、REST APIを利用して外部システムからデータを取り出すことも可能で
す。
データアクションは、クライアントおよびサーバーのAggregateと同時に実行され、各画面のロード後
にデータを取り出します。
ブロックにデータアクションを作成することもできます。

■クライアントアクション
クライアントアクションは、ユーザーデバイス上でロジックを実行します。画面とクライアントロジッ
クという2つの異なるスコープでクライアントアクションを作成できます。
画面のスコープ: 画面によるユーザーインタラクションでロジックを実行します。たとえば、連絡先を
更新する画面では、ユーザーによる［Save］ボタンのクリックに反応して連絡先を更新する更新ロジ
ックを実行するクライアントアクションを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/72461bb2-4564-c315-11f2-bc0156d39d3d.png)

また、ブロックにクライアントアクションを作成することもできます。
クライアントロジック: 複数の画面で再利用できるようにロジックをカプセル化します。たとえば、ア
プリの複数の画面に適用する必要がある検証ルールの場合、クライアントロジックに対して一般に適用
されるクライアントアクションを作成し、画面のクライアントアクションで利用することができます。

クライアントアクションを関数として設定して、クライアント側ロジックのExpressionの中で直接使用
できます。


■サーバーアクション
アプリでサーバーアクションを作成し、ロジックをカプセル化して他のサーバーアクション、データア
クション、クライアントアクションなどで再利用することもできます。サーバーアクションは、サーバ
ー上のロジックを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/e56cdd64-18c1-8422-12af-e29483539e69.png)

サーバーアクションを関数として設定して、サーバー側ロジックのExpressionの中で直接使用できま
す。
【3分間ネットワーキング】※OSIモデル※レイヤ1について

3分間ネットワーキング

第9回
レイヤ1の物理層におけるLANで使われるメディアの話。
3種類のネットワーキングメディアの話。
↪銅線2種類と光ファイバ

銅線2種類は同軸ケーブルとツイストケーブル
光ファイバは光ファイバケーブル


第10回　ネットワーキングデバイス
リピータとハブの話。

リピータの役割⇒信号を増幅や整形させる。（信号増幅器）
ハブ⇒別名マルチポートリピータ
OSIモデル

OSIモデル

通信を制御する機器がレイヤごとに分かれている
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
レイヤ1　物理層
機器：リピート・ハブ
役割：増幅・配分

レイヤ2
データリンク層
機器：ブリッジ・スイッチ
役割：とあるルールにのっとってデータをを通す・通さないという制御

レイヤ3
ネットワーク層
機器：ルーター
役割：宛先までのルートを決定する
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

第８回レイヤ１ 信号と回線

ディジタル信号かアナログ信号化は通信回線に依存する
モデムの役割⇒ディジタル信号をアナログ信号に変換してくれる
ディジタル回線はISDNが有名

参照URL:http://www5e.biglobe.ne.jp/aji/3min/index.html
VMware vSphereお勉強まとめ (Network編)

# 1. はじめに
VMware vSphereについて勉強するにあたり、参考にさせていただいたリンクまとめです。
大昔に作ったメモが出てきたのでこれから勉強される方向けにシェアします。

エンタープライズ向けVMware仮想化製品であるVMware vSphereを学ぼう！と思ったときに、まずつまずくのが仮想ネットワークのところかと思います。

vSphere標準スイッチ(単に標準スイッチと呼んだり、vSSの略称だったり)から始まり、vSphere Distributed Switch(分散仮想スイッチ、もしくはVDSの略称で呼ばれたり)、もうちょっと勉強すると物理NIC、仮想NIC、あげくにVMKernelあたりで???となるのではないでしょうか。私も同じ道を辿ったのでよくわかります。

今回VMware仮想化製品(VMware vSphere)を勉強始めた方向けに、特にネットワーク関連に絞って、私が非常に参考にさせていただいた記事をご紹介します。

どういう風に勉強するか分からないという方、本を買う実機を触るのも大変結構なのですが、まずは無償で試せるVMware社の仮想デモ環境([VMwareハンズオンラボ-VMware HoL](https://www.vmware.com/content/microsites/learn/ja/jphol.html))はいかがでしょうか。別記事でもご紹介します。

https://qiita.com/sanjushi/items/ba6426b202215f39ba22

# 2. 記事紹介
##### [新卒 SE 社員が贈る　vSphere のキソ！第2回 ～仮想環境におけるネットワークとストレージ～](https://blogs.vmware.com/vmware-japan/2014/08/vsphere_kiso02.html)
今でも愛読しているVMware Japan社新卒社員の方々が書いたブログ記事シリーズの一編です。

下図はブログ記事から引用しています。こちらの図だけでもなんとなく概要が理解できそうな気がしてしまうのですが、まだまだ奥が深いので一読必須です。
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/c66f160a-f25b-d18d-20b3-87a95592893b.png)


##### [仮想スイッチのお作法～標準スイッチから分散スイッチへの道～](https://blogs.vmware.com/vmware-japan/2017/02/vds-2.html)
こちらもVMware Japan Blogからのご紹介です。
シンプル構成なvSphere標準スイッチが掴めてきたあたりで、その発展系が気になってくると思うのでそのタイミングで読むと良きかと思います。こちらも非常に分かりやすいです。
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/5b8100ce-f214-929a-7b4c-c908f829d189.png)




# 3. おわりに

まだまだ私が参考にさせていただいた記事や資料は膨大にあるのですが、今回は私が初心者だったころ特に勉強させていただいた（思い出深い）記事だけをご紹介させていただきました。少しでも参考になれば幸いです。

> 最後にこちらVMware vSphereの公式ドキュメントです。呼称や略称で混乱しかけたらぜひ原典もご参照ください。
[VMware vSphere のドキュメント (VMware Docs)](https://docs.vmware.com/jp/VMware-vSphere/index.html)

# 4. 関連記事

https://qiita.com/sanjushi/items/ba6426b202215f39ba22

https://qiita.com/sanjushi003/items/3ce3d14b0ab1d051476b
メモ〜cleaned_dataと外部キー

今回の結論
-

`ModelForm`クラスが外部キー由来のフィールドを持っている場合、`cleaned_data`にも`primary-key`ではなく`インスタンスそのもの`が入る。

具体例
-

```python:models.py
class Book(models.Model):
  title = models.CharField(max_length=30)
  author = models.Foreign_key(Author, on_delete=models.CASCADE)
```
```python:forms.py
class BookForm(ModelForm):
  class Meta:
    fields = "__all__"

  def clean_author(self):
    author = self.cleaned_data.get("author") # ここにはインスタンスそのものが入っている
    if author.pk == 1:
      raise forms.ValidationError("テストユーザーを著者として登録しないでください")
    return author
````
SourceTreeでワンクリックで変更差分・未追跡ファイルを無くして綺麗な状態にする


SourceTreeの作業ツリーにある変更差分と未追跡ファイルを消したい場合、
**変更差分 → 「コミットまで戻す...」**
**未追跡ファイル → 「削除」**
を実行する必要があり、ファイル数が多くなってきて、変更差分と未追跡ファイルが入り乱れていると、選択するのが結構面倒くさいです。

**カスタムアクション**を設定すれば、**ワンクリックで作業ツリーを綺麗**にできます。
![img_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/ca1a5459-fca0-36e5-2fc4-3e95b39c8ead.png)

## 1.カスタムアクションのファイルを用意

↓ Githubにカスタムアクションに設定するファイルを上げているのでこちらをクローンするかダウンロードして、任意のフォルダに保存してください。

https://github.com/onederappli/SourceTreeCustomActions

## 2.SourceTreeでカスタムアクションの設定

■ Macの場合
メニューから「SourceTree > 環境設定 > カスタムアクション」を選択
■ Windowsの場合
メニューから「ツール > オプション > カスタム操作」を選択
![スクリーンショット 2021-11-04 22.24.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/91a2af4f-bbf2-de03-5b2d-75704c3f045f.png)

「追加」を選択し、
メニューキャプションに「**クリア**」と入力（※これがカスタムアクション名になります）
実行するスクリプトに(1)で取得したファイルを指定。
■ Macの場合
「**SourceTreeCustomActions/Mac/clean_checkout.sh**」
■ Windowsの場合
「**SourceTreeCustomActions/Windows/clean_checkout.bat**」
![スクリーンショット 2021-11-04 22.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/a1efbd31-ae0b-e905-868d-9201e98a5f28.png)

※ Windows の場合は、**パラメータ**に「**$REPO**」と入力してください。
![windows.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/f84044ec-bb5a-ee83-ab6a-dcb598840237.jpeg)
OKを選択してカスタムアクションの設定は完了。

## 3.Macの場合は実行権限の追加　（Windowsの場合は不要）
Macの場合、実行権限を追加しないと、カスタムアクションの実行時に「launch path not accessible」というエラーが発生してしまうので、ターミナルから以下のコマンドを実行してください。

```
$ cd "保存したパス"/SourceTreeCustomActions
$ chmod -R +x Mac
```


## 4.カスタムアクションを実行

作業ツリーに差分や未追跡ファイルがある状態で、右クリックし
「**カスタムアクション > リポジトリのアクション > クリア**」
を選択すると、作業ツリーが綺麗な状態になる。
![img_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/c1318d77-63d1-6bc2-dd39-3b2a109fc11f.png)

## 補足説明

カスタムアクション実行時、実際には下記のコマンドが実行されています。
カスタムアクションに指定したファイルに記載されているので、ここを適宜書き換えれば挙動を変更することができます。

```
git clean -df
git checkout .
```
Googleの検索結果をURLでフィルターするChrome(またはEdge)の拡張機能を作った

広告収入が主目的のページとか対話形式の記事とか、いちいち読んでられない。

この拡張機能は、下記のソースに検索結果より削除したい項目のURLを書き込んで使う。

```javascript:content_script.js
'use strict';
(function () {

function main() {
	//URLの比較は前方一致で行う
	const urlBlackList = Object.freeze([
		'https://techacademy.jp/',
		'https://sasasorato.com/',
	]);

	const rso = document.querySelector('div#rso');
	if(rso == null) {
		return;
	}

	for(const child of rso.children) {
		if ( child.tagName === 'DIV' ) {
			const anchors = child.getElementsByTagName('A');
			for (const a of anchors) {
				if (a.href != null && urlBlackList.some(url => a.href.startsWith(url))) {
					if(child.classList.contains('g') || child.querySelector(':scope > div.g')) {
						//とりあえず透明にした。非表示にしたければ child.style.display = 'none'; を有効にする
						child.style.opacity = '0.25';
						//child.style.display = 'none';
						continue;
					}
				}
			}
		}
	}
}

main();
})();
```

```json:manifest.json
{
	"name": "Google Search Filter",
	"description": "Google Search Filter",
	"version": "1.0",
	"manifest_version": 3,
	"content_scripts": [
		{
			"matches": [
				"https://www.google.co.jp/search?*",
				"https://www.google.com/search?*"
			],
			"js": ["content_script.js"]
		}
	]
}
```

<b>インストール方法</b>

<b>1. ファイルの保存</b>
上のふたつのコードをコピーして自分のローカル端末に保存する。
ファイル名は manifest.json, content_script.js にして、ファイルのエンコードはUTF-8で保存する（BOM付き、なし、どちらも可）。エンコードは、だいたいのどのエディタも「名前を付けて保存」で指定できる。
ふたつのファイルは同じフォルダに格納する。フォルダ名は任意でOK。

<b>2. ブラウザにインストールする</b>

Chromeなら
(1) 画面右上の隅のジグソーパズルのピースをクリックして「拡張機能の管理」を開く。
 　 （または、右上の隅の ［  ⁝  ］を押し「その他のツール」→「拡張機能」を開く）
(2) 拡張機能の設定画面が開かれたら、右上の「デベロッパーモード」をオンにする。
(3)「パッケージ化されていない拡張機能を読み込む」をクリックする。
(4) スクリプトが格納されたフォルダーを選択する。

Microsoft Edgeなら
(1) 画面右上の隅の［･･･］を押し「拡張機能」を開く。
(2) 拡張機能の設定画面が開かれたら、左下の「開発者モード」をオンにする。
(3)「展開して読み込み」をクリックする。
(4) スクリプトが格納されたフォルダーを選択する。

Firefoxなら
下記の手順で一時的にインストールできる。
パッケージ化していないので永続的なインストールは不可。
(1) 画面右上の隅の［≡］を押し「アドオンとテーマ」を開く。
(2) アドオンマネージャ―が開かれたら、歯車ボタンを押し「アドオンをデバッグ」をクリックする。
(3)「一時的なアドオンを読み込む...」をクリックする。
(4) ファイルダイアログで manifest.json を選択する。
※「Unsupported manifest version: 3」のエラーが出るなら、上の manifest.json の "manifest_version" を 2 に書き換える。
Git　タグの使い方

### コミットを参照しやすくするためにわかりやすい名前をつけるのがタグ。よくリリースポイントにつける。

```
// タグの一覧を表示 
git tag
``` 
↓

```
// タグのデータを表示 
git show タグ名
``` 

### タグには２種類あり、注釈付き版のタグと軽量版のタグがある
### 注釈付きのタグにはタグ名にプラスでメッセージを追加できる
#### リモートにプッシュする場合は別途指定してあげる必要がある。プッシュの時に勝手についていかない
ソースツリーの場合は以下のキャプチャのプッシュするタグにチェックをするとリモートにプッシュされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756524/e0f68c3e-0cb8-3929-9784-48dce305d6be.png)
soucetreeでもコマンドの履歴が見れるみたい

macであれば「control + command + W」でコミット履歴をだすことができる
windowsは調査中
この[サイト](https://alliance7.blogspot.com/2019/03/sourcetree.html)がわかりやすい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756524/0cd2957b-ce59-b911-d2a4-816ac05dd88f.png)
C#：四則演算

# 四則演算記号
- 足し算
    - A + B
- 引き算
    - A - B
- 掛け算
    - A * B
- 割り算
    - A / B
- あまりの計算
    - A % B
        
## 変数に代入して計算する
- int x = 1; int y = 2; int z = x + y;

- 文字列の計算
    - string s = "野球" string h = "部" string g = s + h; //自民党
    - 文字列 + 数字の場合は全て文字列になる
- 代入演算
    - A += B; → A = A + B;
- インクリメント、デクリメント
    - a++, a--, ++a, --a
    - 変数の前か後につけて変数の値を1増やす、1減らすといった働きをする

```c#:四則演算.cs

//[四則演算]変数を使用して計算
int a = 10;
int b = 3;

//足し算
a + b; // 13
//引き算
a - b; // 7
//掛け算
a * b; // 30
//割り算
a / b; // 3
//あまりの計算
a % b; // 1

//[テキストの計算]
Debug.Log("答え:" + a); // 答え:10 10も文字列として考える


//[代入演算子]
a *= b; //30
a *= 2; //20
string s = "Hello";

//インクリメント、デクリメント
a++; //9
a--; //9
++a; 
--a;

```
djangoの汎用ビューについてまとめる〜UpdateView編

今回のお題
-
今回はdjangoの汎用ビューの一つである`UpdateView`についてとりあげます。

最近クラスベースビューを使い始めたのですが、その過程で今回のテーマであるUpdateViewに遭遇したので自分用に残しておきます。

なお、本記事ではクラスベースビューそのものについての解説は行いませんのでご了承ください。

目次
-
- 汎用ビューとは
- UpdateViewの設定項目
- 実装例
- まとめ

汎用ビューとは
-
まずは汎用ビューそのものの定義からしておきます。

クラスベースビューでは一般的に`TemplateView`クラスを継承させて、新たなビュークラスを作成します。

```python:TemplateViewクラスの継承例
class HomeView(TemplateView):
  template_name = "home.html"
```
しかしTemplateViewクラスでは設定できる属性値やメソッドが限られており、そのために以下のような問題を抱えています。

- 新規登録を行う際に、成功時と失敗時で遷移先を切り替えることが難しい。
- フォームとDBの間での情報の受け渡しを全て記述しているとコード量が膨大になってしまう。

これらの問題を解消するために、djangoでは`汎用ビュー`と呼ばれるTemplateViewのサブクラスが用意されています。

汎用ビューは独自の属性値やメソッドを持っており、それらを設定することによって上記の問題を解決することができるようになっています。

今回取り上げるUpdateViewもその一つであり、必要な値を設定することでレコード更新に必要な項目、すなわち成功時の遷移先urlや利用するフォームなどを簡単に指定することができるようになっています。

UpdateViewの設定項目
-
では、UpdateViewに設定すべき項目について見ていきます。

<dl>
<dt>template_name</dt>
<dd>遷移先のテンプレートを指定するための変数。</dd>
<dd>全てのTemplateViewクラスで設定可能。</dd>
<dt>model</dt>
<dd>レコード更新をかけるモデルを指定するための変数。</dd>
<dd>ここで指定したモデルに関しては、モデル名をスネークケースに変換したものが自動的にcontextに追加される(例：Bookモデルであればcontext["book"]に格納される)。</dd>
<dd>後述のform_classにてModelFormクラスを指定している場合であっても、この変数の設定は必須。</dd>
<dt>form_class</dt>
<dd>テンプレートに表示するフォームクラスを指定するための変数。</dd>
<dd>ここで指定したフォームクラスについても、contextにformというキーで格納される。</dd>
<dd>先述のmodel属性とこのform_class属性に関しては大元のTemplateViewには設定されていないので、それらを設定したければ汎用テンプレートを使う必要がある。<dd>
<dt>fileds</dt>
<dd>フォームに表示するフィールド名を指定するための属性値。</dd>
<dd>上記のform_classとどちらか一方を指定（両方指定するとエラーになる)。</dd>
<dt>get_success_url</dt>
<dd>レコードの更新に成功した場合の遷移先を指定するための関数。</dd>
<dd>こちらも大元のTemplateViewクラスには存在しない。</dd></dl>

これらを指定すればいつもより簡単にレコード更新が実装できそうですね。

実装例
-

では、上記の項目を使ってレコード更新機能を実装していきます。

```python:models.py
class Book(models.Model):
  title = models.CharField(max_length=30)
  author = mdels.CharField(max_length=30)
```

```python:forms.py
class BookForm(ModelForm):
  class Meta:
    fields = "__all__"
```

```python:views.py
from django.views.generic.edit import UpdateView

class BookUpdateView(UpdateView):
  template_name = "book/update.html"
  model = Book
  form = BookUpdateForm

  def get_success_url(self):
    return reverse("book:show", kwargs={"pk":self.object.pk})
```
```urls.py
urlpatterns = [
  path("update/<int:pk>", views.BookUpdateView.as_view(), name="update"),
]
```

これで実装完了です。

ちなみに、以下の部分でパラメータ名を`pk`以外にするとエラーになります。

```python:views.py
  def get_success_url(self):
    return reverse("book:show", kwargs={"pk":self.object.pk})
```
```python:urls.py
  path("update/<int:pk>",
```

まとめ
-
以上でUpdateViewを用いたレコード更新機能が実装できました。

まとめとしては、

- UpdateViewには`model`や`get_success_url`などの独自の属性・関数が定義されているので、それらを利用すると実装が楽になる。
- パラメータの受け渡しは必ず`pk`で行う。

というところですね。

汎用ビューには他にも新規登録や詳細表示などに特化したものもあるので、そちらについてもいずれまとめようと思います。
【Mybatis】TypeHandlerでValueObjectへ値をマッピングできるようにしてみる

タイトルの通り、TypeHandlerでValueObjectへマッピングできるようにしてみたので記事にしてみました。

## Motivation
XMLにこんな感じでどのカラムをマッピングするか書いてたんですが、今後ValueObjectが増えるたびに定義しなきゃいけないのか...とツラミを感じていました。

↓こんな感じにすれば定義の共通化自体は可能なのですが、カラムの名前を都度気にしなきゃいけないのもバグりポイントなのでどうにかしたいなって思ってました。(調べればXMLの設定でもこの辺いい感じに解決できるのかもしれませんけど...)

```xml
  <resultMap id="ValueObject" type="org.test.hoge.ValueObject">
    <constructor>
      <idArg javaType="java.lang.String" column="value" />
    </constructor>
  </resultMap>
```
```xml
    <association property="value" resultMap="org.test.hoge.Dao.ValueObject" />
```

## TypeHandlerでマッピングできるようにする
型がTypeHandlerでサポートされていれば、StringやIntなどのプリミティブな型同様何も気にせずselectできます。
リフレクション使ってるので嫌な人は見ない方がいいと思います。
あとkotlinで書いてます。（javaで書くとどうなるかも未検証... :bow: ）

まずはValueObjectのabstractなclassを作ります。（equalsとhashCodeは適当）

```kotlin
abstract class ValueObject<E>(open val value: E) {
    override fun equals(other: Any?): Boolean {
        return value == other
    }

    override fun hashCode(): Int {
        return value?.hashCode() ?: 0
    }
}
```

あとはtypehandlerを定義します。ValueObjectを継承したクラスのコンストラクタにStringなvalue一つだけのコンストラクタを含む前提です。

```kotlin
@MappedTypes(
    SubVO::class,
)
class StringValueObjectTypeHandler<E : ValueObject<String>>(val type: Class<E>) : BaseTypeHandler<E>() {
    override fun setNonNullParameter(ps: PreparedStatement?, i: Int, parameter: E, jdbcType: JdbcType?) {
        ps?.setString(i, parameter.value)
    }

    override fun getNullableResult(rs: ResultSet?, columnName: String?): E? {
        return rs?.getString(columnName)?.let { valueObject(it) }
    }

    override fun getNullableResult(rs: ResultSet?, columnIndex: Int): E? {
        return rs?.getString(columnIndex)?.let { valueObject(it) }
    }

    override fun getNullableResult(cs: CallableStatement?, columnIndex: Int): E? {
        return cs?.getString(columnIndex)?.let { valueObject(it) }
    }

    private fun valueObject(value: String): E {
        val c = type.kotlin.constructors.first {
            it.parameters.size == 1 && it.parameters.first().type == typeOf<String>()
        }
        return c.call(value)
    }
}
```

valueの型に応じてTypeHandlerを複数作るか、 `it.parameters.first().type == typeOf<String>()` の比較でジェネリクスを使えばいける気もする（試してない）
git プルにはマージ型とリベース型があるみたい

## マージ型
マージコミットが残るのでマージした記録を残したいときに使う

## リベース型
マージコミットが残らないのでgithubの情報を取得したいときにだけ使う
ただ単にmasterの内容を取得する時にはこれでOK！
ソースツリーではプルする時に以下の「マージではなくリベースする」にチェックをつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756524/78456d44-a6fe-736f-e47e-914132ccc2c9.png)
【基礎】アプリケーション層って何？（ざっくり）　TCP/IP

<h2>初めに</h2>
DMMWEBCAMPのコミュニティ（Shuffle)で行われている
「テーマを決めて、それについて調べ、各々で調べた内容」を発表するという勉強会に参加しました。
その際に調べた内容を以下の通りまとめました。
調べてまとめる時間は30分~40分程度なので、ざっくりとした内容になっています:fist:


<h2>アプリケーション層とは　"ユーザーが直接触れる層"</h2>

「実際のサービスをユーザーに提供する層」
「ユーザーが直接触れる層」です。

実際のデータ通信は下の階層に任せ、データの内容を見て仕事をします。

![スクリーンショット 2021-11-06 9.00.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/0de51f73-6e27-08ca-288a-04e934d4c753.png)

<h3>WEBページを表示する際のアプリケーション層の働き</h3>

リクエストしたURLと表示すべきWebページのデータをやり取りします。

<img width="400" alt="スクリーンショット 2021-11-06 9.13.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/94456aa5-7ff3-4722-33d7-d38d7568b8a9.png">
```見たいWebページのURLを送ったり、```
```WebページのHTMLファイルを送り返したり、```
```届いたデータを解釈してWebページを表示したり```します。
Webページ表示の場合には、WebプラウザとWebサーバーがアプリケーション層に当たります。

<h2>代表的なプロトコル</h2>


![スクリーンショット 2021-11-06 9.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/f3b15abe-9643-a22b-0216-f3de425cd232.png)

<h4>以下もアプリケーション層のプロトコル</h4>
以下のようにユーザーが直接操作しないようなものも
アプリケーション層のプロトコルです。
インターネットやLANを円滑に動かすためにバックグラウンドで働いてくれています。

![スクリーンショット 2021-11-06 9.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/a6b25d42-d486-5ee4-6871-a38dac097dde.png)
C# 黒い画面に文字を出す方法

## 対象者
この記事は下記のような人を対象にしています。

- 黒い文字だけの画面[^1]に文字を出したい人
- プログラミング初心者の人

##実行環境
.NET Framework 4.8で実行しています。

## 結論
文章の最後に改行したい場合は```Console.WriteLine("");```を、
改行なしの場合は```Console.Write("");```を使いましょう！

### 詳細
今回出てくる「Consoleクラス」というのをざっくり説明すると、
黒い画面[^1]に、文字を出したり、文字を入力させたりと、
することができるクラスです。

##ソースコード
```Program.cs
using System;

namespace ConsoleSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("WriteLineのテストです");
            Console.Write("Writeのテストです");
            Console.Write("Writeでは、最後に改行されません。");
        }
    }
}
```

###実行結果
```
WriteLineのテストです
WriteのテストですWriteでは、最後に改行されません。
```

---
## おわりに
今回は、コンソール画面に文字を出す方法についてまとめました。
よく使うメソッドなので、覚えておきましょう。

##参照元
Consoleクラス
https://docs.microsoft.com/ja-jp/dotnet/api/system.console?view=net-5.0

Console.WriteLine()
https://docs.microsoft.com/ja-jp/dotnet/api/system.console.writeline?view=net-5.0

Console.Write()
https://docs.microsoft.com/ja-jp/dotnet/api/system.console.write?view=net-5.0
[^1]: 本記事では、コマンドプロンプトのような画面のことを指します。
git リベースとは

変更を統合する際に、履歴をきれいに統合するためにつかうのがリベース
他のブランチをマージし、履歴まで整える事ができる

```
git rebase <ブランチ名>
```

### 気をつけること
githubにプッシュしたコミットをリベースするのはNG
→プッシュできなくなる

### マージとの使い分け
作業履歴を残したい場合はマージを使う
履歴をきれいにしたい場合はリベースを使う

- プッシュしていないローカルの変更にはリベースを使う
- プッシュした変更はマージを使う
- コンフリクトが起きそうな場合はマージを使う→リベースでは複数コミットでコンフリクトが発生する可能性があるから
コンテナイメージを使ったLambdaのローカル検証用ツールを作った



:::note info
この記事は、AWS Lambda と Serverless Advent Calendar 2021 15日目の投稿です。
:::

https://qiita.com/advent-calendar/2021/lambda



# 記事の要約

1. Lambdaではコンテナイメージを利用した処理実行ができる。
2. Lambdaにデプロイする前にローカルでも検証できる。
3. 2.をサクッと出来るようにラップしたツールを簡単につくった。
4. 使ってみてね！


# 経緯

Lambdaではコンテナイメージを利用して、任意のコンテナ環境での処理実行を行うことができます。
（今回ここの詳細な実装方法は本質でないので割愛します。）

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

一度使用する機会があり構築してみたのですが、実装したコンテナイメージをローカルで検証する方法が分からず彷徨っていると、[公式](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images-test.html
)で方法が見つかりました。
が、dockerを立ち上げて、REST投げて、とちょっとめんどくさいなと思ったので、
一連の流れをラップして簡単にテストできるようにしたいと思い、ツールを作ってみました。


# 作ったもの

作ったものはこちらになります。

https://github.com/theMistletoe/wlapper

https://www.npmjs.com/package/wlapper


### 使用方法

[example](https://github.com/theMistletoe/wlapper/tree/main/example) にまとめてあります。

ざっくりまとめると、
Lambdaで使いたいコンテナイメージをbuildして、コマンドに渡してあげるだけです。
インプットするeventデータなども指定することができます。

```shell
wlapper (ビルドしたDockerイメージ) -d '{"body": "Hello world!"}
```

npmにも公開しているので、インストールすることなく使えます。



# まとめ

初めてツールっぽいOSSをやってみました！
今回[oclif](https://oclif.io/)というNode.jsで動くコマンドラインのフレームワークを初めて使って作ってみましたが、CLIツールの実装からパッケージ公開まで、エコシステムが揃っていて、比較的簡単に進めることができました！
日々開発体験、ひいては世界が良くなっていくのを感じます！
aravisを使ってみる (その1) 

# はじめに


産業用カメラをubuntuで動作させたいと思い調べた所,aravisというライブラリでそれができることがわかりました。今回はその使い方を記載します。


https://github.com/AravisProject/aravis

# 使ってみる
## 環境

以下の環境で検証しました。

https://qiita.com/hoshianaaa/items/632e0eb9ddacb8245e66


## インストール方法

※READMEに記載されている手順です

```
# 依存ライブラリのインストール
sudo apt install libxml2-dev libglib2.0-dev cmake libusb-1.0-0-dev gobject-introspection                  libgtk-3-dev gtk-doc-tools  xsltproc libgstreamer1.0-dev  libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev  libgirepository1.0-dev

# 最新版のリリース(2021/11/6現在)をダウンロード
wget https://github.com/AravisProject/aravis/releases/download/0.8.19/aravis-0.8.19.tar.xz

#解凍
tar -xf aravis-0.8.19.tar.xz

#ビルド

sudo apt install meson

cd aravis-0.8.19/
meson build
cd build
ninja
ninja install
```
## 使う

ビューアーを起動してみます。

```
cd ~/aravis-0.8.19/build/viewer
./arv-viewer-0.8
```

起動すると写真のようなGUIが表示されました。

![Screenshot from 2021-11-06 11-30-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/72c03029-2fff-b830-0cd7-cd6e471913e4.png)

(Vendor/Model/Serial) = (Aravis/Fake/1)のカメラを選択肢再生ボタンを押してみます。

すると以下のようなテスト映像が確認できました。

![aravis_fake_cam2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/45a1c8df-7300-5f39-f729-da5856f36380.gif)





# 参考

- aravisの内部を解析している

https://decafish.blog.ss-blog.jp/2019-06-15

# 次回

次回は,aravis内のツールなどのまとめを紹介します。

https://qiita.com/hoshianaaa/items/26247d84f6b5cd87160e
エレキ素人が何か考える（その３：オシロスコープ）

# シロートがオシロスコープを使う
マイコンから出力される正弦波と矩形波をオシロスコープで観測。

## オシロスコープ
Amazonで購入した安価な[オシロスコープ](https://www.amazon.co.jp/gp/product/B08L3JLV3Z/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)（購入時6999円、執筆時点で売り切れ、入荷待ち）を使う。

## マイコン
正弦波を作るため、DAコンバーターを持つM5Stackを利用した。

## 正弦波（Sin wave）
M5StackでDAコンバーターを使う[サンプルコード](https://www.jianshu.com/p/32472eaeedd5)を利用した。ESP32でのDAコンバーターの利用方法詳細は、[Espressifの本家サイト](https://docs.espressif.com/projects/esp-idf/en/v4.2-beta1/esp32/api-reference/peripherals/dac.html)に記載がある。小生の環境では、ArduinoフレームワークではこれらAPI群を使ったコードを利用できず、ESP-IDFフレームワークをPlatformIO環境下で利用しBuild。

### ソースコード
```c++
#include "driver/dac.h"

void app_main() {
    dac_cw_config_t config;
    config.en_ch = DAC_CHANNEL_1;
    config.freq = 2000; // Set frequency of cosine wave generator output. Range: 130(130Hz) ~ 55000(100KHz).
    config.scale = DAC_CW_SCALE_8;
    config.phase = DAC_CW_PHASE_0;
    config.offset = 1;

    dac_cw_generator_config(&config);
    dac_cw_generator_enable();

    dac_output_enable(DAC_CHANNEL_1);    
}
```

[本家サイト](https://docs.espressif.com/projects/esp-idf/en/v4.2-beta1/esp32/api-reference/peripherals/dac.html)によると、130Hzから100KHz(?)の周波数を設定できるようだ。また、DAC_CHANNEL_1は、GPIO25に相当する。

### 環境ファイル（platformio.ini）
```c++:platformio.ini
[env:m5stack-core2]
platform = espressif32
board = m5stack-core2
framework = espidf

```

### 結果
#### 2kHz
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f609e6c6-f67c-6700-a469-9a975d9ede33.png", width=70%>
「1.92kHz」と表示されている。

#### 50kHz
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c00eda36-6185-17f0-0c21-1fda13be695b.png", width=70%>
「50.2kHz」と表示。以降、同様。

何故か低い周波数（例：200Hz）は、正しく表示されなかった。

## 矩形波（PWM）
こちらは、Arduinoフレームワークの利用。M5Stack(ESP32)には、analogWrite()が存在しない。ESP32をArduinoフレームワークで利用する際の[PWM用のAPI](https://garretlab.web.fc2.com/arduino/esp32/reference/cores/led_pwm/)が別途用意されているのでこれを利用。

### ソースコード
```c++
int PIN = 2;
int PWMCH = 0;
 
void setup() { 
  pinMode(PIN, OUTPUT);
  ledcSetup(PWMCH, 2000000, 8); // Hz, 8Bit
  ledcAttachPin(PIN, PWMCH);
  ledcWrite(PWMCH, 128);  //  50%
}
 
void loop() {
}

```

ledcSetup()で周波数、ledcWrite()でデューティ比（例：128 -> 128/256: 50%）を指定する。

### 結果
#### 20Hz, 25%
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/95fa6297-e63c-e1fd-f1c1-6b798024daf2.png", width=70%>

#### 10KHz, 50%
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/06d77cc7-6822-3b68-9708-fa31555d3f7f.png", width=70%>

#### 200KHz, 75%
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c9e38fc0-94a0-103c-458e-fd2367b5d1ec.png", width=70%>

あまり高い周波数では正しく表示されず（オシロスコープの能力不足）。

まずはOK。
API Gatewayにカスタムドメインを付与したときのメモ


APIGatewayのAPIに独自ドメインでアクセスできるようにする。
・Value Doomeinでドメインを購入
・そのドメインをAWS Roote53設定
・API Gatewayのカスタムドメインを設定

####①value Domainで、ドメイン「#domain#」を購入する。

####②Roote53で、ホストゾーンを作成する。
[ドメイン名] #domain#
[タイプ    ] パブリックホストゾーン
→NSとSOAレコードが自動作成されている。
※NSレコード・・・どのDNSサーバーがそのドメインの権威サーバーであるか（すなわち、どのサーバーに実際のDNSレコードがあるか）を示す。 

####③取得したドメインのNameサーバーとして、Roote53を登録する。
→value Domainの管理画面で、取得したドメイン「#domain#」のNameサーバーの設定を、②のNSレコードの値に変更する。
これをすることで、Roote 53に登録するレコードの内容がインターネットに反映されるようになる。

####④AWS ACMで証明書を取得する。
→https通信ができるように証明書を取得

[タイプ　] パブリック証明書をリクエスト
[ドメイン] #サブドメイン#.#domain#
[検証方法] DNS検証
※サブドメインは自分で決める。api作るなら、api.#domein#などでもいい。
→作成後に、CNAMEの情報が表示される。
　これを、Route53のホストゾーン②の新規レコードに設定する。（DNS検証用と思われる）
　※この画面にRoote53にレコードを作成するみたいなボタンがあるので、こちらでも可能。

####⑤API Gatewayのカスタムドメインを設定
[ドメイン名] #サブドメイン#.#domain#
[ACM証明書 ] 作成済みの証明書（④）を選択する
※APIマッピングは、どのAPIのどのステージとマッピングさせるか、必要に応じて設定する。

→API Gateway ドメイン名（ターゲットドメイン）が発行される。

###⑥Roote53の#domain#のホストゾーンにレコードを作成する。（追加）

[レコード名　　] #サブドメイン#
[レコードタイプ] CNAME
[値　　　　　　] ⑤で発行された、API Gateway ドメイン名（ターゲットドメイン）

※ここが一番わかりやすい、#サブドメイン#.#domain#にアクセスするとAPIGatewayにアクセスするよと。

以上です。