OmniAICreator/Qiita-1.07M huggingface dataset:
Javaの例外処理を学んだのでメモを取る

Javaの学習をしていて、例外処理が出てきたのでメモがてらつくってみようとおもいます。

#例外処理とは
例外処理がどういうところで役に立つのかというと、

```
・処理の最中にサーバーのメモリがオーバーフローした時
・何らかの原因で月末(営業日)にならないと操作してデータを送信できてしまった場合
```

このように、開発者が想定していないエラーが起きてしまった場合の処理は、書かなければならないのですがそのコードが動く頻度が高いわけではないと思います。
それをメインのコードがおいてあるところにおいておいては、うっかりいじってしまう可能性が高くなってしまいます。
なのでそういったことがないように、例外処理を書いておくクラスを作成しておきます。

そうすることで、上記の例が起きたときに問題を回避することがしやすくなります。

##例外処理のための基礎文法

###try,catch,finallyを使った命令処理について

```
try{
  例外があるか確認したい文;  
}
catch (例外クラス1 変数名1){
  そして、例外が起きたときに実行する文(1つ目の例外処理が書いてあるクラスを呼び出すことが多い)

}
catch (例外クラス2 変数名2){
  もう一つの例外が起きたときに実行する文(二つ目の例外処理を呼び出すもの);
  
}
```

これだけ渡されてもなんのことかわからないと思うので、とある有名なサイトからソースコードを引用します。


それが、こちらになります。

```
class JSample2_1{
  public static void main(String args[]){
    int n[] = {18, 29, 36};

    System.out.println("開始します");

    try{
      for (int i = 0; i < 4; i++){
        System.out.println(n[i]);
      }
    }
    catch(ArrayIndexOutOfBoundsException e){
      System.out.println("配列の範囲を超えています");
    }

    System.out.println("終了しました");
  }
}
```

このソースコードの流れとしては、mainメソッドの中にある`int n[]`で数値型の配列を宣言して3つの配列を格納します。
そして、`System.out.println("開始します");`で開始のアナウンスをします。

そして、ついにtryのブロックの中に入ります。そしてtryの中でfor文を回します。
このfor文の内容だと、配列の中の値の数が4つ無いといけないのですが最初(`int n[]`)で宣言したときは3つしか無いのでエラーが起きます。
もしこの配列の数が4つあればエラーは怒らずこのまま終わるのですが、この場合はArrayIndexOutOfBoundsExceptionというエラーが起きてしまいます。ですが、その場合には「配列の範囲を超えています」というメッセージを出力したい。
そんな場合に、catchコマンドを使うことで解決します。
今回の場合は、エラーが起きてしまうのでcatchコマンドを使ってエラーが起きてしまったときに取るべき処理を書いていきます。
今回はその中身として`System.out.println("配列の範囲を超えています");`というメッセージを出力します。

##処理の流れをまとめると

```
配列を定義して、3つの要素をその中に入れる
↓
開始しますというメッセージを出力
↓
tryのブロックのなかにはいる。
↓
そして、for文で配列の要素数以上の数の要素を細書に定義した配列nから出力させようとする。
↓
エラーが起きるので、catchブロックの中に入れる
↓
そしてそのエラーが起きたときのために書いておいた、`配列の範囲を超えています`というメッセージを出力させるためのコードを実行させる。
```

というのが主な流れになります。

ただ、ここで一つ問題になってくることがあります。
やっぱりどうやってもcatchで拾いきれない例外というものが出てきてしまうケースがあります。その時は、`finallyメソッド`という例外の有無に関わらず実行される命令文を書いておくことで対処します。
ただし、これは例外をcatchできたとしても実行されてしまうので、そこは留意しておいてください。

#検査例外と非検査例外についての説明

検査例外と非検査例外の違いというは、

```
検査例外　：コンパイラが検査する例外(こんぱいらーが検知してくれる)
非検査例外：コンパイラが検査しない例外(コンパイラーが検知しない)
```
検査例外の違いはこのようなものですが、わかりやすく言うと
「このJavaのプログラムではどうしようもない外部の事情によってできた例外に対してつかうもの」
ということです。
例えば、何かしらのシステムを作っているとSQLの情報が記述されたファイルが送られてくることもあると思います。しかし、そのときにそのファイルが壊れてしまっていたらどうでしょうか。
当然エラーになってしまいますよね。
ただ、この場合は受取る側のJavaのプログラムには同仕様もありません。
そういったときにtry-catchを使って検査例外として処理させるわけです。
逆に非検査例外についてなのですが、これはtry-catchを強制しないものです。
例えば、先程例として使ったArrayIndexOutOfBoundsExceptionなどのプログラマーが気をつけて対処するタイプの例外に対しては、try-catchは使用しません。


以上になります。
まだまだ語り足りないところがあるかもしれませんが、今回はこれまでにします。

ありがとうございました。


#引用元

以下のリンクからソースコードを引用しました。
https://www.javadrive.jp/start/exception/index2.html
簡単な HTMLParser のソースコードを読んでみる [Javascript]

HTML を極めるって、どういうことなんですかね？
勉強で、簡単な HTML Parser を読んでみていたので、そのメモ。
間違いなどありましたら、ご指摘お願いします。

