OmniAICreator/Qiita-1.07M huggingface dataset:
【3D OD Stereo】DSGN : 

<h1>DSGN: Deep Stereo Geometry Network for 3D Object Detection</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/7a52e144-b621-7335-51de-fa0843441876.png)


<h1>新規性</h1>
<h2>plane-sweep volume (PSV)</h2>
今まではCost-Volumeを作る時にDisparityを使っていたが、DepthをCost Volumeに使う事にした


<h2>3D geometric volume (3DGV)</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c8bd704c-c6ba-a14c-11d2-ce25ceb08f50.png)

図を見ると逆に混乱するかもしれないですが、ただCost-Volume(u,v,d)を3次元(x,y,z)に座標変換しただけ。車の形が変形してるので、なんか凄いことをしているのかと最初は困惑しました(T_T)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/56956252-4fcd-2879-9f45-1a26ef0a2cfe.png)

自分で図を書くと分かりやすいかもです。
*zが上ではなく前になっているのに注意


<h2>3D Object Detector on 3D Geometric Volume</h2>
3DGVで得た3次元位置を使ってFCOSとういモデルを使うそうです。
畳み込んで高さ情報をChannelに落とし込み、2次元のBEV(Bird Eye View)でObject Detectionする構成になってます。PointPillarみたいな感じですね。

<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9733f5fe-0749-71f4-46fc-fafcc282a288.png)
Pseudo LiDAR ++を圧倒してますね！！

<h1>結論</h1>
・3D Object Detectorのinputに変化したpoint cloudを入力するのでは特徴量を使う事で精度UP?
・Cost-VolumeにDisparityではなくDepthを使う事で、SmoothingのFilterがより良く働く。

<h1>参考文献</h1>
DSGN: Deep Stereo Geometry Network for 3D Object Detection
https://arxiv.org/pdf/2001.03398.pdf
セキュリティ対策についてまとめてみた

##クロスサイト・スクリプティング（XSS）
**発生箇所**：HTML,JavaScriptで生成している箇所
**種類**：反射型XSS、持続型XSS、DOM based XSS
###【対策方法】
・属性値はダブルクォート[""]で囲んで[<][''][&]をエスケープする
・HTMLで特別な意味を文字をエスケープする
・HTTPレスポンスに文字エンコーディングを明示する

###【保険的対策】
根本的対策が漏れていていた時用に保険をかけておく。
・入力値検証（入力値が英数字のみの時などに有効）
・クッキーにHttpOnly属性を付与する（クッキーの読み出しを禁止できる）
・TRACEメソッドの無効化

##SQLインジェクション
**概要**：SQLの呼び出し方に不備がある場合に発生する脆弱性。
**発生箇所**：SQL呼び出しをしている箇所
**対策**：静的プレースホルダを利用してSQLを呼びだす

###【対策方法】
・プレースホルダによりSQL文を組み立てる
・アプリケーション側でSQL文を組み立てる際に、リテラルを正しく構成するなど、SQL文が変更されないようにする

###【保険的対策】
・詳細なエラーメッセージの抑止
・入力値の妥当性検証
・データベースの権限設定

##クロスサイト・リクエストフォージェリ（CRSF、シーサフ）
概要：Webアプリケーション利用者自身が意図しない処理が実行されてしまう脆弱性または攻撃手法
発生開所・物品の購入、退会処理、書き込み、パスワードの変更など。（ログインした利用者アカウントにより取り消しできない処理の実行場所。）

###【対策方法】
・CSRF対策の必要なページを区別する
・正規利用者の意図したリクエストを区別できるよう実装する

###【保険的対策】
・重要な処理の実行後に登録済みメールアドレスに通知メールを送信する

###正規利用者の意図したリクエストを判定する方法
・秘密情報（トークン）の埋め込み
・パスワードの再入力
・Refererのチェック

##セッションハイジャック
概要：第三者がセッションIDを悪用して成りすますこと。

第三者がセッションIDを知る手段：「セッションIDの推測」「セッションIDの盗み出し」「セッションIDの強制」

##オープンリダイレクタ脆弱性
概要：利用者が知らないうちに別ドメインに遷移させられる。

###脆弱性が生まれる原因
・リダイレクト先のURLを外部から指定できる
・リダイレクト先のドメインのチェックがない
上記二つが当てはまる場合に脆弱性が生まれる。

###【対策】
・リダイレクト先のURLを固定にする
・リダイレクト先のURLを直接指定せず番号指定にする
・リダイレクト先のドメインをチェックする

##HTTPヘッダ・インジェクション
概要：リダイレクトやクッキー発行など、外部からのパラメータを元にHTTPレスポンスヘッダを出力する際に発生する脆弱性。
発生すること：任意のレスポンスヘッダの追加。レスポンスボディの偽造
影響：任意のクッキー生成、任意のURLへのリダイレクト、表示内容の改変、任意のJavaScript実行によるXSSと同様の被害

###脆弱性が生まれる原因
HTTPレスポンスヘッダはテキスト形式で1行に1つのヘッダが定義できる。この性質を利用して、リダイレクト先のURLやクッキー値として設定されるパラメータ中に改行を挿入した場合に、改行がそのままレスポンスとして出力されることが、HTTPヘッダ・インジェクション脆弱性の原因です。

###対策
・外部からのパラメータをHTTPレスポンスヘッダとして出力しない
・「リダイレクトやクッキー生成を専用APIにまかせる」＋「ヘッダ生成するパラメータの改行文字をチェックする」

##クッキー出力にまつわる脆弱性
クッキーにまつわる脆弱性は大別すると以下の２種類。
・クッキーを利用すべきでない目的でクッキーを使っている。
・クッキーの出力方法に問題がある。（「HTTPヘッダ・インジェクション脆弱性」・「クッキーのセキュア属性不備」）

###クッキーのセキュア属性不備
Secure属性を指定していない場合に発生する脆弱性。
Secure属性を指定していればHTTPS通信の場合のみブラウザからサーバーにクッキーを送る。
しかし、指定していても、平文で送信される可能性がある。

###対策
・セッションIDのクッキーにセキュア属性をつける。
・セキュア属性がつけられない時はトークンを用いる。

##メール送信の問題
メール送信時に発生する問題は3つある。
・メールヘッダ・インジェクション脆弱性
・hiddenパラメータによる宛先保持
・メールサーバーによる第三者中継

###メールヘッダ・インジェクション脆弱性
概要：メールメッセージの宛先や件名などヘッダフィールドに改行を挿入することで、新たなフィールドを追加したり、本文を改竄する攻撃手法。

###対策
・メール送信には専用のライブラリを使用する
上記を実施した上で、以下のどちらかを実施。
・外部からのパラメータをメールヘッダに含ませないようにする（sendmailコマンドを使用しない）
・外部からのパラメータには改行を含まないようにメール送信時にチェックする

###hiddenパラメータによる宛先保持
概要：hiddenパラメータの送信先アドレスを任意のアドレスに変更することにより、迷惑メールの送信に悪用される可能性がある。



##豆知識
・「出力」で発生する脆弱性はインジェクションと呼ばれる共通の原理で発生する。
AVSpeechSynthesizerを使って、textFieldの文字を読み上げる

#はじめに
この記事はLife is Tech！Members Advent Calendar 2020 の12日目の記事です。
初めて記事を書くので至らない点もあると思いますが、よろしくお願いします。