## HTML パーサーとは？
HTML ドキュメント は、そのままの形式では描画されません。描画されるには、一度 HTML ドキュメントを機械が読み込める形式に変えてから、それをレンダリングエンジンというプログラムに通すことで、描画が行われます。
ここでは、「HTML ドキュメントを機械が読み込める形式に変える」部分を[簡単なコードに落とした例](https://github.com/developit/htmlParser/blob/master/src/htmlParser.js)があったので、そのソースコードを読んでみます (ファイルはこの1ファイルだけです)。また、このコードを書いた Googler は preact という 軽量版の react を書いた人でもあります。

## ソースコード
では、早速読んでみましょう。
このコードでは継承などが多いので、まずは、そのデータ型の整理からしてみましょう。
まず、78行目から80行目にある

```javascript
	function HTMLElement() {
		this.childNodes = [];
	}
```

が、基本となる HTMLElement の型です。
81行目からある extend の部分 (コードの12行目見れば分かるように上書きしている) で、prototype 部分に、textContent (要素に含まれる文字列) や getElementsByTagName・getElementById や getAttribute・setAttribute などが加わります。

次に、Document という最初の親要素になる要素です。

```javascript
	function Document(){
		HTMLElement.call(this);
	}
```
これも、HTMLElement を継承し、{ nodeType : 9, nodeName: '#document'} で上書きされています。

次は、Node という HTMLElement の中身などを表すデータ型です。

```javascript
	function Node(){}
	util.extend(Node.prototype, {
		toString : function(){ return this.textContent; }
	});
```

prototype の toString で、代わりに textContent という内容を返すようにしています。
この Node は、TextNode, CommentNode, CDATASectionNode の３つの型で継承されています。

では、データ型も分かったので、パースしている部分を読んでみましょう。
パースをする関数が始まっているのは 189行目になっていますが、216行目の部分の、

```javascript
		while ( (token=domParserTokenizer.exec(str)) ) {
```

から、実際に 解析を行なっています。
この正規表現の domParserTokenizer を読んでみると、

```javascript
		domParserTokenizer = /(?:<(\/?)([a-zA-Z][a-zA-Z0-9\:]*)(?:\s([^>]*?))?((?:\s*\/)?)>|(<\!\-\-)([\s\S]*?)(\-\->)|(<\!\[CDATA\[)([\s\S]*?)(\]\]>))/gm;
```

のようになっていて、グループ分けした配列にするとようは、["マッチした文字列", "/があるかどうか", "タグの名前", "Attribute", "/があるかどうか", "コメントアウト始まり", "コメントアウト内容", "コメントアウト終わり", "CDATA始まり", "CDATA始まり", "CDATA終わり"] にマッチします。
ここでマッチした内容が、while文 で繰り返し処理されています。

217行目からの部分は、コメントアウト・CDATA 用のもので、前に出た CommentNode か CDATASectionNode の textContent などを上書きしています。
上書きができたら、text があったら parent.ChildrenNode に追加し 、tags に タグ内容を push して、parentNode の ChildrenNode に追加します。

次は、コメントアウトではない場合かつ タグの始めに "/" が含まれない場合です (244行目)。

```javascript
				tag = util.extend(new HTMLElement(), {
					nodeName : (token[2]+'').toLowerCase(),
					attributes : util.splitAttrs(token[3]),
					parentNode : parent,
					documentPosition : {
						openTag : {
							start : domParserTokenizer.lastIndex - token[0].length,
							end : domParserTokenizer.lastIndex
						}
					}
				});
				tag.className = tag.attributes['class'];
				tag.id = tag.attributes.id;
				tag.name = tag.attributes.name;
```

ここでは、nodeName や attributes などが上書きされた HTMLElement を作っています。終わった後は、コメントアウトと同じように、text があったら parent.ChildrenNode に追加し 、tags に タグ内容を push して、parentNode の ChildrenNode に追加しています。
その後は、img タグなど自分で閉じている形だったら closeTag を設定などして、それ以外だと parent を tag に 設定します。

最後に、タグが閉じるケースを書いているのが、272行目以降です。
まず 現在のタグの名前が parent の nodeName と一致した場合は、parent を tag の親要素にして tag に closeTag などを設定します。
次に 上の 自分で閉じている形でありながら、もう一度閉じてしまった場合は、tag の closeTag を上書きします。
それ以外の場合は、閉じられていないため、警告を出します。

内容は意外と読めたので、次は今度は実際に公開され利用されている HTML Parser を読んでみたいと思います。
shellscriptの配列で管理している値を、pythonの標準入力に渡してリストで扱う＋平均、標準偏差、最大、最小値まで求めてしまう

shellscriptの配列で管理している値を、pythonの標準入力に渡してリストで扱う＋平均、標準偏差、最大、最小値まで求めてしまう

以下の続き

> [shellscriptの配列で管理している値を、pythonの標準入力に渡してリストで扱う](https://qiita.com/seigot/items/74f7cf1f09331c61fa69)

shellscriptの配列

```sh:test.sh
arr=("100" "200" "300")
arr+=("400")
echo ${arr[@]}
```

pythonの標準入力に渡してリストで扱う

```python:test.py
data = list(map(int, input().split()))

from statistics import mean, median,variance,stdev

m = mean(data)
median = median(data)
variance = variance(data)
stdev = stdev(data)
print('mean: {0:.2f}'.format(m))
print('median: {0:.2f}'.format(median))
print('variance: {0:.2f}'.format(variance))
print('stdev: {0:.2f}'.format(stdev))
print('max: {}'.format(max(data)))
print('min: {}'.format(min(data)))
print('num: {}'.format(len(data)))
```

実行（`test.sh`の出力をパイプで`test.py`に渡すバージョン）

```
$ bash test.sh | python test.py
mean: 250.00
median: 250.00
variance: 16666.67
stdev: 129.10
max: 400
min: 100
num: 4
```

実行（`test.sh`の中から`test.py`を呼び出すバージョン）

```shell:test.sh
# declare                                                                                                                                                                                            
SCORE_ARRAY=()
LOOP_TIMES=10
TMP_LOG="tmp.log"

# append array                                                                                                                                                                                       
for i in `seq ${LOOP_TIMES}`
do
    SCORE_ARRAY+=("${i}")
done

# calc static value                                                                                                                                                                                  
echo ${SCORE_ARRAY[@]} | python test.py > ${TMP_LOG}
MEAN=`cat ${TMP_LOG} | grep "mean" | cut -d' ' -f2`
STDEV=`cat ${TMP_LOG} | grep "stdev" | cut -d' ' -f2`
MAX=`cat ${TMP_LOG} | grep "max" | cut -d' ' -f2`
MIN=`cat ${TMP_LOG} | grep "min" | cut -d' ' -f2`
NUM=`cat ${TMP_LOG} | grep "num" | cut -d' ' -f2`
cat ${TMP_LOG}
echo "${MEAN}" "${STDEV}" "${MAX}" "${MIN}" "${NUM}"
```

```bash
$ bash test.sh
mean: 5.50
median: 5.50
variance: 9.17
stdev: 3.03
max: 10
min: 1
num: 10
5.50 3.03 10 1 10
```

shellscript中心の処理で、平均、標準偏差などを求めたい時に便利かも

# 参考

https://note.nkmk.me/python-statistics-mean-median-mode-var-stdev/
データポータルでGoogle広告のコンバージョンアクション毎に数値を出す

ウェブ広告の運用をする中で、Excelを使った日々のレポート更新作業から脱却したく、
自動でデータが更新されて便利なGoogleデータポータルへ移行した時のメモ。

#コンバージョンアクション毎に数値を出す方法

Google広告で、複数のコンバージョンアクションを使って運用していた場合、
データポータルでは`コンバージョン`や`すべてのコンバージョン`単位でしか分類できず、
`コンバージョンアクション`ごとに分けて指標を見ることができません。

なぜなら、データポータルの仕様上、`コンバージョンアクション`を表す
`Segment Conversion Type Name`でフィルタリングをすると、テーブル内の全ての指標に適用されてしまうためです。

## データ統合を用いる


そこで、`データ統合`を用いて、Google広告のデータソースに、Google広告の`コンバージョン`
（コンバージョン列に含めていない場合は`すべてのコンバージョン`）だけが含まれたデータをリンクします。

その際に、`コンバージョンアクション`を表す`Segment Conversion Type Name`でデータを絞り込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/27510272-cf6f-6432-d3c7-972d24566da7.png)


##まとめ

データはダミーですが、これで、異なる`コンバージョンアクション`ごとにデータを分けてレポートできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/74417091-08be-52a1-0a3f-61ea97a354d0.png)

定期的にウォッチしたいが、抽出から成形まで時間がかかるような指標であっても、
一回作ってしまえば、簡単に定点観測することができそうです。

データポータルは作成するのは大変ですが、テンプレも転がっているのでオススメです。
リーダブルコードのまとめ。　2/2

前回のリーダブルコードまとめの続きです。

### 8章 巨大な式を分割する
- 式を保持する変数(説明変数)を使う
- ド・モルガンの法則を使う。複雑な論理条件はif(a<b)のような小さな条件に分割する。
- 大きなコードの塊を変数に置き換える(要約変数)。

### 9章 変数と読みやすさ
不要な変数があるとコードが読みにくくなる。以下のような方法で変数を減らしていく。
- 「中間結果」を保持する変数を削除する
- 変数のスコープをできるだけ小さくする。
- constやfinalなどを使ったり、一度だけ書き込む変数を使用すると、変数に何が入っているのかわかりやすくなる。


##【第三部 コードの再構成】
### 10章 無関係の下位問題を抽出する

- あるコードがある。そのコードの目的は「与えられた地点から最も近い場所を見つける」である。そしてそのコードの中には、「2つの地点の距離を算出する」という目的のコードがある。これを「無関係の下位問題」と呼ぶ。本来の目的とは違う下位問題を扱うコードは別の場所に分離する。
- 「無関係の下位問題」を扱うコードは、たいていの場合汎用化できる。よく使う処理は、どんなプロジェクトでも使えるような汎用コードとして別の場所に分離しておく。プロジェクト固有の処理を除き、積極的に汎用コードを作っていくよう心掛ける。

### 11章 一度に一つのことを
- 一度に複数のタスク（処理）を行うコードは読みづらい。大きな関数を小さな複数の関数に分離したり、大きな関数の中で論理的な段落を作ってタスクごとに分離したりするとよい。
- 読みにくいコードがあれば、そこで行われているタスク（処理）をすべて列挙する。それらのタスクを論理的に分離したり、別の関数に分けたりする。

### 12章 コードに想いを込める
- コードをわかりやすい言葉で説明する。アヒルや熊のぬいぐるみに対して自分のコードや問題、設計を説明する「ラバーダッキング」を行うことでより簡潔なコードが書けるようになったり、問題に対する解決策が見つかりやすくなる。

### 13章 短いコードを書く
出来るだけコードは書かない。コードを無駄に増やさない。
- 不必要な機能をプロダクトから削除する。過剰な機能は持たせない。
- 定期的にAPIリファレンスなどを読んで標準ライブラリでできることをわざわざコードを書いて実装するようなことを避ける。
- 最も簡単に問題を解決できるような要求を考える。

### 14章 テストと読みやすさ
テストコードも読みやすさが大切。

- テストコードが大きく恐ろしいものだと以下のようなことが起きる。<br />
・テストを直すのを恐れて本物のコードを更新するのを恐れる<br />
・新しいコードを書いたときにテストを書かなくなる
- テストのために本物のコードの読みやすさを犠牲にしたり、テスト都合で本物のコードに手を加えない。
- カバレッジ100%にしないと気がすまないのはよくない。現実的にはカバレッジが100％になることはない。
- あとでテストを書くつもりでコードを書くと、テストしやすいようにコードを設計するようになる。
TDD(テスト駆動開発）は本物のコードを書く前にテストコードを書こうという手法。
TDDを導入するかはともかく、テストを意識しながらコードをかけばいいコードになる。
Microsoftの認定資格を更新する

#はじめに
Microsoftのロールベース (アソシエイトおよびエキスパート) と専門分野の認定資格は、2022/02現在有効期間が1年間となっています。（Fundamentalsは除く）
多くのベンダー資格では有効期限が切れる際は同試験を受けなおす（あるいは上位資格を取得する）ことで期限の更新を行いますが、Microsoftの資格では更新専用の手順が存在します。
過去取得した認定資格を更新してみたので、更新方法について解説します。

#参考
[Microsoftの公式ドキュメント](https://docs.microsoft.com/ja-jp/learn/certifications/renew-your-microsoft-certification)

#有効期限の通知
##お知らせメール
有効期限の約6か月前に、以下のようなメールが届きます。
![スクリーンショット 2022-02-06 035602.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/e3dba872-c31d-faf6-a184-9cdfde356f70.png)
メール内の「Get started with renewing your certification」をクリックすると以下のような更新用ページに飛びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/06b634e6-5e09-26ef-5c91-ad00d845a2ce.png)
URLの「en-us」を「ja-jp」に変更すると日本語のページも開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/ab348b55-473c-7c9a-b0b6-813835ffbbbb.png)


##認定プロファイル
メールのリンクから飛ぶ以外に、自身のプロファイルページからも更新対象の資格を確認できます。

https://docs.microsoft.com/ja-jp/users/me/certifications

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/118955f8-4044-5b84-5aca-e75dfad285d0.png)
更新可能になった資格には「更新」ボタンが表示されます。

#更新試験の準備
更新用ページには試験対策用コンテンツのコレクションがあります。
当初の合格時から出題範囲が変わっている場合もあるので、こちらを利用して更新試験の準備をしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/6498b591-4b48-f98d-d158-8dbccc843cc8.png)

#更新試験
更新用ページの「更新評価を受ける」ボタンをクリックすると試験を受けれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/09b2f3f6-d258-a17e-6689-a7aa239de91a.png)

試験は20～30問の問題を45分間で解答するという形式です。
注意点として、一度解答した問題に戻ることはできません。1問づつ慎重に解いていきましょう。

#合格したら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/65e65006-6f5a-7c61-6c78-fd78ee193eaa.png)
無事合格すると、資格の有効期限が1年延長されます。
この1年延長は、延長試験を受けた日からではなく、元の有効期限の終了日から1年延長となります。
ですので、早く受けたからといって期限的に損することはありません。お知らせメールが届いたら、計画的に延長試験を受けましょう。

#不合格だったら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/dfda7d02-c4ac-a94e-ad15-55e25d513fe2.png)
本番の試験と同様、カテゴリごとの正答率が表示されます。これを参考に再試験に向けて学習を進めましょう。

また、正答率の低いカテゴリを基にカスタマイズしたコレクションを作成してくれる機能があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/0aec3e09-0153-1cdd-9d6b-fe0b47361643.png)
再試験は何度でも受けれるようなので、苦手分野を補強して再試験に臨みましょう。
（2度目の再試験はすぐ受験可能、それ以降は前の受験から24時間空ける必要があります）

#おわりに
有効期限が1年しかないというのは他のベンダーの試験と比べてもかなり短いと思いますが、更新は無料で可能かつ手順はかなりシンプルなので、その点では優位性があると思います。
進歩の早いパブリッククラウドの領域では、1年に1度の更新というのも理に適っていると思います。
常に新しい知識をインプットして、資格という形でその知識の証明を得ていきましょう！
textView.text = "文字列" はできるのに editText.text = "文字列" とできない理由とは

# 経緯

俺「Javaを使っていたけど、これからはKotlinだ！ まずは TextView での文字列の表示のあたりから。」
俺「`textView.setText("文字列")` っと。ほとんどJavaと変わらないけど、セミコロンが不要になったのはいいな」
Android Studio「セッターメソッドの呼び出しをプロパティ構文に置き換えられるよ！」
俺「なるほど！プロパティ構文で書けるのか、`textView.text = "文字列"` っと。いいね！」

俺「さて、じゃあ TextView の派生クラスである EditText の方も書き換えよう。 `editText.text = "文字列"` っと」
Kotlin「`Type mismatch: inferred type is String but Editable! was expected`」
俺「え？」
Kotlin「`Editable`じゃないとダメです。`String` なら `setText()` を使って。」
俺「...」

# 理由

`TextView#getText()` の戻り値の型は `CharSequence` [^1] だが、
`EditText#getText()` の戻り値の型は `Editable` [^2] となっているため。

[^1]: https://developer.android.com/reference/android/widget/TextView#getText()
[^2]: https://developer.android.com/reference/android/widget/EditText#getText()

## どういうことか

なぜセッター(`setText()`)ではなく、ゲッター(`getText()`)の話が出てきたかというと
Javaで定義されたゲッター/セッターをKotlinからプロパティ構文でアクセスする際、型の推論には**ゲッターの戻り値の型**が使用されるため。
(ちなみに、セッターしか無く対応するゲッターが無い場合にはプロパティ構文すら使えない)

メソッドのオーバーライド時に、戻り値の型を派生型(`Editable` は `CharSequence` の派生型)に変えることは許されているので、こんな事態となってしまっている模様。

(´・ω・｀)

# それでもプロパティ構文が使いたい

## TextView に明示的にキャストする

```
(editText as TextView).text = "文字列"
```

基底クラスにキャストするという一見「？」なコードにはなってしまう。

## (別) `Editable` に変換する

```
editText.text = Editable.Factory.getInstance().newEditable("文字列")
```

インスタンス生成を伴うのでパフォーマンスが重視される場面では注意。
[JS]サーバーサイドにリクエストを送る

学習したことのアウトプットとして

ブラウザでイベント発火
↓
JavaScript
↓<font color="Red">リクエスト</font>
ルーティング

上記の`リクエスト`の部分の学習をしていて、処理をするための記述が自分の中でごちゃごちゃ混乱しているので、少しでも整理できればいいなと思い、記事にしてみる。

#XMLHttpRequestオブジェクト
JavaScriptを用いてサーバーとHTTP通信を行うときに利用するオブジェクト。
XMLHttpRequestのメソッドやプロパティを利用してJSからのリクエストの実装を進めます。

```javascript:記述例
const XHR = new XMLHttpRequest();
```
`new XMLHttpRequest`と記述することで、新しくオブジェクトを生成できます。
そして、新たに生成したXMLHttpRequestオブジェクトを`変数XHR`に格納しています。

変数名のXHRはXMLHttpRequestの略です。

##openメソッド
リクエストを初期化するメソッドです。リクエストの内容を指定するメソッドだと理解する。
`XMLHttpRequestオブジェクトのメソッドの一種`です。

```javascript
const XHR = new XMLHttpRequest();
XHR.open(HTTPメソッド, パス, 非同期通信であるか);

//例
XHR.open("POST", "/posts", true);
```
|記述場所|目的|記述例|
|-------|---|-----|
|第一引数|HTTPメソッドの指定|POST|
|第二引数|パスの指定|/posts|
|第三引数|非同期通信のON/OFF|true(ON)|

##responseTypeプロパティ
レスポンスの`データフォーマット（＝どのような形式のデータにするか）`を指定するプロパティ。
リクエストを送信する際に、レスポンスで欲しいデータフォーマットをあらかじめ指定しておく必要があります。
###JSON（JavaScript Object Notation）
JavaScriptをもとにして構成されたデータフォーマットのことです。
データを記述するフォーマットはいくつかありますが、動作が軽いことやモダンなフロント言語と親和性が高く管理がしやすいなどのメリットがあります。

```javascript:記述例
const XHR = new XMLHttpRequest();
XHR.open("POST", "/posts", true);
XHR.responseType = "json"; //データフォーマットをJSONに指定
```

##send()メソッド
リクエストを送信するメソッド。`XMLHttpRequestオブジェクトのメソッドの一種`です。

```javascript:記述例
const form = document.getElementById("form");  //フォームの要素を取得
const formData = new FormData(form);  //フォームに入力された値を取得
const XHR = new XMLHttpRequest(); //オブジェクトを生成
XHR.open("POST", "/posts", true);  //リクエストの内容を指定
XHR.responseType = "json";  //データフォーマットを指定
XHR.send(formData);  //フォームに入力された値を送信
```