#環境
xcode12.3
swift 5.0以降
#AVSpeechSynthesizerとは
まず、今回の記事で使用するAVSpeechSynthesizerについて説明します。
[こちらのページ](https://developer.apple.com/documentation/avfoundation/avspeechsynthesizer)によると、
>テキストの発話から合成音声を生成し、進行中の音声の監視または制御を可能にするオブジェクト。

とあります。簡単にいうと、テキストを読み上げてくれるよーということですね。
#コード
```SpeechService.swift

import UIKit
import AVFoundation //①

class SpeechService {
    private let synthesizer = AVSpeechSynthesizer()
    var rate: Float = AVSpeechUtteranceDefaultSpeechRate
    var voice = AVSpeechSynthesisVoice(language: "ja_JP") //②
    
    func say(_ phrase: String) {
        let utterance = AVSpeechUtterance(string: phrase) //③
        utterance.rate = rate
        utterance.voice = voice
        utterance.pitchMultiplier = 1.0 //④

        synthesizer.speak(utterance) //⑤
    }
    
    //⑥
    func stop() {
        synthesizer.stopSpeaking(at: AVSpeechBoundary.immediate)
    }
}

```

```ViewController.swift

import UIKit
import AVFoundation //⑦

class ViewController: UIViewController{

    let speechService = SpeechService()

    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tappedSpeakButton(_ sender: Any) {
        speechService.say(textField.text!) //⑧
    }

    @IBAction func tappedStopButton(_ sender: Any) {
        speechService.stop() //⑨
    }

}


```

#コード解説
①AVFoundationをインポートしてあげてください。これによって、AVSpeechSynthesizerを使うことができます。
②言語を設定します。今回は日本語の文章を読むことを前提としているので、languageはja_JPです。英語の場合は、en_JPかen_USを入力してください。
③読み上げる文字を設定します。
④声の高さを調節します。0に近づく程、音が低くなります。
　私の場合、1.0だと少し高いと思ったので、0.8などに設定して使っています。
⑤実際に話すところです。
⑥話すのを止めます。
⑦①と同じで、AVFoundationをインポートします。
⑧ボタンをタップすると、textFieldの内容を話します。
⑨ボタンをタップすると、読み上げを停止します。
![スクリーンショット 2020-12-11 19.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934672/30327901-4bef-e5ef-cfcb-d4a8a04eef36.png)

storyboardで、textField、tappedSpeakButton、tappedStopButtonを関連付けして完成です。

#最後に
最後まで読んでいただき、ありがとうございました！
間違いだったり、わかりにくい点などありましたら、コメント欄にてご指摘ください。
kintone の　ガントチャートプラグインを使ってみる

キントーンでガントチャートを使いたかったので、まずサンプルプラグインを使ってみた。
https://developer.cybozu.io/hc/ja/articles/203716110

なにはともあれ、権利関係を確認。
* ライセンスは、MIT License
* 著作者は、Cybozu, Inc.

# kintone 準備
契約してなかったので、30日試用版を申込み。

# インストール
## パッケージをダウンロード
SAMPLE_gantt_plugin_v2.1.zip （パッケージングされたプラグイン） をダウンロード。
※ダウンロードリンクは、[ガントチャートプラグインのページ](https://developer.cybozu.io/hc/ja/articles/203716110)を参照のこと。

## kintone システムにインポート
### kintoneシステム管理メニュー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/1308828d-5a41-2b79-e9a8-de9f3e312540.png" width="300">

### プラグインメニュー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/e4faaeb0-79cb-a699-b194-f27d56a22a26.png" width="200">

### プラグインの読みこみ
#### 左上の「読み込み」より、先ほどダウンロードしたプラグインを読み込む
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/78224b96-025b-9a6f-3953-262eccdc42d3.png" width="200">

#### 読み込み後の「プラグイン」画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/0574fdda-a1b6-4547-f8f7-84249f9e966b.png" width="600">

## kintone アプリに設定
### アプリを開く
Todoを少し変えたタスク管理アプリ。タスク、開始、終了、担当を持つシンプルなもの。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/5f01c071-6b17-562f-b2e5-456f662b9bdf.png" width="400">

### アプリ設定
#### プラグインメニュー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/6e07dfed-3d5a-bc1b-5858-6ef9604696f0.png" width="400">

#### プラグインの追加
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/2407ab3e-b776-dc80-1731-ff9000f5bd7a.png" width="400">

#### プラグインが追加された
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/a653ada0-159f-64f1-95fa-d10e247970b3.png" width="500">

#### ガントチャートプラグインの設定
利用する項目を設定する。丁寧なインターフェースだ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/83ce7aba-813a-c961-e4f7-62ff7d519c85.png" width="500">

### アプリを更新
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/eec4275f-37ce-7a27-daab-11c158680de9.png" width="200">


## 表示してみる
一覧の上部に表示される。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/49142bbb-3c50-6d65-f488-3375ba79dfcf.png" width="600">

まずは今日のゴールはここまで。

## 今後いじりたい点
* ブラウザの表示を縮小すると、バーの位置がずれる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27486/7c8fcb89-f486-c062-0ef0-5c5ea5123dee.png" width="600">

* 一覧で更新すると、更新のたびにリフレッシュされ、サクサク感が損なわれる。

* そもそも、一覧の上にガントチャートが表示されるのではなく、ガントチャート専用ビューを作りたい
先輩が新人エンジニアとのコミュニケーションで気をつけるポイントたった1つ

追記：[そして前任者誰もいなくなったときのサバイバルガイド](https://qiita.com/e99h2121/items/7190085458af285893df) を書きました。こういう経験も以下を後押ししているかも...と思い起こしています。

-----
アドベントカレンダーを読んでインスパイアされることが多いです。[モチベーションクラウドさんの記事から](https://qiita.com/okadadaisuke/items/5259b89cf48de69fad0f) また自分はこうしたいというお題を発見したので書きました。[新人エンジニアが上司とのコミュニケーションで気を付けるポイント3選](https://qiita.com/okadadaisuke/items/5259b89cf48de69fad0f) との話。[アドベントカレンダーではありますまいか Advent Calendar 2020](https://qiita.com/advent-calendar/2020/mba) 13日めですぞ。

> 新人エンジニアが少し意識してコミュニケーションをとることで、回避できる箇所が多い
> 技術的に考える時間を増やすために、新人の成長角度を最大化するために、意識すべき観点3選

最初に書いておくがこの記事に書かれているようなことを新人さんが考えてくれていたら、最高です。しかし実際は初めからパーフェクトなことはないんじゃないか。同時に**先輩である側の私がまずそれに至らない**。そこで 先輩が新人エンジニアとのコミュニケーションで気をつけるポイント を考えました。

## 先輩が新人エンジニアとのコミュニケーションで気をつけるポイントたった1つ

結論、それは**「相談」**、ちょっと言い換えると

- 先輩だからこそ、新人エンジニアに相談する
- 相談して、先輩より経験のない人からこそ教えてもらう

です。また冒頭語弊があったので補足すると「実際は初めからパーフェクトなことはない」かどうかはどうでもいいんです。


## 実際に何が起きるか
見ていきましょう。実際にこのようなことが起きやすいと思っています。こちらは3選。

- 私の考える「何でも聞いてよ」との差
- アウトプット物の完成度の高さ
- 考えているのか、悩んでいるのか、悩ましい

詳細を見ていきたいと思います。

## 1. 私の考える「何でも聞いてよ」との差

私がひとにものを頼むときのイメージはだいたい単純に以下。
「このサブシステムでこういうエラーが出るトラブルが有る」 からの、丸投げ
です。

私は表面的には「マイクロマネジメント」を避ける意味で、また、最初にこのトラブルが起こっている段階で色々指図しても意味がないと思ってそうします。ではその裏の意味としてどうしてほしいのか。「わからなかったら即聞いてもらえば良い」を暗黙的に自分の中で前提事項とした上でそうしてしまうことがあります。

結果何が起こるか。

放っておいても質問は来ません。結果、なにか本当にトラブルが大きくなりそうなポイントに差し掛かった時点で「あれ？そんなところで詰まっていたの？」例えばその環境は今メンテナンス中だから使えなくて、こちらを使わないといけない、等、人に聞かないと知り得ないようなルールを新人さんが知らなかったような事態が発覚します。


## 2. アウトプット物の完成度の高さ

完成度が高くて何が悪いの？と思われてしまうと思います。違うんです。もっと未完成状態から見せてもらいたいんです。これは[新人エンジニアが上司とのコミュニケーションで気を付けるポイント3選](https://qiita.com/okadadaisuke/items/5259b89cf48de69fad0f) では

> - 先輩が自分の能力をどれぐらいと思っているかわかる
> - 自分が出そうと思ってたアウトプットより、質の高いものにチャレンジできる（大体最高の期待値は自分が考えもつかなかったようなものです）
> - 最低限守るべき箇所がわかる（ミニマムの期待値）
> 
> 期待値をすり合わせ続けていくことで、お互いの認識の齟齬がなくなっていき、自分が本当に求められているものを作っていくことが出来るようになってきました！！

が述べられています。共感します。私の場合、相手のアウトプットの、完成度が全く高いことが多いです。同時にそうではなくてもっと途中経過も見たいのです。その完成途上の段階でどうしたら状況を聞けるか、引き出さないといけないと思います。


## 3. 考えているのか、悩んでいるのか、悩ましい

考えることはとても素晴らしいことだと思います。
一方で悩んでいる状態はできるだけ短くさせてあげたいです。なぜなら先輩だから！
でも自分が上司に「悩んでる？」なんて常々聞かれたら正直逆に滅入るというか、そこまで気遣われないでいいよという気持ちになる。勝手なもんですねえ。

自分の娘・息子のことを考えてみます。彼らは公園で遊んだりするとき、ちょっと危ないことをしようとするとき、チラっと私の顔を見る。「...良い？」と確認しているのだと思います。大抵のところで「良いよ」としか言わないです。だってだいたい大丈夫だし。そういう彼らから教えてもらいます。

そうです。本人の考える力を信頼しなければならないと思います。
さり気なく「挨拶」や「リアクション」しつつ、完全に目を離してはいないよ、という安全なところで遊んでもらう。



### 補足：マクロマネジメントと「完全放置」は違う

完全に目を離すことはしない。気持ちは気にかけて、いざとなったら声をかけて、会話する。
タスクを切り分けて**「いつまでに、どんなものを、どのクオリティで出せそうか」**は **私の方から相談していく**。

小さなテクニックはありそうです。聞き方。
「これ、～～までにって言われてたりするんだけど、どうしよう？」
「まず、～～でこのエラーが本当に発生するかから確かめることできる？」
等。そうです。これって**「相談」**なんです。


## まとめ
> （僕自身そうなんですが、、、）求められると「やります！！！」って言いたくなるし、結果を残そうと思ってしまうのですが、簡単に結果が出ないことの方が多いです。
> その中で、自分ができることは早く貢献できるように成長することが大切だなと思っています。

そりゃあ、そう思っているひとが大半なはずです！ そのために「時間はかけつつも、丁寧にコミュニケーションをとって、常に考えて、技術を伸ばしていく」は、私から**「相談」**していくことで応援し、達成していきたいと思いました。

以上です！
【ESLint】error  clear  vue/comment-directiveって怒られる（その場凌ぎ）

ご無沙汰してます、おおのんです。
ワケあってnuxtのnode-module入れなおしたら、ESLintで怒られてビルドできない。
<a href="https://qiita.com/tashinoso/items/a72741ca8e2fd928ca77">[Vue] ESLintを更新すると謎のエラー clear が表示される件</a>
こちらの記事で少し解説されています。プラグイン制作者本人様も登場されています。

```:これが複数表示される
error  clear  vue/comment-directive
```

参考：<a href="https://stackoverflow.com/questions/64529114/eslint-vue-plugin-showing-false-positives-for-vue-comment-directive">ESLint Vue plugin showing false positives for vue/comment-directive</a>

```javascript:ルートディレクトリ配下の.eslintrc.js
module.exports = {
  ...省略...
  // add your custom rules here
  rules: {
    'vue/comment-directive': 0
  }
}
```

これで解決します。
その場凌ぎです。
遺伝的アルゴリズムの概要説明

#はじめに#
この記事はLinkbal_Advent_Calendar_2020の12日目の記事です。:tangerine:

この数年間、人工知能(Artificial Intelligence、略称：AI)の言葉って所々でもよく聞くはずですね。簡単に目的を言えば機械が自身で学習して自ら賢くなることも間違うわけではありません。
人工知能の週類はいくつかありますが、大学時代にちょっと調べたことがあって面白い感じがしたのは進化的計算です。
生物学から浮かばれた手法で、ある問題の最高解決策を進化や突然変異を適用して求めることです。この手法は遺伝的アルゴリズムと群知能に分類される。今日は遺伝的アルゴリズム(Genetic Algorithm、略称：GA)の概要についてザッと紹介させていただきます！:whale:

#概要#
遺伝的アルゴリズムはダーウィン(Darwin)の進化論に基づき、生物突然変異や交叉や選択などを使って最適化または検索問題に対する高品質の解決策を調べるために使用されています。
では、何が進化論に基づくか遺伝的操作がどうやって真似して取り込むかこれから以下のように簡単に説明します。

#アルゴリズムの流れと主な要因#
##流れの省略##
アプローチはいくつかあってもまとめておけばこの流れのようになります。四つあります！
-　問題の答えを暗号化する（バイナリー変換するとか置換するとか）
-　以上のソリューションを個体として初期の団体を生成する（N個体）
-　適応評価を計算して遺伝的数学を使って新しい個体を生成する
-　望みたい結果に近づかないとまた先ほど作られた個体で次世代を作り、それから繰り返す
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/f4cdd785-92a9-9d29-85cf-b76b9c0ee834.png" height="600">

##主な要因の概要##
###選択###
選択は生物の自然淘汰説を基づいて、適応度で判断して個体を増やすか削除するかの操作です。 選択のアルゴリズムはたくさんありますのでもっともわかりやすいのを紹介します。

**ルーレット選択**
ルーレット選択は個体 $i$ を選ぶ確率を $p_i$ と置いたとき、

$p_i = \frac{f_i}{\sum_{k=1}^N f_k}$　（$f_i$は個体の適応度である）

とする選択方式です。と言うと $f_i$ は個体 $i$ の適応度を表示する。見るとわかるはずなのは最も適度が高い個体は大分次世代に変遷できることです。しかし、適応度が高いことが前提になると最小値を求める問題なら使いづらいと分かられています。さらに、もしかしたら個体間の適応度の格差が激しい場合は非常に選ばれるのは適応度の高い個体なって、初期収束になってしまいます（全部同じ個体）。

**トーナメント選択**
トーナメント選択は決めた数（トーナメントサイズ）だけ集団の中からランダムで個体を取り出してその中から最も適応度の高い個体を選択する方式です。トーナメントサイズを変更すると選択圧を変更できる特徴があります。だが、サイズを大きくしたら選択圧を高めることができても初期収束による局所的な最適解に陥りやすくなってしまします。:sweat:

###交叉###
交叉は生物が交配によって子孫を残すことをモデル化したもので、個体の遺伝子の一部を入れ換える操作です。すなわち、最も重要な遺伝的操作と言うこともできます。切る数は $X$ なら $X$ 点交叉と言われます。

**一点交叉**
切れた部分を交換することです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/dbac1c40-7bd2-9739-5560-a5bb5934c9a1.png" height="300">

**二点交叉**
二つの交叉点に挟まれている部分を入れ換えるということです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/8fb0fc03-3456-44f3-ae90-8ac2da92d648.png" height="300">

###突然変異###
突然変異は生物に見られる遺伝子の突然変異をモデル化したもので、個体の遺伝子の一部を一括変化させる操作です。局所的な最適解に陥ることを防ぐ効果があるのため実装されてます。
注意すべき点は突然変異の確率は0.1%~1%です。なぜかというと、確率が低すぎると局所的な最適解に陥りやすくなりますが、高すぎるとランダム探索に近づいてしまうからです。:weary:

**元々**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/78982dd9-c956-f945-9ac2-25d698d667cd.png" height="100">

**交える突然変異**
個体の中に二つの部分を変換します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/856824b1-7b79-e47d-4ff3-0cd2d53da072.png" height="100">

**逆にする突然変異**
個体の一部の中に逆順にします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/7006ce20-294b-97d9-c028-11cc1366e7fd.png" height="100">

**変異する突然変異**
個体の一部を別の位置に変異します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539197/ea264a23-8e57-44c4-916a-9e32767abad8.png" height="100">

#終わりに#
ここでは以上ですが、よかったら次の記事で例を上げたいと思ってます。単なる概要ですが、みなさんに遺伝的アルゴリズムについての興味をもたらしますでしょうか。とっても詳しいとは言えないですので間違ったところを見つければ是非ご意見いただきたくと幸いです。:writing_hand::writing_hand::writing_hand:
Adobe Analytics API 2.0 で、任意のWorkspace table からデータを取得


Adobe Analytics API 2.0 の使い方は、このビデオで一通りわかります。
https://experienceleague.adobe.com/docs/analytics-learn/tutorials/apis/using-analysis-workspace-to-build-api-2-requests.html?lang=en#apis


具体的に、Python のプログラムに置き換える方法は以下の通り。

1. Swagger UI からCURL をコピー
2. CURL を　Python に変換　＠ https://curl.trillworks.com/ 

    response = requests.post('https://analytics.adobe.io/api/*******/reports', headers=headers, data=data)

   というコマンド終わるPython script が取り出せます。

３．上記のPython script に続けて、以下の変換できれいなデータテーブルが得られます。

j = response.json()['rows']
df = pd.DataFrame(j)
pd.concat([df['value'],df['data'].apply(pd.Series)], axis = 1)
Nextcloud 唯一の管理者アカウントが2要素認証でログインできなくなったときの対処方法

[先日の記事](https://qiita.com/S_Katz/items/6af09cf7a2fdfdc0db58)で、Nextcloud のユーザーが Google Authenticator による2要素認証ができなくなった際の対応方法について記事にしました。

「おー、助かる！　ちょうど依頼が来てたところだし、やってみるさ！」
「あれ、管理者ユーザーの Google Authenticator ってだれが設定したの？　誰も知らないってか。」
「ま、いいや。このユーザーのバックアップコードは？　え、誰も知らない？」

ちーーーーん..... orz

このようなことが起きた場合に対応方法についてまとめました。

# 対応手順をざっくりまとめ
1. [Two-Factor Admin Support](https://apps.nextcloud.com/apps/twofactor_admin) アプリをインストール。
2. `occ twofactorauth:admin:generate-code` コマンドで管理者ユーザーのワンタイムパスワードを生成。これを利用してログイン。

# もう少し詳しく
1. Nextcloud サーバーに SSH 接続。
2. 2要素認証できなくなった時のワンタイムパスワードを生成するための[Two-Factor Admin Support](https://apps.nextcloud.com/apps/twofactor_admin)をインストール、有効化。

    ```shell:WebサーバーがNginxの場合
    cd 【Nextcloud インストールディレクトリ】
    sudo -u nginx php ./occ app:install twofactor_backupcodes
    ```
3. `occ twofactorauth:admin:generate-code` コマンドで管理者ユーザーのワンタイムパスワードを生成。"Generated new one-time code for 【管理者ユーザー名】:" で表示されるワンタイムパスワードを確認。

    ```shell:WebサーバーがNginxの場合
    sudo -u nginx php ./occ twofactorauth:admin:generate-code 【管理者ユーザー名】
    ```
4. 管理者ユーザーでログイン。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/4886fb29-4ee0-20ee-092e-f45e4b4d238b.png)
5. "Admin code" をクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/37e85eb0-a61e-9e1f-b5f6-b1063155b930.png)
6. "Authentication Code" の入力欄に 3. のワンタイムパスワードを入力し "Submit" をクリック。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/85d296ed-aeef-8a90-7acc-cb829efb706b.png)

# おまけ
なんとなく想像つくかと思いますが、`twofactorauth:admin:generate-code` は管理者ユーザーだけではなく Nextcloud の全てのユーザーで使えます。なので、[先日の記事](https://qiita.com/S_Katz/items/6af09cf7a2fdfdc0db58) の対策にも使うことができます。
エンジニアが顧客へ提供したい価値を見つけるまでにやっていること

[Classi Advent Calendar 2020](https://qiita.com/advent-calendar/2020/classi) の12日目の記事を担当する @kitaharamikiya です。

昨日は、 @tetsuroito さんの、 [ベイズファクターとブリッジ・サンプリング](https://qiita.com/tetsuroito/items/67d76eaf3bffdddc0e34) でした！ ぜひ御覧ください。

今回は、顧客へ提供したい価値を見つけるまでにやっていることを書いてみました。

# 背景
### ユーザーの解決したい課題が多すぎる
- プロダクト開発と運用を行っていくと、ありがたいことにユーザーの声を聞くことができます。
- いろいろな観点で困られていることがあるのですが、何も考えずに一つ一つこなしていくと、何がしたいかわからないプロダクトになってしまいます。
- 「なんでもできるプロダクト」は「なんにもできないプロダクト」になることを痛感してます。

### ユーザーのこと理解していない
- 自分たちが実生活で使うことがないプロダクトを開発することの難しさを改めて実感しています。
- 急激に変化する世の中で、過去の経験や常識が通用しなくなっていることがあります。

### チームでできることが限られている
- ありがたいことに、とても優秀なメンバーとチームを組んで、開発することができていますが、それでも、限られた時間のなかで、1秒でも早く価値を届けるとなると、できることは限られてきます。


上記以外にも、さまざまな背景がありますが、優先的に提供したい価値を見つけるためにやっていることをいくつかご紹介いたします。

# やったこと

## ペルソナ(顧客になりうる人物・ターゲット)の仮設定
- 顧客に価値を届けたいのに、まず顧客がいないと話にならないです。
- できる限り案を出す前にやってくと、フラットな状態で検証ができると思います。
- 時間を掛けないけど、できる限り詳細に項目を出します。
- 可能であれば、実在する顧客のほうがいいかもしれません。

## ユーザー行動マップの作成
- ペルソナの行動を事細かに出します。
- 期間(時系列)と登場人物にこだわりました。
    - 期間は、どれくらいの粒度でも良いと思います。直近やったのは、1日で設定してみました。
- カスタマージャーニーマップとは用語を分けました。
    - カスタマージャーニーマップは、プロダクトに出会う前から出会ったあとのゴールを設定するイメージでいるのですが、今回は、製品の有無は関係なかったので。
- それぞれの時間ごとに、「行動」「利用しているツール」「利用方法」「思考」「感情」 を洗い出しました。

## 顧客が雇用しているジョブを洗い出す
- 行動を見ながら、顧客が雇用しているジョブを言語化します。
- できる限り多くのジョブがでると、このあとのワークの精度がより高くなるかと思います。

## 軸を設定し、プロットする
- 4象限(それ以上でもいいけど)の表を作るイメージで縦軸・横軸を設定します。
    - 軸は、YES・NOで回答できるもの、0〜10 -1〜1のように数値化できるもので考えました
    - 難しかった・・・
    - 何度も四象限の表をつくって、ジョブをプロットしては崩すを繰り返し、なんとなくしっくり来たポジショニングを見つけます。
- 右上に良い状態、左下ほどダメな状態にしておく。
- 4象限に名前をつけます。
    - メンバーの認識を揃えるためにも言語化重要だなと感じました。
- 左下から右上にするだけではなかったです。
    - 左下のジョブをなくす、右上のジョブをエンハンスするというアイデアも出ます。

## バリュープロポジションキャンバスワークでGainとPainを洗い出す
- 選択したジョブについて、バリュープロポジションキャンバスワークを行います。
- バリュープロポジションキャンバスを作ることが目的ではなく、選択したジョブGainとPain、Gain CreatorsとPain Relieversを洗い出すことに専念しました。
    
## Gain CreatorsとPain Relieversが達成できる顧客に提供したい価値の案を言語化します
- 難しい・・・
- ペルソナや、行動マップに立ち返りながら、言葉にします。

## 提供したい価値の案を検証しにいく
- 「この価値どうですか？」というオープンクエスチョンで聞くと、8割くらい「いいんじゃない？」って言われます。
- 工数を掛けずに具体化する方法で検証する
    - プロトタイピング
        - ストーリーボード
        - ペーパープロト
    - ここで、カスタマージャーニーマップを作成しても良いかも？
    - ヒアリング時に、利用時とできる限り同じ状況を作る・想像してもらう

## ダメだと思ったら捨てる
- 仮説検証をする上では、これができるかどうかがキモになることを痛感しました。
- サンクコスト効果(コンコルド効果)が一番の敵。
- これまでの作業がムダになる。ではなく、これから発生したかもしれないムダを取り除けた！と考えるようにします。

# まとめ

- あまり使わない脳みそをつかうことになるので、とても疲れます笑
- 今後、チームではLeSS(Large-Scale Scrum)・デュアルトラックアジャイルの導入を検討しています。
    - LeSS ではいかに、顧客中心で話せるか
    - デュアルトラックアジャイルのディスカバリートラックの検証を、チームでいかにムダなく回せるか。
    - こういったことも、カイゼンしながら進められればいいなと。


# あとがき
- この記事を書き始めたのが、12月12日の4時・・・
    - [毎年本当に成長しないよね・・・](https://qiita.com/kitaharamikiya/items/0f80ec54f23aa64be297#%E6%9C%80%E5%BE%8C%E3%81%AB)

明日は、 @sussan0416 です！ お楽しみに！
Raspberry Pi4 / Ubuntu 20.10 (aarch64): OpenVINO-2021.3, OpenCV-4.5.2-openvino 

# Environment
2021-03-26時点の内容。

- Raspberry Pi4 + Intel Neural Compute Stick 2 (NCS2)
- OpenVINO 2021.3
- OpenCV 4.5.2-openvino

# install Ubuntu 20.10 using Raspberry Pi Imager

Use [Raspberry Pi Imager](https://www.raspberrypi.org/software/)
![スクリーンショット 2020-12-11 6.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154910/50b9c49e-9984-ef37-bf44-4a23bf9f14da.png)

# build OpenCV 4.5.2-openvino

## source tree

```
git clone --depth 1 -b 4.5.2-openvino https://github.com/opencv/opencv.git opencv-4.5.2-openvino
```

## build

```
sudo apt install libtbb-dev libjpeg-dev libtiff-dev libwebp-dev

mkdir opencv-4.5.2-openvino/build
cd opencv-4.5.2-openvino/build

source /opt/intel/bin/setupvars.sh

cmake \
    -DCMAKE_INSTALL_PREFIX=/opt/intel/openvino/opencv \
    -DCMAKE_BUILD_TYPE=Release \
    -DWITH_INF_ENGINE=ON \
    -DENABLE_CXX11=ON \
    -DWITH_TBB=ON \
    -DPYTHON_EXECUTABLE=/usr/bin/python3.8 \
    -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.8.so \
    -DPYTHON_INCLUDE_DIR=/usr/include/python3.8 ..

make -j 4
sudo make install
```
# build OpenVINO 2021.3

## source tree

```
sudo apt install git-lfs cython3

git clone -b 2021.3 https://github.com/openvinotoolkit/openvino.git openvino-2021.3
cd openvino-2021.3
git submodule update --init --recursive
```

## build

```
cd openvino-2021.3
./install_build_dependencies.sh

mkdir build
cd build

cmake \
    -DCMAKE_INSTALL_PREFIX=/opt/intel/openvino \
    -DCMAKE_BUILD_TYPE=Release \
    -DENABLE_SSE42=OFF \
    -DTHREADING=SEQ \
    -DENABLE_GNA=OFF \
    -DENABLE_PYTHON=ON \
    -DPYTHON_EXECUTABLE=/usr/bin/python3.8 \
    -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.8.so \
    -DPYTHON_INCLUDE_DIR=/usr/include/python3.8 \
     ..

make -j 4
sudo make install

source /opt/intel/bin/setupvars.sh

sudo openvino-2021.3/scripts/install_dependencies/install_NCS_udev_rules.sh

```
patch this.

```
*** setupvars.sh.orig	2020-12-17 12:28:59.000000000 +0900
--- setupvars.sh	2020-12-17 12:29:34.000000000 +0900
***************
*** 18,23 ****
--- 18,24 ----
  BASE_DIR="$( dirname "$SCRIPT_DIR" )"
  
  INSTALLDIR="${BASE_DIR}"
+ INSTALLDIR=/opt/intel/openvino
```  

environment valiable

```
source /opt/intel/openvino/bin/setupvars.sh
export ngraph_DIR=/opt/intel/openvino/deployment_tools/ngraph/cmake
export OpenCV_DIR=/opt/intel/openvino/opencv 
export PYTHONPATH=$OpenCV_DIR/lib/python3.8/site-packages:$PYTHONPATH
```
※ お互いに依存しているので OpenCV → OpenVINO →OpenCVでビルド&インストールすること。


# Run with Intel Neural Compurte Stick 2 (NCS2)
Benchmark Raspberry pi 3B, 4B (Raspberry Pi OS 32bit), 4B (Ubuntu 20.10 64bit)
is [here](https://github.com/kose/benchmark-OpenVINO).

Using [Benchmark C++ Tool](https://docs.openvinotoolkit.org/latest/openvino_inference_engine_samples_benchmark_app_README.html).

# Reference
- [OpenVINO Toolkit Wiki](https://github.com/openvinotoolkit/openvino/wiki)
- [Run OpenVINO-2021.1, OpenCV-4.5.1-pre on M1 MacBook Air with Intel Neural Compute Stick 2](https://qiita.com/kose3/items/0585ad0696e4a00ef9a1)
Fingers Lite - Touch Gestures for Unity をとりあえず使えるようにする。

# Fingers Lite - Touch Gestures for Unity をとりあえず使えるようにする。

[Fingers - Touch Gestures for Unity](https://assetstore.unity.com/packages/tools/input-management/fingers-touch-gestures-for-unity-41076?aid=1011lGbg&utm_source=aff)
のアセットが良さそうだったが、チュートリアルドキュメントが見つからなかったのでメモを書いた。

そもそもの話として、タッチ機能の実装などは車輪の再開発になるのか？

という疑問はあるが、こちらのフル機能のFingersは画像と形状の認識があるので
今後、ジェスチャーで必殺技！みたいなことをしたい時に使いたい。
(形状認識はさすがに面倒だね)

## 買う前に Liteを使う

さて、最初に$20を出して購入するのはとても良い事だが
私の頭がこのassetを使えないかもしれない。Lite版があるのでそちらをimportして試してみよう。

[Fingers Lite - Free Finger Touch Gestures for Unity](https://assetstore.unity.com/packages/tools/input-management/fingers-lite-free-finger-touch-gestures-for-unity-64276)

動画チュートリアルは以下だ。古いが基本的な部分はさほど変わらないはずだ。
[Fingers Gestures for Unity - Complete Tutorial](https://www.youtube.com/watch?v=97tJz0y52Fw)

## デモスクリプトを確認

動画を見たあとはデモスクリプトを確認しよう

重要なのは以下の4点ほどだ。
(混乱が少ないように随時書き換えてあるので、実際のコードを確認してくれるとうれしい :) ) 


### 一番最初に実行されるコード
```c#
        private TapGestureRecognizer tapGesture;
        ...
        private void Start()
        {
            ...
            CreateTapGesture();
            ...

            FingersScript.Instance.CaptureGestureHandler = CaptureGestureHandler;
        }
```

### ジェスチャーの作成

```c#
        private void CreateTapGesture()
        {
            tapGesture = new TapGestureRecognizer();
            // デリゲートにcallbackを委譲
            tapGesture.StateUpdated += TapGestureCallback;
            // シングルタップのみを判定させるため、ダブルタップだった場合、
            // シングルタップを無視させる
            tapGesture.RequireGestureRecognizerToFail = doubleTapGesture;
            // ジェスチャーを登録
            FingersScript.Instance.AddGesture(tapGesture);
        }
```

### 実際のシングルタップの動作

```C#
        private void TapGestureCallback(GestureRecognizer gesture)
        {
            // ジェスチャーが認識されているか
            if (gesture.State == GestureRecognizerState.Ended)
            {
                Debug.Log("Tapped at " + gesture.FocusX + "," + gesture.FocusY);
            }
        }
```


### ジェスチャが有効かの判定

```C#
        private static bool? CaptureGestureHandler(GameObject obj)
        {
            if (obj.name.StartsWith("PassThrough"))
                return false;
            if (obj.name.StartsWith("NoPass"))
                return true;
            return null;
        }
```
`bool?` はnull許容値型だ。

以上の4点を書いたコードをGameObjectにアタッチすれば
タップした時の動作が確認できるはずだ。

私にしては短いが、メモ程度なのでこんなものだろう。
ロジックアナライザを試すその７：RS232 DTR

# USBからRS232のDTR（Data Terminal Ready）を確認
最近のPCでは、RS232がほとんど装着されておらず、シリアル系はUSBが使われる。USBをRS232に変換するボードやケーブルは多数存在しているが、データ以外の信号線を意識することはほとんどない。ここでは、USB経由でPC側からDTR(Data Terminal Ready)信号が制御されている（できる）ことを確認する。

## 用いたもの
ロジックアナライザはいつもと同じで[こちらを参照](https://qiita.com/infinite1oop/items/508873f660812e52f324)。USB-RS232変換は、FTDIチップを搭載する[こちらのboard](https://www.switch-science.com/catalog/1032/)を利用。PCにインストールするFTDI対応ドライバでUSB-RS232の変換を行っている。このBoardはすべてのRS232の信号線をアウトプットしないが、DTRを扱うことができる。また、ソフトウェアは定番のTeratermを利用。

## 構成
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5a5d36af-491d-4a7d-8309-d38536700568.jpeg", width=70%>
ボードのDTRをロジックアナライザのチャネル1(CH1)に接続。

## Teraterm
マクロを使って、DTR信号を制御する。マクロの詳細は[こちらを参照](https://ttssh2.osdn.jp/manual/4/ja/macro/command/index.html)。
![TeratermMacro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2ecb71cc-44e4-9936-9bdb-260a9afec195.png)
今回利用したマクロは次のようなもの。このファイルを読み込む。

```
setdtr 0
mpause 500
setdtr 1
mpause 100
setdtr 0
mpause 500
setdtr 1
mpause 100
setdtr 0
mpause 500
setdtr 1
```
DTRのOFF(setdtr 0)/ON(setdtr 1)を適当な間隔で実施。

## RS232
RS232の電圧レベルについては、[こちら](https://en.wikipedia.org/wiki/RS-232#:~:text=The%20standard%20specifies%20a%20maximum,3%20or%205%20volt%20supply.)に説明あり。乱暴に解釈すると、ONは0V、OFFは0V以外。

## 実験
DTRが接続されているチャネル1(D1)と何も接続されていないチャネル7(D7)とを表示する。
### Teratermクローズ
![TeratermNotOpen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/638d9115-9d7b-0c3e-0387-0783dac925b1.png)
Teratermクローズ時に、D1(DTR)もD7もOFF(0V以外)。

### Teratermオープン
![TeratermOpen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e2748113-9b84-fcfc-abf4-9bc22502c159.png)
Teratermをオープンすると、D1(DTR)がON(0V)となる。

### Teratermマクロ実行
![RunMacro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/46dbf87e-62e7-0562-3c41-4b1d703d2cc9.png)
さきほどのマクロを実行する。マクロの内容どおり、500msのOFF(0V以外)と100msのON(0V)との繰り返しが見える。

## 考察
成功。
ドラッグアンドドロップで別のフォルダのファイル検索

## 概要
- 手元にあるファイルをドラッグアンドドロップでして、どこかアーカイブフォルダ的なところにあるファイルを開く
- 投げ込むのはpdf、開くのはdxfなどの図面ファイル、という指定もできるように
- 複数同時投げ込みＯＫ
- 投げ込んだファイル名と検索結果がListViewに表示される

## コード 標準モジュール

``` vb

Option Explicit
Const folder = "C:\Users\***\探すフォルダ"
Const fExt = ".dxf"

Function SerchFile(Target As String) As String
  '探す
    Dim buf
    buf = Split(Target, ".")(0)
    buf = Dir(folder & "\" & buf & fExt)
    SerchFile = buf
  '開く
    Dim WSS
    Set WSS = CreateObject("WScript.Shell")
    WSS.Run folder & "\" & buf
End Function

Function OpenFile(Target As String) As String
    Dim WSS
    Set WSS = CreateObject("WScript.Shell")
    WSS.Run folder
End Function


```

## コード ユーザーフォーム

ユーザーフォームにListViewｗを配置しておく。

↓ユーザーフォーム部分はほとんどこちらから流用させていただきました。
[ドラッグ＆ドロップで指定ファイルを処理し、更にその結果を表示する。](https://infoment.hatenablog.com/entry/2019/04/29/065351)

``` vb

Option Explicit

Private Sub ListView1_OLEDragDrop(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
  ' Microsoft Scripting Runtime参照済み
  ' https://infoment.hatenablog.com/entry/2019/04/29/065351より
  Dim FSO As FileSystemObject
  Set FSO = New FileSystemObject
  
  Dim OldFileName As String
  Dim NewFileName As String
  Dim ParentFolderPath As String
    ParentFolderPath = FSO.GetParentFolderName(Data.Files(1)) & "\"
  
  Dim i As Long
    For i = 1 To Data.Files.Count
      OldFileName = FSO.GetFileName(Data.Files(i))
      With ListView1.ListItems.Add
        .Text = OldFileName
        NewFileName = SerchFile(OldFileName)
        If NewFileName <> "" Then
          .SubItems(1) = NewFileName '"正常処理終了"
        Else
          .SubItems(1) = "見つかりませんでした"
        End If
      End With
    Next
End Sub

Private Sub UserForm_Initialize()
  With ListView1
    .View = lvwReport
    .LabelEdit = lvwManual
    .HideSelection = False
    .AllowColumnReorder = True
    .FullRowSelect = True
    .Gridlines = True
    
    .ColumnHeaders.Add , "_FileName", "ファイル名", 100
    .ColumnHeaders.Add , "_Result", "結果", 100
  End With
End Sub


```
PostgreSQL の初期化ができない場合

# 本記事の内容

PostgreSQLの初期化をする際のエラーを共有し、初学者の方に役立てればと思い作成しました。


### エラーコード

```
initdb: error: directory "/usr/local/var/postgres" exists but is not empty
If you want to create a new database system, either remove or empty
the directory "/usr/local/var/postgres" or run initdb
with an argument other than "/usr/local/var/postgres".

Data page checksums are disabled.
```
### エラーコードの意味


*ディレクトリ "/usr/local/var/postgres" は存在しますが、空ではありません。
新しいデータベースシステムを作成したい場合は
ディレクトリ"/usr/local/var/postgres "を指定するか、initdbを実行します。
に"/usr/local/var/postgres "以外の引数を指定してください。*


### 解決方法

- `rm -rf /usr/local/var/postgres`を実行.
- `initdb /usr/local/var/postgres -E utf8`を実行。

```
Success. You can now start the database server using:
```
フォトビューワーみたいなのを作った話

# なんで作ったの？
画像、特に縦長の画像を分割したい。

例えば、

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/71ae8661-6a1a-a708-218d-53d5a13cb7cd.png)
（いらすとや画像）
https://www.irasutoya.com/p/terms.html


みたいな画像がある時、

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/09920277-2cce-9c0d-0a81-e5e6306f8db8.png)

と

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/2f0bf2c8-4def-a850-b07f-8a48e0320f1d.png)

に分けて表示する。

今の例では、上半身の画像を表示しているときに次の画像へ移動すると、下半身の画像になる。



# 細かいことは？

画像があまり荒く表示されるのも嫌なので、表示する高さの最低値は500。

ceil(画像の高さ / 定数) を分割数を決定する。
ここでは定数を400とした。
ここで計算した分割数が2の時は、分割数が確定する。

### 分割数が2の時

画像の高さが400~500の場合があり、高さの最低値を満たせない。
画像の高さ < 400 * 1.5の場合、分割数1の処理をする。
そうでない場合、分割数が2以上の時の処理をする。

### 分割数が1の時

高さの最低値を無視して、幅・高さそれぞれを2倍にした画像を表示。


### 分割数が2以上の時

元画像を切る長方形を仮決定する。

height_ = Math.Max(表示する高さの最低値, img.Height / 分割数)
{
　x: 0
　y: (img.Height - rect.Height) * curDivNum / (分割数 - 1)
　width: img.Width
　height: height_
}
x, y, width, heightは元画像基準である。

このプログラムのウィンドウの幅の候補 := このプログラムのウィンドウの高さ * rect.Width / rect.Heightと仮決定する。

if (このプログラムのウィンドウの幅の候補  > このプログラムのウィンドウの実際の幅)　なら、アスペクト比に気をつけながら、実際の幅に収める。

# フォルダ選択

プログラム起動時に、ピクチャディレクトリを表示。

以下のように表示。
ただし、以下ではピクチャディレクトリ直下のフォルダを表示しない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/b3ae0d20-df25-f795-b6f3-95a2d1e897bc.png)

カーソルを上に持っていくとこのようになる。
dummy 1と表示しているのは。このディレクトリのpathあら.../Picturesまでのパスを消して、'\'を' 'に置き換えて表示している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/d4dceb39-aec0-b8e5-c3ac-f4f9710417bf.png)

fugaの画像部分、もしくはテキスト部分をクリックした場合、以下のように表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/4b855e4b-4a1a-5454-c78b-78aa6dee46df.png)

カーソルを上に持っていくとこのようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/af3b0b0b-c1fa-cd79-9eff-014afb87024f.png)


hogeフォルダを開くと、このようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894099/53f2301c-9c2b-1c52-78b9-f6e152be5863.png)

(サブディレクトリの)^* サブディレクトリを表示できる。

# 表示順
同画像の分割は上から下だが、ファイルの順番は作成日時、更新日時、最終アクセスタイム、ランダムスタート（更新日時ソートの順列のランダムな位置から順番に表示）、シャッフルがある。
（”日時”は方法が分からない。知っている人がいれば教えてくれると嬉しいです）

また、逆順表示機能もある。

# トリミング
トリミングボタンを押すと、画像に割り当てられているプログラムが現在表示している画像を開く。

windows10で何もしていなければ、windowsフォトが開く。
フォーカスが戻ると、更新日時が元画像の更新日時の+900m、または-900msになる。

# bestフォルダから移動、bestフォルダに移動
"→"ボダンがあり、このボタンをbestフォルダの画像を表示している時に押すと、from_bestフォルダに送られる。
bestフォルダ以外で押すと、bestフォルダに移動。
はじめてのAWSその2 EC2のサーバを構築する

AWSでサーバ構築するための覚書です。その１で作ったVPCにEC2のサーバを作ります。

#EC2のインスタンスを起動
インスタンスを起動＝インスタンスを構築 の意味です。

###インスタンスを起動をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/a4b9cdd2-e6ae-fea5-c6c1-38486bf71bf4.png)

###Amazon Linux 2 AMI (HVM), SSD Volume Type の64bit(x86)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/3cbe2ac0-6bae-ca47-aa24-fbcf60dde264.png)

###t2.microを選択して「インスタンスの詳細の設定」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/fd24e287-5875-f5cc-7866-73a59209c03e.png)

###詳細を設定する
* ネットワーク：その１で作成したVPC
* サブネット：その１で作成したパブリックサブネット
* 自動割り当てパブリックIP：無効から有効に変える
* ネットワークインタフェースのプライマリIP：自動的に割り当てのまま
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/bd9dae41-8856-19d5-aab0-5d195595d56c.png)

###ストレージの追加
ここは変更しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/369a3410-6211-8d19-25e8-88596ac1b8fc.png)

###タグの追加
も変更なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/312dc1a3-2e06-985f-835c-99acbf74af0d.png)

###セキュリティグループ
ここも変更しない セキュリティグループはファイアウォールの意味。特定のIPアドレスしか通さない、とか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/1333cb98-ca72-0b01-485f-723b0c26c0f1.png)

###いよいよ起動！？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/2cb95fa8-2d37-eb82-dc51-908427c15018.png)

###キーペアをダウンロードしてインスタンスの作成
ここで秘密鍵を作りますが、これがないとサーバに接続できなくなるので大切に保管する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/b7edca7f-585d-7d4e-4015-2390203ba95d.png)

###インスタンスが完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/64816c98-511e-a2ea-56f3-c17941d62354.png)

###teratermで接続する
* ユーザー名は ec2-user
* パスワードは なし
* ダウンロードした秘密鍵を利用
* うまくコンソールが表示されたら成功！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/694881d2-2bed-61f4-9977-c49d0770992c.png)

#注意点
* Windowsのコマンドプロンプトからsshコマンドでつなごうとしましたがうまくいかず、teratermを入手しました https://ja.osdn.net/projects/ttssh2/releases/p
* インスタンス操作の日本語の使い方が少し独特で最初悩みました(English)
    * 起動(Lounch):インスタンスを作ること
    * 終了(Terminate):インスタンスを抹消すること
    * 開始(Start):電源ONのこと
    * 停止(Stop):電源OFFのこと
PySide2 ファイルの更新を検知する

この記事は[Takumi Akashiro ひとり Advent Calendar 2020](https://qiita.com/advent-calendar/2020/takumi_akashiro "ひとり Advent Calendar 2020")の12日目の記事です。

## 始めに
またQtネタです。今日はファイルの更新を検知します。

使うクラスは`QFileSystemWatcher`！分かりやすい名前ですね。
[QFileSystemWatcher Class | Qt Core 5.15.2](https://doc.qt.io/qt-5/qfilesystemwatcher.html)

QFileSystemWatcherインスタンスが保持しているパスのリストを監視し、変更や追加、削除があった場合にfileChangedシグナルとかに通知を飛ばします。

## じっせーん

では使っていきましょう。

```python
#!python3
# encoding:utf-8

from PySide2 import QtCore
from PySide2 import QtWidgets

class Window(QtWidgets.QListView):
    def __init__(self):
        super().__init__()
        self.model = StringListModel()
        
        self.setModel(self.model)

        self.watcher = QtCore.QFileSystemWatcher()
        self.watcher.addPath("d:/hoge.txt")
        self.watcher.fileChanged.connect(self.append_to_model)

    def append_to_model(self, path):
        self.model.append(f"changed {path} !")

class StringListModel(QtCore.QAbstractListModel ):
    def __init__(self):
        super().__init__()
        self.__data = []

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return len(self.__data)


    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return self.__data[index.row()]

    def append(self, text):
        self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
        self.__data.append(text)
        self.endInsertRows()

if __name__ == "__main__":
    app = QtWidgets.QApplication()
    window = Window()
    window.show()

    exit(app.exec_())

```

![12_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294868/b82ba952-c289-8432-aa21-6535d1b056b8.gif)

できましたね！

## 締め

これでExcelなどでゲームデータを管理していても、DCCツール側でファイル上書きを感知して、現在開いているシーンを更新できそうですね！
…まあ……やったことは無いんですが。
現在のデフォルトレイヤーを取得する方法

# やりたいこと

現在のデフォルトレイヤーが何番か知りたい

# 方法

`get_highest_layer(default_layer_state)` または古いqmk_firmwareの場合は `biton32(default_layer_state)` を使用する(実装は同じ)。以下のような感じ。

```c
enum layers {
  LAYER_PC,
  LAYER_MAC
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (biton32(default_layer_state)) {
    case LAYER_PC:
      tap_code(KC_MHEN);
      break;
    case LAYER_MAC: 
      tap_code(KC_LANG2);
      break;
    default:
      SEND_STRING("ILLEGAL STATE!");
  }
}
```

実際に動く例: https://github.com/bigwheel/qmk_firmware/blob/cbc18cf8/keyboards/ble_micro_pro/keymaps/sensible/keymap.c#L125-L129

# 参考

https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_layer.c#L52
など。
M1 MacBookにnvmをインストールする方法

#nvmのインストール#

ターミナルを以下の記事を参考に起動する（下記のコマンドを実行する）

https://qiita.com/tanaka-lapis-jp/items/2039570c8d05824665da

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
```

この際、Profile not found.と怒られた場合は以下のコマンドでProfileを作成してあげれば解決できる。

```
source ~/.nvm/nvm.sh
```

#Node.jsのインストール#

```
nvm i v14.15.1
```
上記は2020/12/12時点のLTS。nvmのバージョンは特に指定がなければ最新版のLTSを使用すると良い。（LTSとはLong Time Supportの略。長期的なサポートを保証するという意味。）

```
npm install
```

```
% npm -v
6.14.8
% node -v
v14.15.1
```

これでNodeが使えるようになりました。
データサイエンス初心者に読んで欲しい本3選

下記のようにこれまでたくさんのデータサイエンスの良書を紹介してきましたが、

- [統計初心者が統計モデリング力を鍛えるための勉強法](https://qiita.com/ueniki/items/ebdafbd123c714dabf10)
- [統計初心者が時系列分析を学ぶための勉強法・オススメ本](https://qiita.com/ueniki/items/6231cc51e8c0f9d29624)
- [統計初心者がベイズ統計学に入門するまでの勉強法](https://qiita.com/ueniki/items/d02a81766ff65bde8a0c)
- [機械学習・ディープラーニング初心者のためのおすすめ勉強順序](https://qiita.com/ueniki/items/25b08c9fc505c5876e73)

この中でも特に良書だと思った3選を紹介したいと思う。

ここでいう良書とは、
読み終わったときに地平が広がる本
です。

つまり、これまで自分が住んでいたのは日本という小さな国で、海の向こうには広大な大陸が広がっていたのだと気づかせてくれる本です。


# 1. ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

![51aFEr4SG4L._SX350_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115709/9158dcb8-cee1-c4aa-55ec-d71a88e14127.jpeg)
[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_em_r_mt_dp_hY10Fb0N8VZFD)

ディープラーニングは何？という方は必読です。
Pythonのコードを書きながら勉強していきましょうというスタンスですが、なんとなく意味さえ理解できれば十分だと思います。
ディープラーニングの得意分野である、画像認識について非常にわかりやすく書かれています。

ディープラーニングの基礎にある、ニューラルネットワークの概要と、画像認識のための工夫である「畳み込み」という技術を理解することが出来ます。

一冊でディープラーニングの基礎はマスターできます。

# 2. 詳解ディープラーニング 第2版 ~TensorFlow/Keras・PyTorchによる時系列データ処理

![51uMuKy-yKL._SX382_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115709/4b2be39a-39ad-cb14-797f-a9c6b8022f4c.jpeg)

[詳解ディープラーニング 第2版 ~TensorFlow/Keras・PyTorchによる時系列データ処理](https://www.amazon.co.jp/dp/4839969515/ref=cm_sw_em_r_mt_dp_2310FbVEAFT9Z?_encoding=UTF8&psc=1)

自然言語処理に使われているRNN（の中のLSTM、GRU）に焦点を当てた本です。
1と合わせて読むと、Deep Learninで何ができるのか、AIの何がすごいのかが、初心者が知るべき範囲ではほぼカバーできるといっても過言ではないでしょう。

アレクサくんが、なぜ人語を解するのかを理解することができるかと思います。

# 3. データ解析のための統計モデリング入門――一般化線形モデル・階層ベイズモデル・MCMC (確率と情報の科学)
![download.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115709/b9c1e992-3fcd-4d46-68a1-92d9a106423b.jpeg)

[データ解析のための統計モデリング入門――一般化線形モデル・階層ベイズモデル・MCMC (確率と情報の科学)](https://www.amazon.co.jp/dp/400006973X/ref=cm_sw_em_r_mt_dp_I-10FbTHYS8QE)


ベイズ統計学に入門する上で、この本（通称ミドリ本）以外にはありえません。

平易に楽しく統計学の世界の広がりを感じることができるでしょう。
私もこの本を読んで統計学がもっと好きになりました。
ただ数式ばかりで、堅苦しく、楽しくないと思っていた統計学が、ミドリ本に出会って一気に色付いて見えました。

この本が統計学における最大の名著の1つである（私の意見です 笑）理由は、
一般化線形モデルを通して、適切な統計モデリングとは何かという哲学的な問題に真っ向から立ち向かっている点です。
さらに素晴らしいのは、説明・回帰型の統計モデリングという題材を使いながら、なめらかに（ここがスゴい！！）ベイズ統計学にも入門させてくれる点です。


以上を読めば、データサイエンスの勉強をはじめたくなること間違いなしでしょう。
さあ、これらの素晴らしい書籍を小脇に抱え、データサイエンスの世界に入門しましょう。
ラズパイにPythonの開発環境をつくる

# はじめに
ラズパイっていいですよね...

**サイズ・価格・性能**

文句のつけようがない。
あまりにも可愛すぎて「もうメインPCラズパイでいいんじゃね？」と思った次第です。そこでラズパイ上に環境を整えるにあたり、詰まったところを備忘録としてまとめます。

*私は全くのPC初心者です。Qiita初投稿なので、書き方等間違ってる部分も多分にございます。コメントで指摘していただけると助かります。*

# 目標
- Raspberry PI で Ubuntu を使う
- Pythonが使える
 - pipenv
- ターミナルで作業が完結する
 - vim, git(github)

# RaspberryPiにUbuntuをインストール
####PCでの操作

Raspberry Pi Imager をインストール。

> https://www.raspberrypi.org/software/

Ubuntu 20.04 LTS(64bit版) をマイクロSDに書き込み。

#### ラズパイでの操作
マイクロSDをラズパイに差し込み起動。
ログイン画面が表示されので、しばらく待つ。cloud-initの完了メッセージが表示された後、ログインする。

~~~    
ユーザー名:ubuntu
パスワード:ubuntu
~~~

新しいパスワードを入力するとコマンド操作が可能になるので、アップデートしておく。

~~~
$ sudo apt update
$ sudo apt upgrade -y
~~~

Desktopigyを利用してLubuntuをインストール。

~~~
$ git clone https://github.com/wimpysworld/desktopify.git
$ cd desktopify
$ sudo ./desktopify --de lubuntu
$ sudo reboot now
~~~

> **なぜLubuntuなのか**
> Ubuntuは処理が重いし、Ubuntu Mateはちょっとダサい
> Lubuntuは軽いし、見た目もカッコイイ！


あとは普通にログイン画面が表示されるのでログインする。
地域・言語・wifiを設定しておく。

# Pythonの環境を構築する
#### Pythonのインストール
まずはpythonのバージョン確認

~~~
$ python3 --version
Python 3.8.5
~~~

2020/12/10時点では3.8.5でした。
私はtkinterが使いたかったので確認しておきます。

~~~
$ python3 -m tkinter
/usr/bin/python3: No module named tkinter
~~~

理由はイマイチわかりませんがエラーがでたので、pythonを新しくインストールします。

> https://pythonlinks.python.jp/en/index.html

ここの手順通りにコマンドを打ちます。

~~~:依存パッケージのインストール
$sudo apt update
$ sudo apt install build-essential libbz2-dev libdb-dev libreadline-dev libffi-dev libgdbm-dev liblzma-dev libncursesw5-dev libsqlite3-dev libssl-dev zlib1g-dev uuid-dev tk-dev
~~~

~~~:ダウンロードと解凍(3.x.yは書き換える)
$ wget https://www.python.org/ftp/python/3.x.y/Python-3.x.y.tar.xz
$ tar xJf Python-3.x.y.tar.xz
~~~

~~~:ビルドとインストール
$ cd Python3.x.y
$ ./configure
$ make
$ sudo make install
~~~

#### pipenvのインストール
まずはpipのインストール。ここも脳死でコマンド実行。

~~~
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ sudo python3 get-pip.py

$ pip3 install -U pip
~~~

次にpipenvのインストール。

~~~
$ pip3 install pipenv
~~~

.bashrcに追加。

~~~
$ vim ~/.bashrc
~~~

~~~:.bashrc
PIPENV_VENV_IN_PROJECT=true
~~~

これでpipenvを使用してのバージョン・パッケージ管理が可能になりました。
使い方を簡単にまとめておきます。

~~~
$ pipenv --python 3.x.y #指定したバージョンで仮想環境を構築
$ pipenv install hoge #パッケージのインストール
$ pippenv graph #インストールしたパッケージの確認
$ pipenv shell 仮想環境に入る(exitで脱出)
~~~

# ターミナルでの作業環境を整える
#### vimの最新バージョンのインストール
エディタはvim一択なので注意

~~~
$ sudo apt-get install software-properties-common
$ sudo apt-get update

$ sudo add-apt-repository ppa:jonathonf/vim
$ sudo apt update
$ sudo apt install vim
$ sudo apt install vim-gtk
~~~

#### Githubと連携する
※**セキュリティ関連の作業は他の人の記事を参考に行ってください！筆者は全くと言っていいほどわかりません！**
まず、ssh鍵を作成します。

~~~
$ mkdir ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa

$ vim id-rsa.pub
~~~

vimで公開鍵を開いたら、[V]で選択、["+y]でコピーする。
github の setting を開き, SSH and GPG keys ページ右上の NEW SSH key をクリック。
key の部分に公開鍵をペーストし Add SSH key。
接続テストとユーザー名を定義しておきます。

~~~
$ ssh -T git@github.com

$ git config --global user.name 'hoge'
$ git config --global user.email 'hoge@huga.com'
~~~

あとはgit cloneするなりしてdotfilesを引っ張ってくれば終了。

# 感想
初投稿ということで文章・構成ともに拙いものになってしまいました。
Markdown記法も初めてでしたが書きやすくて感動してます。他の人の記事を見るときには、構成やレイアウトにも注目していきたいですね！
Android11でキーボードの表示/非表示を検知する

Android11で新たに導入されたAPIの中にキーボードの表示/非表示を検知するAPIが追加されたという情報を目にし、試してみました。

調べていく中でいろいろと仕組みをしっかり理解したほうがよさそうな雰囲気を感じたのですが今回はHowに焦点を絞ってまとめます。

# 実装
実装はいたって簡単です。
### 1.まず `WindowsInset` のコールバックを有効にするための設定を行います

```kotlin:Fragment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requireActivity().window.setDecorFitsSystemWindows(false)
    }
```
[setDecorFitsSystemWindowsのAPIドキュメント](https://developer.android.com/reference/android/view/Window#setDecorFitsSystemWindows(boolean))

### 2.続いて `WindowInset` のアニメーションのコールバックをViewに設定します
どのViewに設定しても良いようなのでここではrootのviewに設定します

```kotlin:Fragment

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.setWindowInsetsAnimationCallback(object: WindowInsetsAnimation.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE) {
            override fun onProgress(
                insets: WindowInsets,
                runningAnimations: MutableList<WindowInsetsAnimation>
            ): WindowInsets {
                return insets
            }
        })
    }
```
[WindowInsetsAnimation.CallbackのAPIドキュメント](https://developer.android.com/reference/android/view/View?hl=ja#setWindowInsetsAnimationCallback(android.view.WindowInsetsAnimation.Callback))

上記は必要最低限の実装になりますがキーボードの表示を検知するには `onProgress` は向いていません。代わりに
### 3. `onEnd` をオーバーライドしてキーボードの表示/非表示アニメーション終了を検知します

```kotlin:WindowInsetsAnimation.Callback
    override fun onEnd(animation: WindowInsetsAnimation) {
        super.onEnd(animation)
        if (animation.typeMask == WindowInsets.Type.ime()) {
            val keyboardVisibility =
                view.rootWindowInsets.isVisible(WindowInsets.Type.ime())
            val message = if (keyboardVisibility) "キーボード表示" else "キーボード非表示"
            Toast.makeText(context, message, LENGTH_SHORT).show()
        }
    }
```
上記コードの結果は以下の通り
<img width="200px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149859/fc5dde34-832f-1f69-56f9-2e66decb30b7.gif"/>

# コード解説
上記実装の中の３つめの `onEnd` に関しては前提知識がないとなぜこんなコードになっているかわかりにくいと思うのでちょっとだけ解説します。
今回利用した `WindowInsetsAnimation.Callback` はおそらくキーボードの動き以外も検知するものだと思われます（ここはしっかり調査したわけではないのですが`WindowInsets.Type`がime以外にもいろいろあったためそう推測しました）
なので`animation.typeMask==WindowInsets.Type.ime()` を行いアニメーションの対象がキーボードかどうかを判定してからキーボードの表示状態をチェックしているという形になっています。

# 所感
Android11以上でしか利用できないのでまだまだこの機能に頼ることはできませんが、今までの「Viewの変化を自分で検知してキーボード表示/非表示の判定をする」に比べると格段にわかりやすくなったと思います。
ただWindowInsetsについてはもっと理解をしなければとも感じたのでこれからも学習を続けたいと思います。

# 参考・関連記事
- https://developer.android.com/about/versions/11/features?hl=ja
- https://developer.android.com/reference/android/view/View?hl=ja#setWindowInsetsAnimationCallback(android.view.WindowInsetsAnimation.Callback)
- https://developer.android.com/reference/android/view/Window#setDecorFitsSystemWindows(boolean)
- https://qiita.com/takahirom/items/c0864ad6ec2a6c013552
- https://qiita.com/HaSuzuki/items/f39e0857eaa7dcd88637
- https://github.com/android/user-interface-samples/tree/master/WindowInsetsAnimation
AWS CLI を使う

# AWS CLIをセッティング
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

- [aws cli pkg](https://awscli.amazonaws.com/AWSCLIV2.pkg)

Macならこれをダウンロードして、AWS CLIを使えるようにする

# 名前付きプロファイルを追加する

ここであらかじめ、権限を持ったIAMユーザーの
アクセスキーID、シークレットアクセスキーを控えておき、
以下のコマンドの対話の中で設定する

```shell
$ aws configure --profile testUser

AWS Access Key ID [None]: XXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

# プロファイルを指定して処理を実行

```shell
$ aws s3 ls --profile testUser
```