#まとめてみて
おそらくXMLHttpRequestオブジェクトには、まだたくさんメソッドやプロパティがあって、今の自分には難しい内容なのかも・・と不安に思うが、とりあえず今回学習したものについては少し理解が深まったかなと感じた。

※補足等ありましたらコメント頂けると幸いです。
shellscriptの配列で管理している値を、pythonの標準入力に渡してリストで扱う

shellscriptの配列で管理している値を、pythonの標準入力に渡してリストで扱う方法です
（ニッチかもですが）

shellscriptの配列

```sh:test.sh
arr=("100" "200" "300")
arr+=("400")
echo ${arr[@]}
```

pythonの標準入力に渡してリストで扱う

```python:test.py
l = list(map(int, input().split()))
print(l)
```

実行（パイプで渡す）

```shell
$ bash test.sh
100 200 300 400
$ bash test.sh | python test.py
[100, 200, 300, 400]
```

これでOK（皆さんはどうやってるのでしょうか）

# 参考

[【bash】シェルの配列について](https://www.task-notes.com/entry/20150119/1421646435#:~:text=%E9%85%8D%E5%88%97%E3%81%AB%E8%A6%81%E7%B4%A0%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AF%20%E9%85%8D%E5%88%97%E5%90%8D,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%80%82&text=%E6%8B%AC%E5%BC%A7%E3%82%92%E4%BB%98%E3%81%91%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F,%E6%B0%97%E3%82%92%E4%BB%98%E3%81%91%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%E3%80%82)
Power BI: Teams Channel の Reactions 解析用 カスタムコネクター

# 背景
Teams のリアクション解析方法が無かったので、取りあえず作ってみた。

# 概要
- Graph API で messages を取得
- 20件ずつしか取れないので、指定日までひたすら取得
- 指定日は、日付指定ではなく、何日前か？を指定

:::note warn
指定日より古いデータがあった時点で、その際に取得した全データを返すので注意
気になるなら、フィルターすれば良い
:::

:::note info
Power BI Serivce や Custom Connector での自動更新には認証が出来ないので、たぶんアプリ登録必要？
:::

https://docs.microsoft.com/en-us/graph/api/channel-list-messages?view=graph-rest-beta&tabs=http

:::note warn 2022/9/24
全メッセージ取得には課金発生している様子・・。その影響が出てるかも
:::

https://learn.microsoft.com/ja-jp/graph/teams-licenses

# 機能改修
## 2022/2/16 不具合修正
Version 1/0/2/0

- Replies の Text 返却が固定値になっていたので修正

## 2022/2/8 要望があったので追加＆修正 (詳細版へのみ）
Version 1/0/1/0

- CreatedDateTime の TimeZone 対処
- nextlink が無い場合の取得終了（エラー対処）
- Replies の取得追加

https://docs.microsoft.com/ja-jp/graph/api/chatmessage-list-replies?view=graph-rest-1.0&tabs=http

- message 情報の追加
    - subject
    - createdDateTime
    - deletedDateTime
    - bodyText: contentType = text 時のみ。それ以外は　<none text> とした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/30a3af49-c182-f1a8-3952-81b652f7ad26.png)


# すぐ使ってみたい人用の使い方
## まずはダウンロード
https://github.com/baku2san/PQExtensionTeamsReactions/blob/main/PQExtensionTeamsReactions/bin/Release/PQExtensionTeamsReactions.mez

## カスタムコネクター認識フォルダーへ保存
以下で多分行ける筈。

> %userprofile%\ドキュメント\Power BI Desktop\Custom Connectors

Documents じゃないと動かない場合もあるかも？英語版？

## Power BI を（再）起動して、今回のコネクターを探す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/68018f6c-5ffd-9528-840a-c553cd897b38.png)



## 以下が出るので「続行」（詳細省略）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/5b9a699c-704f-992c-083b-80262f8522db.png)

不安な場合は、GitHub からコードをダウンロードして、Build して *.mez ファイル作成してください

## Teams の チャネル内メッセージの URL をコピーして貼り付けして、「OK」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e560055f-d22a-8ace-c5e8-d62d4268ff87.png)

"TeamId", "ChannelId" を「リンクをコピー」で取得したURLから抽出してます

![Connecting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c2a855b2-b218-ef86-79a7-0ad195db8182.png)

# データの再構築方法
https://qiita.com/baku2san/items/e4f4517d7dca6336b7a9

# コネクター二点
## TeamsReaction
投稿者とリアクションで集計したもの
こっちさえあれば、と思ったものの・・集計の仕方に悩んだので詳細版も追加

悩んだことは
- Bot の投稿
- 投稿者自身の reaction 
- reactionType での集計（それぞれに分けたほうがいいのか・・それとも三分割ぐらいにしたほうがよいのか・とか）

![RetreiveSample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f442b3ed-18cb-0cce-34fc-435496355395.png)
## TeamsReactionDetails
元となるデータを必要なとこだけ抜粋して返してる
![RetreiveSampleDetails.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3e974385-247e-5d4d-6fa8-80944eb7a15d.png)


### 注意
- Bot代理投稿だと、postUser が null なので、 onBehalfOf がある
- 完全Botだと、両方 null
- link は、元となるメッセージへのリンクなので、気になるメッセージの確認用途に
- reactions は nullable で複数有。誰がつけたかも保持しているので、自己reactions を外す方がいいかも

# ソース
https://github.com/baku2san/PQExtensionTeamsReactions

# あとがき
Team, Channel を選択式にしたかったんだけどダイアログにする方法がわからず諦め

事前に team だけ取得して見せることは出来そうだったけど、channel もってなったので・・
Power Automateで、選択したチャネルメッセージの分析結果を通知してくるようにしたほうが使いやすいかも？
BootstrapからTailwindに乗り換えを試みる

# はじめに
<!-- 発端や概要を記載 -->
普段フロントの見た目をBootstrapで誤魔化して生きているが、Bootstrap感が嫌になる事がある。
TailWindというのが何やら流行っているらしく、
公式ドキュメントを流し見した感じBootstrap感が全然無かったのでちょっと触ってみる。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [第一印象](#第一印象)
1. [もしかして](#もしかして)
1. [daisyUI](#daisyUI)
1. [FlowBite](#FlowBite)
1. [おわりに](#おわりに)

<!-- 各チャプター -->
<a id="#第一印象"></a>
# 第一印象
うーん・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/0021e681-f2bd-4681-db9d-82fee0f83969.png)

```html:
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>
```

ボタン1つでこれだけクラスを書かないといけないとなると、色んなページでこのボタンをコピペしないといけないんかぁ・・・。
複数人で開発するとなると勿論全く同じクラスを書く訳では無いし、なんだかなぁ・・・。

<a id="#もしかして"></a>
# もしかして

あれ？もしかしてTailWindでそのまま書くのでは無く、プロジェクト単位でコンポーネントを作ってそれを使えって事か？
じゃあ誰かコンポーネント作ってんじゃねぇか？

と思ったのでTailWindをBootstrapみたいに書けるコンポーネントを探してみました。

<a id="#daisyUI"></a>
# daisyUI
TailWindで作られたUIコンポーネント、やはりありました。
bootstrapのようにデザイン済みのパーツが用意されてるので最低限の記述で済みます。

https://daisyui.com/docs/use

ドキュメントも見やすくて欲しいものを探しやすいので大変ありがたい。

<a id="#FlowBite"></a>
# FlowBite
こちらもコンポーネントと言えばコンポーネントなんですが、
TailWindで作られたパーツのレシピ集みたいなものです。

https://flowbite.com/docs/getting-started/introduction/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/569c36c3-0d78-0cf2-bece-05c9414de71a.png)

ボタンが欲しければ1からTailwindで書くのでは無く、TailWindで作られたボタンをコピペしようぜって感じですね。
なのでレシピ集という表現の方が分かりやすいです。


<a id="#おわりに"></a>
# おわりに

TailWindをそのまま使うのは自分には向いてなさそうなのでdaisyUIをベースにちょい足ししたりして活用して見ようと思います。
Vue3+Vuetify(Preview)のプロジェクト作成時のエラーについて

# はじめに
VuetifyがVue3に正式バージョンではサポートしておらず、プレビュー版で色々エラーを踏んだので、シェア。ちなみにM1 Mac。
（2022年３月に正式サポート版をリリース予定）

# 各ライブラリのバージョン
ここが最も重要。
以下のバージョンで上手く行った。（おそらくメジャーバージョンがあっていればOK）

```ruby:terminal
% node -v && vue -V && npm -v   
v17.4.0
@vue/cli 5.0.0-rc.2
8.3.1
```

この状態で、vue create ＆ vue add vuetifyを行う。
各ライブラリが古いと以下のエラーが表示されるはず。

```ruby:terminal
% npm run serve
 ERROR  ValidationError: Progress Plugin Invalid Options
        
        options should NOT have additional properties
        options should NOT have additional properties
        options should NOT have additional properties
        options should pass "instanceof" keyword validation
        options should match exactly one schema in oneOf
        
ValidationError: Progress Plugin Invalid Options

options should NOT have additional properties
options should NOT have additional properties
options should NOT have additional properties
options should pass "instanceof" keyword validation
options should match exactly one schema in oneOf

```

エラーが発生した際のライブラリのバージョンは以下。

```ruby:terminal
% node -v && vue -V && npm -v   
v17.4.0
@vue/cli 4.5.15
8.3.1
```

# vue add vuetifyの際のエラーの対処
vuetifyを追加しようとすると、以下のエラーが発生する。

```ruby:terminal
% vue add vuetify  
  10:9  error  Component name "Home" should always be multi-word  vue/multi-word-component-names

✖ 1 problem (1 error, 0 warnings)

```

これは.eslintrc.jsにコードを足すことで対処する。

```.eslintrc.js
  overrides: [
    {
      rules: {
        "vue/multi-word-component-names": 0,
      },
      files: [
        "src/views/**/*.vue",
      ],
    },
  ],

```
AIシステムトレード　改良編

https://qiita.com/EasyCording/items/29c76dec61fded6722dc

前回に続いて、実装をしていく。
前半は前回と同じ。


```main.py
!pip install pandas_datareader
!pip install --upgrade pandas
!pip install mplfinancme
```

```main.py
import pandas as pd
import datetime as dt
from pandas_datareader import data
import mplfinance as mpf
import torch
from torchvision.datasets import ImageFolder
from torchvision import models, transforms
import torch.nn as nn
import numpy as np

import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'

apikey = '取得したAPIキー'
symbol = 'EURUSD'

start = dt.date(2021,1,1)
end = dt.date(2022,2,3)

df = data.DataReader(symbol,'av-daily',start,end, api_key=apikey)
```

```main.py
wsize=80 #サンプル期間
after=10 #最終レコード＋α
change_large = 4 #変化大　4%

df.index = pd.DatetimeIndex(df.index)
alldata =[]

for time in range(len(df)-wsize-1):
    try:
        dfspan = df[time:time+wsize]
        alldata.append({"df":dfspan,"date":dfspan.tail(1)})
    except:
        pass
```

```
open	high	low	close	volume
2021-10-13	1.1530	1.1599	1.1527	1.1597	0
2021-10-14	1.1597	1.1624	1.1582	1.1598	0
2021-10-15	1.1597	1.1619	1.1586	1.1600	0
2021-10-18	1.1599	1.1622	1.1570	1.1609	0
2021-10-19	1.1609	1.1669	1.1607	1.1629	0
...	...	...	...	...	...
2022-01-26	1.1299	1.1311	1.1234	1.1241	0
2022-01-27	1.1241	1.1243	1.1130	1.1142	0
2022-01-28	1.1143	1.1174	1.1120	1.1146	0
2022-01-31	1.1141	1.1248	1.1137	1.1233	0
2022-02-01	1.1235	1.1279	1.1219	1.1270	0
```

#メイン
一応考えたことは、こういう感じでイメージできる。

```main.py
a = np.array([x for x in dfspan['close']])
m = np.outer(a, a).astype(np.float32)
plt.imshow(m, vmin=np.min(m), vmax=np.max(m), interpolation='none')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/641602b0-56ae-2246-6f42-b1eac32e6412.png)

Close , High , Lowをテンソルに突っ込む
High,Lowは、それぞれcloseに対する差分として扱っている


```main.py
from PIL import Image

def min_max(x, axis=None):
    min = x.min(axis=axis, keepdims=True)
    max = x.max(axis=axis, keepdims=True)
    result = (x-min)/(max-min)
    return result
    
a = np.array([x for x in dfspan['close']])
b = np.array([x for x in dfspan['high']])
c = np.array([x for x in dfspan['low']])
m = min_max(np.outer(a,a).astype(np.float32))
n = min_max(np.outer(a-b,a-b).astype(np.float32))
o = min_max(np.outer(a-c,a-c).astype(np.float32))
te = np.stack([m,n,o])
tmp = torch.from_numpy(te).clone()

img_pil =  transforms.ToPILImage(mode='RGB')(tmp)
plt.imshow(img_pil)
plt.show()

```

なんか凄くないですか？　
とても特徴量があるようには見えない・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/28571572-ea93-e7b1-79ed-67466fad66b0.png)
firebase-toolsのバージョンアップに伴うforceオプションの追加

# firebase-toolsのバージョンアップに伴うforceオプションの追加

firebaseのアクションをきっかけにfirestore内のデータを操作したい場合があります。

ex.
アカウントが削除されたときにFirestoreデータベース内のユーザーのコレクションを削除するFirebase関数。

```code
const firebase_tools = require("firebase-tools");
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.deleteUser = functions.auth.user().onDelete((user) => {
  return firebase_tools.firestore
      .delete(`users/${user.uid}`, {
        project: process.env.GCLOUD_PROJECT,
        token: functions.config().fb.token,
        recursive: true,
        yes: true
      }).catch((error) => {
        console.log(error);
        throw new functions.https.HttpsError(
            "unknown",
            "Error deleting user's data"
        );
      });
});
```

"firebase-tools": "9.18.0"まではこれで動作していましたが、"firebase-tools": "^10.1.*"以降で確認が求められるように。
そのため、force: trueが必要になりました。

```code
{
        project: process.env.GCLOUD_PROJECT,
        token: functions.config().fb.token,
        recursive: true,
        yes: true,
        force: true // add this
}
```

firebase-tools
`firebase firestore:delete -h`で最新のコマンドを確認することもできます。

```options
Options:
  -r, --recursive    Recursive. Delete all documents and subcollections at and under the specified level. May not be passed along with --shallow.
  --shallow          Shallow. Delete only documents at the specified level and ignore documents in subcollections. This action can potentially orphan documents nested in subcollections. May not be passed along with -r.
  --all-collections  Delete all. Deletes the entire Firestore database, including all collections and documents. Any other flags or arguments will be ignored.
  -f, --force        No confirmation. Otherwise, a confirmation prompt will appear.
  -h, --help         output usage information
```

## 参考
https://stackoverflow.com/questions/70932654/firebase-functions-firebaseerror-missing-required-options-force-while-runni
【jQuery】今いるディレクトリに該当するナビゲーションだけスタイルを変えたい

#背景
前回、一部ディレクトリだけWordPressでできてるサイトでヘッダーフッターを一括管理する方法を書きました。

https://qiita.com/kg_nuts_kg/items/9bbbf8270c4206031932

これってヘッダーはどのページからも同じものを呼び出します。
で、こういうデザインのヘッダーメニューってよくあると思うんです。
![スクリーンショット 2022-02-05 17.38.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522080/3806cb8c-7260-e2bd-f07c-ef12faa54ef8.png)

「会社紹介」のページにいるときは、メニューの「会社紹介」のところだけスタイルを変えたい！！！
どうする？ページごとに違うマークアップのメニューを呼び出す？しんどいですよね。
じゃあヘッダーのマークアップはそのままで、jQueryの力を借りて勝手にスタイル変えてもらいましょう！！！

#HTMLのメニュー部分のマークアップ
ヘッダーメニュー部分はこんな感じでできているとします。
実際にはスタイル当てるためにclassとかバシバシ当てますが、わかりやすくするために最低限にしておきます。

```html:index.html
<header>
 <h1>サイトタイトル</h1>
 <nav>
  <ul>
   <li>
    <a class="header_link" href="/">ホーム</a>
   </li>
　　<li>
    <a class="header_link" href="/company/">会社紹介</a>
   </li>
　　<li>
    <a class="header_link" href="/works/">事業紹介</a>
   </li>
   <li>
    <a class="header_link" href="/recruit/">採用情報</a>
   </li>
　　<li>
    <a class="header_link"href="/news/">お知らせ</a>
   </li>
　　<li>
    <a class="header_link" href="/contact/">お問い合わせ</a>
   </li>
  </ul>
 </nav>
</header>
```

で、例えば https://hogehoge.com/company/ みたいな、会社紹介に当たるディレクトリのページを見ている時にはこんな感じになってほしい。

```html:company/index.html
<header>
 <h1>サイトタイトル</h1>
 <nav>
  <ul>
   <li>
    <a class="header_link" href="/">ホーム</a>
   </li>
　　<li>
    <a class="header_link active" href="/company/">会社紹介</a>
   </li>
　　<li>
    <a class="header_link" href="/works/">事業紹介</a>
   </li>
   <li>
    <a class="header_link" href="/recruit/">採用情報</a>
   </li>
　　<li>
    <a class="header_link" href="/news/">お知らせ</a>
   </li>
　　<li>
    <a class="header_link" href="/contact/">お問い合わせ</a>
   </li>
  </ul>
 </nav>
</header>
```

jQueryにいい感じにやってもらいましょう。こんな感じです。

```javascript:script.js
$(function(){
 const currentUrl = location.pathname;  //現在のURLのドメイン以下のパスを取得
 const urlArr =  currentUrl.split('/'); //取得したURLを / で区切って配列化する
 const currentDir = urlArr[1];  //配列の1番目、親ディレクトリを取得

 $('.header_link').each(function (i, v) { 

      let targetHref = $(v).attr('href'); // header_linkのhref属性を取得
      let hrefArr = targetHref.split('/'); //href属性の値を分割して配列化する
      let hrefDir = hrefArr[1]; //href属性の第1階層を取得

    // 現在の第1階層と、href属性の第1階層が一致していたらclassを付与する
    if (currentDir === hrefDir) {
      $(v).addClass('active');
    }

  });
});
```

これで、companyディレクトリを見ている場合は 上記company/index.htmlのコードみたいになるし、他の階層でも同じように動きます。
.activeのclassが当たっている.header_linkに、スタイルを当てておきましょう。

例

```css:style.css
.header_link.active {
 border-bottom: 2px solid #000;
}
```
#終わり
検索してみたら、ほとんど同じことを紹介してるサイトありました。
要件やサイト構成に合わせてカスタマイズしてみてください。

https://attadesign.co.jp/blog/745/
【Vue.js】VueCLIインストール時の「zsh: command not found: vue」の解決方法

```
npm install -g @vue/cli
```
を実行し、VueCLIをインストールした後に、

```
vue --version
```
としてバージョンを確認しようとしたのですが、

```
zsh: command not found: vue
```
と返ってきてしまったので、備忘録のため解決方法を掲載しておきます。

#zsh: command not found: vueの解決方法

```
open ~/.zshrc
```
ターミナルで上記のように入力し、.zshrcファイルを開き、最下部に

```
export PATH=$PATH:/Users/ユーザーの名前/.npm-global/bin
```
と入力。その後、ターミナルにて

```
source .zshrc 
```
を実行。
再度、バージョンを確認したところ、無事コマンドが実行され、インストールができていることが確認できました。
Viewを突き出して表示させたい Part2

#初めに

[Viewを突き出して表示させたい　](https://qiita.com/Tsubasa12/items/8db55ca6a186abf2d905)

前回こちらの記事で
FrameLayoutやLinearLayoutで使える
Viewを凸出して表示させる方法を書きました

今回はConstraintLayoutを使って　Viewを突き出して表示させていきたいと思います

#コードでxmlに書いていく
前回と同じように　Viewが突き出しているこ事を確認できるように、色のついたViewを用意しました

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

      <FrameLayout
        android:id="@+id/teal_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="50dp"
        android:background="@color/teal_200" />
    
      <FrameLayout
        android:id="@+id/purple_view"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:layout_gravity="center_horizontal"
        android:background="@color/purple_200"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

![スクリーンショット 2022-02-06 22.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/07deb9a4-a3ca-5962-7317-b1248760109c.png)


前回との違いは本題の通り大元のViewがConstraintLayoutである事と、親子の関係ではなくそれぞれで独立するViewである事です
(それぞれ見やすいように真ん中に配置する為layout_constraintやlayout_marginの設定をしています)


    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

      <FrameLayout
        android:id="@+id/teal_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="50dp"
        android:background="@color/teal_200" />

      <FrameLayout
        android:id="@+id/purple_view"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:layout_gravity="center_horizontal"
        android:background="@color/purple_200"
        app:layout_constraintTop_toTopOf="@+id/teal_view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/teal_view"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>


 purple_viewの自身の上辺と下辺にteal_viewの上辺をの制約を設定します

![スクリーンショット 2022-02-06 22.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/92544486-ba39-3e81-6817-7fe3410acaa6.png)

Viewを突き出して表示することができました！

#注意
Viewのコードの順番に違和感があったかもしれませんが、ConstraintLayoutでは下に書いたViewが高さでは上に表示され　

![スクリーンショット 2022-02-06 22.26.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/06a089dd-d87e-6bd6-6a08-c61068c0cbc0.png)
同じような制約の設定を行っても　Viewが半分見切れた状態になってしまいますので注意が必要です！


#最後に
今回は"突き出して表示する"と言うよりも、ConstraintLayouの特徴をいかした"Viewを重ねて表示する"といった表現の方が正しいかもしれませんね
前回に続いてViewを突き出して表示する方法について記事を書きましたが、今回の方法を知った時には自分の視野の狭さを実感しました。
また、違った方法を見つけましたら記事にしていこうと思います。
Clear Linux にリモートVNC出来る様に

#やりたいこと
リモートサイトから本宅にあるLinuxのデスクトップにSSH経由でVNCで画面共有したい。
リモートにいるとやはりGUIでアクセス出来ないと何かと不便。XRDPでやろうとしていたが、なかなかうまくいかない。というわけでVNCでとらいしたところ成功したのでここに書き留める。
#まずVNCのインストール

```
$ sudo swupd bundle-add vnc-server
```
次にクライアント（私の場合MacOS）からSSHでアクセスするスクリプト

```
#!/bin/sh
# vnc to remote host via ssh
#
REMOTEHOST="your-domain.mydns.jp"
REMOTEUSER="user-name"
REMOTEPORT=65xxx
VNCPORT=5901
#
if [ $# -gt 0 ]; then
	VNCPORT=$1
fi
#
ssh -A -t -L ${VNCPORT}:localhost:${VNCPORT} ${REMOTEUSER}@${REMOTEHOST} -p ${REMOTEPORT}
```
SSHでシェルに入った後、VNCサーバを立ち上げて、VNCで使うポート（5900＋ディスプレー番号　最初は5901でこれが上のシェルスクリプトではデフォルト）をLocalhostの同じポートにバインドしてMacOSからLocalhostに対してVCNする形でアクセスする。
こうすれば外部に露出するのはFWに開けた65xxxのポートだけ。

```
$ vncserver
You will require a password to access your desktops.

Password:
Verify:
Would you like to enter a view-only password (y/n)? n
xauth:  file /home/hoge/.Xauthority does not exist

New 'clr-linux:2 (hoge)' desktop is clr-linux:2
...

$ vncserver

New 'clear:1 (hoge)' desktop is clear:1

Starting applications specified in /home/hoge/.vnc/xstartup
Log file is /home/hoge/.vnc/clear:1.log

hoge@clear~ $ cd .vnc
hoge@clear~/.vnc $ cat config
## Supported server options to pass to vncserver upon invocation can be listed
## in this file. See the following manpages for more: vncserver(1) Xvnc(1).
## Several common ones are shown below. Uncomment and modify to your liking.
##
# securitytypes=vncauth,tlsvnc
# desktop=sandbox
 geometry=2000x1200
# localhost
# alwaysshared
```
~/.vncの下にあるconfigの中身を必要に応じてコメントを外す。（上の例は画面の大きさを　 geometry=2000x1200　で調整）

その後、MacOSの画面共有で
vnc://localhost:5901

![スクリーンショット 2022-02-06 22.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/ad719df4-3778-d178-1ec2-76cc5b797bc1.png)
先ほど作ったパスワードを入力

![スクリーンショット 2022-02-06 22.53.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/f4480453-2609-c41d-f092-b8070878c1c0.png)

これで、在宅でも別宅でも同様にVNCでClear Linuxの環境にGUIでアクセスできる！
めでたし、めでたし。



参照リンク：
https://docs.01.org/clearlinux/latest/guides/network/vnc.html
ANT+対応のスマートウォッチから心拍数を取得してOBSに表示させる(GitHubにソースあり)

# 経緯
最近、GarminのFenix7Sを購入してテンション爆上がりしたんですが、当然こんな機能モリモリの端末を手に入れたら色々遊んでみたくなりますよね。
なんと、この端末はANT+で心拍数を送信できるようなので「なんかよくYoutuberがやっているような、ゲーム画面の右上あたりの心拍数表示が実装できるんじゃね！？」という感じがしたので、なんか作ってみました。

# アプリについて
ひとまず、アプリの使い方とかだけを知りたい人も居るかも知れないので、技術云々は一旦おいておいて説明します。
機能は主に「ANT+で送信された心拍数情報をブラウザに表示するアプリ」です。
また、表示するレイアウトはユーザーが自由にカスタムできるようにしています。（レイアウトのファイルはejsになっているため、基本的なHTMLが書けるのであれば割とどんなレイアウトでも作れるはず）

※ちなみになぜブラウザに表示なのかといいますと、単純にOBS[^1]でブラウザをソースとして選択できることと、心拍数を取得するライブラリがNode.jsで準備されていたため、作りやすかったからという理由です。
![heartbeat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523180/305e0306-d04c-e70f-6e0e-fd880bfee4f6.gif)

# 使用方法
基本的には[Githubのリポジトリ](https://github.com/yamaserif/Mr_Heartbeat/tree/develop)を確認してください。
一応、MITライセンスですので自由に改変しても大丈夫です。
また、利用には以下の機器が必要になります。
・ANT+にて心拍数を送信できる端末
・ANT+受信用のドングル

# 環境
・Node.js
・Fastify
・TypeScript
・ejs
辺りの環境で作成しています。
せっかくなので、今まで使ったことがなかったフレームワークとか使おっかな～とか思っていたら、こんな闇鍋みたいな構成になってました…
この構成はネットにも資料が少なく苦労しました。
ちなみに今回のアプリの肝となる心拍数取得部分は「ant-plus」[^2]というライブラリを使用しています。
また、「nexe」にて単一での実行形式ファイルも準備しておいています。

動作確認を行った構成は
・OS：Windows 64bit
・心拍数送信端末：Garmin fenix 7S Sapphire Dual Power
・心拍数受信ドングル：AZ4U ANT+USBドングル ミニタイプ
になります。（もしかしたら他の端末だとうまく動作しないとかあるかも…[^3]）

# 構成
ページ構成は大体以下のような感じです。
![heartbeat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523180/f6d63c3c-244b-03a5-2baa-63f1f254f958.png)
ブラウザ側に情報を保持させるのもあれなので、Node.js（サーバ側）に各種設定値を保持させています。（心拍数表示ページのレイアウトファイル設定や心拍数取得に関わる設定など）
また、ページの描写をリアルタイムで変化させるために一定周期で「心拍数取得用API」にリクエストを投げ、その値を使って動的に要素を制御させています。

# 感想
趣味で遊んだだけにしては、思ったよりそれっぽいものができたので満足です。
個人的には「どんどん誰か使ってってくれ！」って感じでGithubにおいたので、改変なりしていい感じに皆さんも遊んでいってくれると嬉しいです。[^4]（個人でゴリゴリにカスタムしたレイアウトとか見てみたい。）

本当はGarmin IQ用のアプリ開発も手を出して見ようと思っていたのですが、今回割としっかり開発したので流石にしばらく休憩しようかと思います。
あ、あと今回Qiita初投稿記事ですので、マサカリは優しく投げていただけると幸いです。
以上、ここまでありがとうございました。

[^1]: よく考えると、別に私自身は配信者ではないので、遊ぶというだけの目的であればそこにこだわる必要はなかったかもしれません…
[^2]: う～ん、そのまんまの名前でわかりやすい！
[^3]: 流石にいろんな端末で動作確認ってのはお財布的に厳しいっすね…
[^4]: 心拍数を出したホラゲ実況とかいいっすよね。
Vue.jsとRailsでユーザ作成時の422 Unprocessable Entityエラー

# エラー内容
RailsとVue.jsプロジェクトで、ユーザ登録機能を実装した際
「422 Unprocessable Entity」　というエラーが発生し登録できなかった。

エラーメッセージを検索してみたけれど、原因詳細はなかなか探せず。。。
と思っていたところ、下記参考記事を見つけて解決できた。感謝！！


https://qiita.com/baby-0105/items/fd563733d2b6b810a4dc#:~:text=%E5%8E%9F%E5%9B%A0,-CSRF%E4%BF%9D%E8%AD%B7%E3%81%8C&text=%E3%81%93%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E6%80%92%E3%81%A3%E3%81%9F,%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A8%E8%80%83%E3%81%88%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82



```Ruby:渡したパラメータ
Started POST "/auth" for ::1 at 2022-02-06 21:41:56 +0900
Processing by Auth::RegistrationsController#create as HTML
  Parameters: {"name"=>"yyyyyy", "email"=>"yyyyy@test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "registration"=>{"name"=>"yyyyyy", "email"=>"yyyyy@test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}
   (0.1ms)  begin transaction
  User Exists? (0.2ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."provider" = ? LIMIT ?  [["email", "yyyyy@test.com"], ["provider", "email"], ["LIMIT", 1]]
   (0.0ms)  rollback transaction
```

```Ruby:エラー
Completed 422 Unprocessable Entity in 262ms (Views: 0.2ms | ActiveRecord: 0.3ms | Allocations: 5646)
```

# 原因

- パスワードの入力規則を満たさない値を入力していた

# 解決方法

- ブラウザ検証ツールから、コンソールに出力したエラー詳細を読み取る

- 入力規則を満たす６文字以上のパスワードを入力

# 解決方法詳細

- ブラウザ検証ツールから、コンソールに出力したエラー詳細を読み取る

###### エラー発生当初、コンソールに表示された下記内容だけを見ていたが原因詳細は発見できず。
![スクリーンショット 2022-02-06 21.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/e7f7424e-f38f-8be2-690e-17782f87b627.png)

###### ブラウザ検証ツール [ネットワーク]タブ->[XHR]->[ぷれ]からエラー詳細を読み取る。
今回、Vue.jsにてasync/awaitを用いた非同期通信を行なっていたため、[XHR]を確認した。
パスワードが短かすぎる、という些細なエラーだった。。。。。
![スクリーンショット 2022-02-06 21.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/99490406-3c43-0b34-449b-a5bbc89db3dd.png)

入力規則を満たす６文字以上のパスワードを入力して、無事解決！
![スクリーンショット 2022-02-06 22.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/56d6a7e8-6830-bf75-26fd-2c5a223a74a1.png)


# 最後に
コンソールに出力されたエラーメッセージだけをググっても原因がわからない時には、ブラウザの検証ツールを活用していくことの大切さが身にしみた経験だった。。。
[JS]フォームに入力した値を取得する

学習したことのアウトプットとして

#フォームに入力した値をJavaScriptで取得する
###FormDataオブジェクト
FormDataとは、フォームに入力された値を取得できるオブジェクトのことです。
`new FormData(フォームの要素);`のように記述することでオブジェクトを生成し、引数にフォームの要素を渡すことで、そのフォームに入力された値を取得できます。

```javascript:例
function post (){
  const submit = document.getElementById("submit");
  submit.addEventListener("click", () => {
    const form = document.getElementById("form");//フォームの要素を取得
    const formData = new FormData(form);//新たに生成したFormDataオブジェクトを変数formDataに格納している
  });
};

window.addEventListener('load', post);
```

要素の取得方法は↓
[HTMLの要素を取得する方法](https://qiita.com/Shi-raCanth/items/7ae6c1efac28668571b3)

　
コメント機能などをJavaScriputで実装したい場合などに使えそうです！


※補足等ありましたらコメント頂けると幸いです。
警告：DevTools failed to load source map の対処法

#自己紹介
現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学２年生です！
インターンや個人開発で学んだことや苦労したことを記事にしています！
よろしくお願いします🙇🏻‍♂️

#はじめに
先程コンソールにこんな警告文が

DevTools failed to load source map: Could not load content for chrome-extension://ehmajmfoaieibgpanghhnnnlfjjffhni/js/vendor.js.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME

DevTools failed to load source map: Could not load content for chrome-extension://ehmajmfoaieibgpanghhnnnlfjjffhni/js/content_script.js.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME

こんな警告文見たことがなく、解消するのにも時間がかかってしまったので、備忘録として残しておきます。

#結論
先日面白そうだと思って入れてみた拡張機能「[未来翻訳機](https://chrome.google.com/webstore/detail/%E3%81%BF%E3%82%89%E3%81%84%E7%BF%BB%E8%A8%B3/ehmajmfoaieibgpanghhnnnlfjjffhni)」をOFFにしたら直りました。
つまり「警告：DevTools failed to load source map の対処法」としては、「原因は拡張機能にあるので虱潰しにOFFにしていく」となります。

ではいい一日を😎
pyenv 初期設定

新規Macを設定する際に忘れていたのでメモ。
（諸事情で移行アシスタントやTimemachine使えない）

1 pyenv を追加

```
brew install pyenv
```

2 PYENV_ROOT 追加

```
export PYENV_ROOT="${HOME}/.pyenv"
```

3 pyenv の初期化処理を追加（profile,rcなどに)

```
eval "$(pyenv init -)"
````

4 PATHの設定（profile,rcなどに）

```
export PATH="$PYENV_ROOT/bin:$PATH"
export PATH="$PYENV_ROOT/shims:$PATH"　
```

5 profile or rc のリロード

```
source {.zshrc|.zprofile}
```
Laravel6.2で非同期処理のいいね機能を実装したときにハマったこと

#やってること
Laravel6.2を使って掲示板の実装中。今回はjQueryを使っていいね機能を実装しました。
今回は投稿・投稿に付けられるコメントにいいねをできるように実装。
白抜きの♡から赤い塗りつぶしの❤️になるようにしました。

#ここが詰まった
①コメントに対していいねを付けることができない
②ハートを押下しても赤く塗り潰されない

##やったこと(コメント編)
これは単にJavaScriptの仕様が分かっていませんでした(ﾊｽﾞｶﾁｰ)
投稿(post)のいいね機能をそのままコピペして実装したのですが、うまく実装できず。
今回は**let**を使ったのですが、違うファイルでも同じ変数宣言をするとエラーが出て登録できなくなります。

```JavaScript:ajaxcommentfavorite.js
$(function () {
  let commentfavorite = $('.favorite-toggle');
  let FavoritePostCommentid;
  commentfavorite.on('click', function () {
    let $this = $(this);
    FavoritePostCommentid = $this.data('comment-id');
~省略~
```
元々は**let favorite**だったものを、commentfavoriteに変更。
投稿(post)のいいね機能で既にfavoriteは宣言していたので、違う変数にすることで実装できました。
エラーがMySQLのエラーがずっと出ていたので数時間潰しました。

##やったこと(塗りつぶし編)
今回はfontawesomeを使ってハートを実装しました。
view

```php:detailpost.blade.php
@if (!$comment_fav->isfavoritedBy(Auth::user()))
        <span class="comment-favorites">
            <i class="far fa-heart favorite-toggle" data-comment-id="{{ $comment->id }}"></i>
          <span class="comment-favorite-counter">{{ $comment_fav->commentfavorite_count }}</span>
        </span>
      @else
        <span class="comment-favorites">
            <i class="fas fa-heart favorited favorite-toggle" data-comment-id="{{ $comment->id }}"></i>
          <span class="comment-favorite-counter">{{ $comment_fav->commentfavorite_count }}</span>
        </span>
@endif
```

favoritedクラスにCSSで色をつけて赤くするように設定しています。
これもjQueryで制御する必要があるとのこと。
ajax処理のdone部分に下記を追加します。

```JavaScript:ajaxcommentfavorite.js
.done(function (data) {
      if($this.hasClass('favorited')){
        $this.removeClass('favorited');
        $this.removeClass('fas');
        $this.addClass('far');
      }else{
        $this.addClass('favorited');
        $this.removeClass('far');
        $this.addClass('fas');
      }
      $this.next('.comment-favorite-counter').html(data.comment_favorite_count);
    })
```
removeClassで白抜きのハートのclassを削除し、塗りつぶしハートのclassを追加することでSNSでよく見るいいね機能の実装ができました。
JavaScriptの勉強はかなりサボっていたのでものすごく参考になりました！

#参考にした記事
[LaravelとjQueryで非同期処理で実装するいいね機能を世界一わかりやすく解説してみたい](https://qiita.com/kakudaisuke/items/01816910b7b9ecba0486)
とっても参考になりました…！ほぼこの記事のコピペです。

#まとめ
備忘録のためかなり分かりづらく申し訳ございません。
エラーの原因はかなりつまらなかったりする。
Dynamics 365 Finance and Operations ~ 便利機能集（ユーザ共通） ~

ユーザマニュアル作成時や、デモ紹介時にお役立てください。
初めての方にもやさしい内容となっております。

#ショートカット集
https://docs.microsoft.com/ja-jp/dynamics365/fin-ops-core/fin-ops/get-started/shortcut-keys

#個人用設定
https://docs.microsoft.com/ja-jp/dynamics365/fin-ops-core/fin-ops/get-started/personalize-user-experience

例.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/5474bd20-26e2-54bc-894d-13d1f50d894f.png)

#エクセル・ワード連携
https://docs.microsoft.com/ja-jp/dynamics365/fin-ops-core/dev-itpro/office-integration/office-integration-tutorial

例. 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/4fe617dc-31d6-abf1-7563-e7bd1a9e7c19.png)

#マニュアルの自動作成
https://docs.microsoft.com/ja-jp/dynamics365/fin-ops-core/dev-itpro/user-interface/task-recorder-training-docs

例.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/64a56620-0c8b-1b33-332f-5705f8a3bd09.png)
Raspberry Pi ヘッドレスセットアップ

## はじめに

久々にRaspberry Piをセットアップしようと公式サイトの手順を覗いたら、ヘッドレスセットアップがとても簡単になっていたのでメモ。

## やりたいこと

キーボード・マウス・モニター・LANケーブルをRaspberry Piに繋ぐことなく、OSインストール&Macからssh接続して初期設定を行う。

## 環境

- Raspberry Pi 4 4GB
- MacBook Air (M1, 2020)
    - macOS Monterey Version 12.1
    - Raspberry Pi Imager v1.7.1

## 手順

### SDカードにOSを書き込む

[Raspberry Pi Imager](https://www.raspberrypi.com/software/)をMacへインストールする。

![Screen Shot 2022-02-06 at 21.18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281326/38acebcf-5e81-d20d-2289-16fa5a53c719.png)

#### インストールの設定

- Operating System
    - 今回はRaspberry Pi OSの64bit版を選択しました。Ubuntu等も選べます。
- Strage
    - Raspberry Pi用のSDカード

最低限の設定は以上。しかしこのImagerは右下の歯車がミソ。

#### Advanced Option(歯車)

このオプションの存在によりヘッドレスセットアップが劇的に楽になる。

##### SSH有効化

これまでのように、ターミナル開いて空のsshファイル作る必要無し。

![Screen Shot 2022-02-06 at 21.29.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281326/f7db292c-784c-56ff-a7d2-7b8b92068036.png)

##### WiFi設定（とログインパスワード変更）

最初だけ有線接続したり、wpa_supplicant.conf作ったりも不要。

![Screen Shot 2022-02-06 at 21.30.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281326/0389b95d-d576-bc1d-cbf7-43eecd768885.png)

Advanced Optionを設定したら、WRITEをクリックしてOSをインストールする。

### 起動と接続

SDカードをMacから取り出し、Raspberry Piに挿入して電源繋ぐ。
１分ほど放置したら、Macのターミナルより

```
ssh pi@raspberrypi.local
```

で接続する。

### 初期設定

#### OSアップデート

ssh接続した状態で（Raspberry Piのターミナルで）
```
sudo apt update
sudo apt full-upgrade
```

#### IPアドレスの固定

デフォルトゲートウェイとDNSサーバーのIPアドレスを調べる。
Raspberry Piのターミナルで

```
route -n
```

を実行し、"Gateway"のIPアドレスを記録する。次に

```
sudo nano /etc/dhcpcd.conf
```

を実行し、設定ファイルを開く。ファイルの最下部に次のように追記し、
control + O → ファイル名変えずにEnter →　control + X
で保存する。

```
interface wlan0
static ip_address=192.168.xx.xx/24
static routers=192.168.xx.xx
static domain_name_servers=192.168.xx.xx
```

再起動

```
sudo reboot
```

おわり。
Python openしたファイルはcloseすること

放っておいてもガベージコレクションによっていずれクローズされる。
しかし明示的に閉じるのが良い習慣である。
参照
https://teratail.com/questions/217860

ガベージコレクションとは、コンピュータプログラムの実行環境などが備える機能の一つで、実行中のプログラムが占有していたメモリ領域のうち不要になったものを自動的に解放し、空き領域として再利用できるようにするもの。 そのような処理を実行するプログラムを「ガベージコレクタ」（garbage collector）という。

pythonのガーベージコレクション
https://www.sejuku.net/blog/90518