OmniAICreator/Qiita-1.07M huggingface dataset:
DockerでRailsアプリケーション立ち上げ〜Githubプッシュまで

学んだこと、細かい設定、エラーをメモ

# 環境
`Ruby 2.6.5`
`Rails 5.2.4`
`Docker 19.03.5`
`bundler 2.1.4`

# 実装：Docker環境

## 各ファイル用意

適当にディレクトリ作成してその中に下記のファイルを入れる

```console:ターミナル
$ mkdir hoge
```

`Dockerfile`
`docker-compose.yml`
`Gemfile`
`Gemfile.lock`

**Dockerfile**
Dockerの新しいimageを作成する際に使用する設定ファイル。
コンテナはこの設定(image)を元に作成される。
Dockerfile → クラス
コンテナ → インスタンス
みたいなイメージ？

```docker:Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```

**docker-compose.yml**
Dockerで複数のコンテナを設定に従ってまとめて起動するために使用する。
今回はRailsを実行するコンテナ、Mysqlを実行するコンテナの2つを起動する設定を記述。

```yml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:
```

```Gemfile:Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.4'
```

```Gemfile.lock:Gemfile.lock
空でOK
```

## Railsプロジェクト作成

```console:ターミナル
$ docker-compose run web rails new . --force --database=mysql
```

`docker-compose run web`
**docker-compose.yml**で設定したWebコンテナ(Railsコンテナ)の中で後に続くコマンドが実行される。

## イメージをビルド

```console:ターミナル
$ docker-compose build
```

`Dockerfile`が実行

## database.yml編集

**password**と**host**の指定

```yml:database.yml
password: docker-compose.ymlの MYSQL_ROOT_PASSWORD で設定した文字列(今回はpassword)
host: MySQLサーバーのコンテナ名(今回はdb)
```

## コンテナ起動

・起動

```console:ターミナル
$ docker-compose up -d
```

・起動確認

```console:ターミナル
$ docker-compose ps
```

**state**が**Up**になっていれば起動確認

・コンテナ、ネットワークの削除
`--rmi all`でイメージも削除

```console:ターミナル
$ docker-compose down --rmi all
```

## データベース作成

```console:ターミナル
$ docker-compose run web bundle exec rails db:create
```

## bundlerのバージョンを変更したらエラー

1系がインストールされていることに気がついたので2系にしたらエラーがでた。
[こちら](https://qiita.com/hashimoto-atsunori/items/904aa696040014fd26e3)の記事を参考に。

```Dockerfile:Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN gem install bundler # 追加
RUN bundle install
COPY . /app
```

`bundle install`の前に最新のbundlerをインストールすることで解決。

## Docker内のMySQL接続方法

```console:ターミナル
dockerで立ち上げた MySQLへの接続
$ docker-compose up -d →コンテナ起動
$ docker-compose ps →現在立ち上がってるコンテナ確認
 ↪︎ NAMEのdb名を確認(my_youtube_space_db_1)
$ docker exec -it my_youtube_space_db_1 bash → コンテナへ接続
# mysql -u root -p →シャープが表示されたら入力する
Enter password: → docker-compose.ymlで設定したパスワード入力

後はローカルのMySQLいじる時の操作と同じ 
```

# 実装：Githubへプッシュ

## Git Flow

```console:ターミナル
$ git flow init
enter * 7回
```

## リモート作成

github → Your profile → Repositories → NEW → リモート名記述 → Create repository

## リモートとローカルの紐付け

```console:ターミナル
$ git remote add origin url
$ git push -u origin master
$ git push --all
```
## .gitignore編集

```.gitignore:.gitignore
# 追記
/config/database.yml
docker-compose.yml
```

## add commit push

割愛
Flask 1.1.x でlogging.getLoggerしようとしてハマった

# 結論

appインスタンスを触れないところでログ出力するときは、
`app.logger`を一度でも参照してから、
`logging.getLogger("app")`でロガーを取得する。

# メモ

基本はこのように、`app.logger`でログ出力すればよい。

```python3:app.py
from flask import Flask

app = Flask(__name__)

app.logger.warning("This is warning message.")
# => [2020-02-21 14:35:09,642] WARNING in app: This is warning message.
```

これは普通に動く。
でも、main以外のソースからappを触りたくないので
`logging.getLogger` でロガーを取得する。
ググって出る記事を見て下のようにした。

```python3:index.py
import logging 

log = logging.getLogger("flask.app")
log.warning("This is warning message.")
# => This is warning message.
```

だめ。出力されるけどなにも整形されず、たんに`print`したのと同じ。

[1.1.xのドキュメント](https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.logger)を見ると仕様が変わっていた。
`app.name` と同じ名称でロガーが登録されるらしい。
メインのソースファイル名が`app.py`、初期化を`Flask(__name__)`としているので
`getLogger("app")`で取れるはず。

```python3:index.py
import logging 

log = logging.getLogger("app")
log.warning("This is warning message.")
# => This is warning message.
```

何故かこれもだめ。出力が整形されなかった。

いろいろいじった結果、こうすれば動いた。

```python3:app.py
from flask import Flask

app = Flask(__name__)
app.logger.warning("適当に1回ログを出しておく")
```
```python3:index.py
import logging 

log = logging.getLogger("app")
log.warning("This is warning message.")
# => [2020-02-21 14:35:09,642] WARNING in index: This is warning message.
```
Windowsでの快適なDjango開発環境構築

#### Ubuntu 18.04 LTS  をインストール
Windows app store wsl Ubuntu18.04 LTS

####環境設定

``` {
"terminal.integrated.shell.windows": "C:\\Windows\\System32\\bash.exe",
}```

### Django拡張機能のインストール
VSコードにて

#### HTML Emmetとの競合を阻止する
環境設定
``` {"emmet.includeLanguages": {"django-html": "html"}
}```
参照：https://github.com/vscode-django/vscode-django/issues/16
iOS/androidアプリのレイアウト微調整がめんどくさかった話

##はじめに

iOSアプリのレイアウト微調整、めんどくさいですね。
機種もたくさんあるし、スクショ撮ってくらべてやり直して、また撮って・・・。
おまけにモックとスクショのサイズをあわせてくらべたりね。超面倒:joy:

ってやってたんですが、もっと楽な方法がありました。

##楽な方法
シミュレータ/エミュレータと、できればzeplin等を使う。

zeplinという便利ツールでデザイナーとやりとりしてて、モックもそれなんですが、サイズがiOSシミュレータと一緒なので、リサイズも必要無し。スクショ無し。
並べて比べるのみ。
Androidはzeplinでzoom to fitして同じサイズにして使う。

[zeplin紹介記事](https://liginc.co.jp/423041)

zeplinじゃなくてもいいしね。モックの表示サイズ調整できれば良し。

##終わりに
一時期ライブラリの関係でシミュレータ向けビルドができなくなってて、すっかり使わなくなってたんですが、シミュレータをガシガシ使った方が楽だってことに気がつきました。

日英切り替えとかも２台起動しておいて、それぞれにしておいて、設定切り替え無しで確認できますしね。

もっと早く気づけば良かった:joy:

超絶に楽になりました。
人工知能、Google Coralは全行業提供智慧解法案である

AI技術は、生産ラインでの製品の量を制御するために、AIを使用して、AIの画像を介して製品の量を分析することを可能にします。 画像内で潜在的な腫瘍を識別し、それを医用にマークします。

![alt](https://blogimg.goo.ne.jp/user_image/79/f7/de8a1c7c58ea91151aec7d0e44ae6972.jpg)

さらに、データを分析するために、AIの画像を使用する企業の機器を分析するために、以前の市場では非常に少数の機器しか使用できませんでした。


Google Coral则は、こうした行程を提供する合理的な解決策です。

![alt](https://blogimg.goo.ne.jp/user_image/5c/b3/10f603a7b7e723066f3e0c73c2aaf751.jpg)

市の分析により、2020年まで、7.5の複数のAIコアチップがインテリジェントデバイスエンドに配置され、2024年までに15に延長されました。

Coralは、ローカライズされたAIを使用して製品を構築する一連の開発デバイスです。 Coralを使用すると、デバイス上のAIアプリケーションのアイデアをプロトタイプから生産まで拡張できます。 Coralシリーズのハードデバイスとコンポーネント、ソフトウェアツール、プリコンパイルモデルのプラットフォームを通じて、ローカルAIを使用して、効率的でプライベートなオフラインの人工知能製品を迅速に構築できます。

![alt](https://blogimg.goo.ne.jp/user_image/1e/8e/200e5de9f4d0e97319b65804caf409f5.jpg)


Coralシリーズのデバイスには、エッジでTensorFlow Lite MLモデルを実行するように設計されたASICチップであるエッジASICが搭載されており、低電力、高性能の機械学習推論を提供できます。

 Edge TPUは、予測メンテナンス、異常検出、マシンビジョン、ロボット工学、音声認識など、ますます多くの産業利用シナリオで使用できます。 製造、現地展開、ヘルスケア、小売、スマートスペース、輸送などのさまざまな分野で使用できます。 小型で低消費電力ですが、優れたパフォーマンスを発揮し、エッジで高精度のAIを展開できます。 Edge TPUは、エッジでAIを実行するCPU、GPU、FPGA、およびその他のASICソリューションを補完します。

Coralシリーズのデバイスは非常に柔軟です。 新興企業であろうと大企業であろうと、製品の開発と生産のニーズを満たすさまざまなサイズのハードウェア機器があります。 製品プロトタイプ開発機器には、開発ボード開発ボードとUSBアクセラレータアクセラレータが含まれ、製品生産機器には、SoMシステムモジュールとPCIeモジュールが含まれます。

![alt](https://blogimg.goo.ne.jp/user_image/1a/91/a0cc0dcc331c262b8ad196ccd2dede2f.jpg)

Google Coral Edge TPUシリーズのハードウェア製品に興味がある場合は、Google CoralエージェントのGravitylinkオンラインストア（https://store.gravitylink.com/global）にアクセスして注文してください。 企業ユーザーは、メールでの相談を通じて一括注文割引価格を取得することもできます。 （sales@gravitylink.com / market@gravitylink.com）


今すぐ製品を購入して、50以上のAIモデルを入手し、学習ツールを無料で移行してください。
『Unity C# 個人用メモ』型とか演算子

###よく使う型
```
int ・・・整数
/// -1,0,1　
```
```
flot・・・小数点以下を含む
/// fが必須　-1.5f,1.5f　
```
```
string・・・文字列
/// ""が必須　"こんにちは"
```
```
bool()・・・真偽判定
/// true(真) or false(偽)
```
```
Vector3(2)・・・座標とかベクトル
/// VectorのVは大文字なのを忘れないで！！
/// 使う時は Vector3 zahyou = new Vector3(〇,〇,〇)の様に宣言する
/// Vector2の場合なら　new Vector2(〇,〇)の様な感じ
```
```
GameObject・・・ゲームオブジェクト
/// 用途によってGameObjectとgameObjectの二つ使い分けるので気を付ける
/// 宣言するときは```private GameObject ○○ ```など
/// 使用するときは```gameObject.GetComponent<〇〇>();```など
```
```
Transform・・・トランスフォーム。オブジェクトのインスペクタ(Unity画面の右側)の上の方にある座標とか回転入力するときに使うやつ
/// 宣言するときは```private Transform ○○;```など
///使用するときは```transform.position;```など
```

###演算子
計算で使うやつ
四則演算省略
```+=```　追加(```=```が後ろ)
```-=```　差引(```=```が後ろ)
```++```　1増やす
```--```　1減らす
```=```　 代入

if分で使うやつ
```==```　同じであるとき
```!=```　同じではない時
```&&```　どちら[も]
```||```　どちら[か]
```>```　 大なり
```>=```　大なりイコール(```=```が後ろ)
```<```　 小なり
```>=```　小なりイコール(```=```が後ろ)
VBAで共有ブックの編集履歴一覧を表示する

共有ブックの編集履歴一覧をマクロで一発表示させます。

# 前置き

共有設定されているブックでは（機能をオフにしていなければ）編集履歴が記録されているので、「校閲」タブのメニューから指定して変更履歴一覧を「履歴」シートとして表示できます。
が、都度メニューから表示を指定するのが面倒になったので、マクロで一発表示させてみました。

# コード

共有設定されたブックではマクロを実行できないので、別のブックから下記を実行してやる必要があります。
※表を並び替える場合は「履歴」を表示させる前に行うこと

```vb
    With ActiveWorkbook
        '共有設定されている場合のみ実行
        If .MultiUserEditing Then
            .HighlightChangesOptions When:=xlAllChanges
            .ListChangesOnNewSheet = True
            .HighlightChangesOnScreen = False
        End If
    End With
```

# 備忘

* 「履歴」というシート名は予約語になっているので、表示させた「履歴」シートを他ブックにコピーすると「履歴 (2)」のようなシート名になります。
* テーブル機能はとても便利ですが、共有設定できなくなるので注意が必要です。
【TypeScriptの罠】親クラスのコンストラクタ内で子クラスのメソッドを実行ー＞何故か親クラスのメンバ変数の値が

TypeScriptでちょっとハマったのでメモ。

``` TypeScript:qiita.ts
abstract class Parent {
	protected hoge: string = "Parent";
	constructor() {
		this.foo();
	}
	public abstract foo();
	public bar() {
		console.log(this.hoge);
	}
}

class Child extends Parent {
	protected hoge: string = "Child";
	constructor() {
		super();
	}
	public foo() {
		console.log(this.hoge);
	}

}

const child: Parent = new Child(); // Parent
child.foo();// Child
child.bar();// Child
```

上記のコードだとC#やJavaの感覚では、
Childが3回出力されるものだと勘違いしてあせった。
想定した出力（実際、JavaやC#で似たようなことをするとこのように出力される）

```
Child
Child
Child
```

実際の出力は

```
Parent
Child
Child
```
になる

これを把握せずにこんなコードを書くと・・・

``` TypeScript:qiita.ts
abstract class Parent {
	protected hoge: string = "Parent";
	protected speech: string = "";
	constructor() {
		this.init();
	}
	public abstract init();
	public bar() {
		console.log(this.hoge);
	}
	getSpeech() {
		return this.speech;
	}
}

class Child extends Parent {
	protected hoge: string = "Child";
	constructor() {
		super();
	}
	public init() {
		this.speech = `私の名前は${this.hoge}です。`
	}
}

const child: Parent = new Child();
console.log(child.getSpeech());

```

出力結果

```
私の名前はParentです。
```
となってちょっと悩みました。

期待した出力

```
私の名前はChildです。
```

## なぜそうなるか

TypeScriptではC#やJavaのようにクラスにメンバ変数を直接書くことができる。
が、JavaScriptではそのような書き方はできず、コンストラクタ内で定義することになる。

エラーになるコード

``` Javascript
//JavaScript
class Hoge{
 foo="a"
}
```
正しいJavaScript

```Javascript
//JavaScript
class Hoge{
 constructor(){
  this.foo="a"
 }
}
```

なのでTypeScriptの以下のコードはビルドされると

``` TypeScript
//TypeScript
class Hoge{
 foo="a"
}
```
このようなJavaScriptを吐き出します。

``` JavaScript
//JavaScript
class Hoge {
    constructor() {
        this.foo = "a";
    }
}
```

つまり先程のよくわからない挙動をしていたTypeScriptは以下のようなJavaScriptになるためにC#やJavaに慣れ親しんだ人にとっては意図しない挙動になったということでした。
子クラスのメンバ変数に値が定義される前に親クラスのコンストラクタが実行されていることがわかります。
メンバ変数の定義がsuper()のあとに入れられてしまうという仕様のせいでした。

``` JavaScript
//TSCでコンパイルされたJavaScript
class Parent {
    constructor() {
        this.hoge = "Parent";
        this.speech = "";
        this.init();
    }
    bar() {
        console.log(this.hoge);
    }
    getSpeech() {
        return this.speech;
    }
}
class Child extends Parent {
    constructor() {
        super();//<-ここに注目
        this.hoge = "Child";///<-ここに注目
    }
    init() {
        this.speech = `私の名前は${this.hoge}です。`;
    }
}
const child = new Child();
console.log(child.getSpeech());
```
【Rails】SwitchPoint利用時にSchemaCacheを設定しSHOW FULL FIELDSを防ぐ

# SwitchPointとは？
https://github.com/eagletmt/switch_point
DBの書き込み接続と読み込み接続を切り替えることができるgemです。

# SchemaCacheについて
Railsでは`rake db:schema:cache:dump`を使うことで`db/schema_cache.yml`にテーブルやカラムの情報が書き出されます。
このキャッシュを使うことでActiveRecordが型情報などを特定する手助けになします。

# SwitchPointによりSchemaCacheが使えなくなる
SwitchPointを使うと`ActiveRecord::Base`とは別のConnectionPoolを保持してしまうため、SchemaCacheが自動で読み込まれません。
これによる、SQL実行時に`SHOW FULL FIELDS FROM some_table`が実行され不要な遅延を発生させてしまいます。

## 対策
```config/initializers/switch_point.rb
ActiveSupport.on_load(:after_initialize) do
  ApplicationRecord.switch_point_proxy.connection.pool.schema_cache = ActiveRecord::Base.connection.schema_cache
  ApplicationRecord.switch_point_proxy.connection.schema_cache = ActiveRecord::Base.connection.schema_cache
end
```

initializer内で`switch_point_proxy`のもつConnectionPoolに`ActiveRecord::Base`と同様のschema_cacheを設定してあげることで対策できます。

※ただしこのコールバックより適当な実行タイミングがあるかは未確認
[Rails] 2つのテーブルをjoinsで結合したときのwhereのRailsライクな書き方

## きっかけ
2つのテーブルをjoinsで結合した際に、結合した側のテーブルのカラムを使用して
whereで絞り込みをする際に、どうしてもwhereの中でSQLライクな書き方をしていました。

それをRailsライクな書き方で書く方法を見つけたので残しておきます。

## 前提
以下のような関連があったとします。

```rb
Author has_many Book(s)
Book belongs_to Author
```

あるAuthorが複数のBookを持っている、という状況です。
これらのテーブルは、主に以下のようなカラムを持ち合わせています。

```rb
Author
 - id
 - name

Books
 - id
 - name
 - author_id
```

idとnameという同じ名前のカラムがあります。

## 本題

```rb
   Author.joins(:books)
```

とすれば、SQLのINNER JOINが実行されるので
`author.id`と`book.author_id`が等しい、つまり
`author.id == book.author_id`となるようなレコードが抽出されます。
ということは、`book.author_id == nil`のレコードはこの時点で弾かれます。

ではここで、Bookのnameに対してwhereを使って絞り込みを行いたいと思います。

## SQLライクな書き方
その際、自分はいつもこのようなSQLライクな書き方をしていました。

```rb
   Author.joins(:books).where("books.name": "XXXXX")
```

これをRailsライクな書き方で書こう、ということです。

## Railsライクな書き方
以下のようにネストするだけです。

```rb
   Author.joins(:books).where(books: { name: "XXXXX" } )
```

これで上記SQLライクの場合と同じように調べられます。
ぱっと見、わかりやすくなったなと個人的には思っています。


<br>
おわり
AWS CLI スイッチロール設定

### Linux 環境で config を編集

config の確認

```
$ cat ~/.aws/config
[default]
region = ap-northeast-1
output = json
```

上記 config にスイッチロールを追記

```shell
# エディタを起動し config を編集
$ vi ~/.aws/config
```

エディタ起動時はコマンドモード
`i` でカーソル位置から文字の入力が可能（インサートモード）となる

```
[default]
region = ap-northeast-1
output = json

[profile 【スイッチロールするプロファイル名】]
role_arn = arn:aws:iam::【スイッチロールするアカウント】:role/【スイッチロール名】
source_profile = default
```

編集後は `Esc` でコマンドモードへ戻り、`:wq` で上書き保存
保存せずに終了する場合は `:q`
強制終了は `:q!`

```shell
# スイッチロールで aws cli を利用
$ aws 【実行するコマンド等】 --profile 【スイッチロールするプロファイル名】
```

### スイッチロールをデフォルトにしたい場合は credentials を編集

credentials の確認

```
$ cat ~/.aws/credentials
[default]
aws_access_key_id = ZZZZZZZZZZZZZZZZZZZZ
aws_secret_access_key = 9999999999999999999999999999999999999999
```

エディタを起動し credentials を編集

```
$ vi ~/.aws/credentials
```
デフォルトの `aws_access_key_id`, `aws_secret_access_key` に `default` 以外のプロファイルを命名
`[default]` の `role_arn` にスイッチロールを、`source_profile` にデフォルトのプロファイル名をそれぞれ記載する

```
[【デフォルトのプロファイル名】]
aws_access_key_id = ZZZZZZZZZZZZZZZZZZZZ
aws_secret_access_key = 9999999999999999999999999999999999999999

[default]
role_arn = arn:aws:iam::【スイッチロールするアカウント】:role/【スイッチロール名】
source_profile =【デフォルトのプロファイル名】
```

### 現在使用しているプロファイルの確認

```shell
$ aws sts get-caller-identity
{
    "UserId": "XXXXXXXXXXXXXXXXXXXXX",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/【ユーザ名】"
}
```
### シェルスクリプトで sts assume-role を利用
```shell
AWS_STS_CREDENTIALS=`aws sts assume-role \
  --role-arn arn:aws:iam::000000000000:role/【ロール名】\
  --role-session-name【スイッチロールセッション中の名前】\
  --duration-seconds【スイッチロールセッション時間 900秒(15分)～最大はIAMの設定次第】`

AWS_ACCESS_KEY_ID=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.AccessKeyId'`
AWS_SECRET_ACCESS_KEY=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SecretAccessKey'`
AWS_SESSION_TOKEN=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SessionToken'`

export AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY
export AWS_SESSION_TOKEN

【スイッチロール中に実行したいコマンド等】

unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
```

【参考】
https://dev.classmethod.jp/etc/cli-switch-role/
https://dev.classmethod.jp/cloud/aws/get-aws-account-id-with-get-caller-identity/
https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role.html
１フォルダの中のライフカードの明細PDFを一気にパスワード解除する

## 前提条件
* ファイル名```lifecard_meisai_201905.pdf```のような形である。
* １つのディレクトリ（フォルダ）に入っている。
* パスワード解除したものは同一ディレクトリに```nopass_lifecard_meisai_201905.pdf```の形で保存されるでOK
* qpdfがインストールされている。（brewなどで入れておく）

##使い方
* パスワードは```<PASS>```としてあるので書き換えて使う。

```sh
for FILENAME in lifecard_meisai_*.pdf;do
qpdf --decrypt --password=<PASS> $FILENAME nopass_${FILENAME}
done
```
【Nuxt.js】iOSっぽい画面遷移をする

こういうやつやります。
![nuxt-ios.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/97d7c13d-01d2-95dd-3882-956685b7f64c.gif)
# スタイル
## 共通スタイルの設置
公式：https://ja.nuxtjs.org/api/configuration-css/

nuxt.config.jsにファイルを追加。

```javascript:nuxt.config.js
  css: [
    { src: '~/assets/styles/transition.scss', lang: 'scss' },
  ],
```

## スタイル例
公式：https://ja.nuxtjs.org/api/pages-transition/

ゆくページと来るページの遷移前・中・後スタイルをそれぞれ指定。今回は「戻る」「進む」の2パターンあるので2*3*2=12のクラスが必要です。
コメント部分は今回不要ですが、混乱しがちなので補助として書いています。

```scss:transition.scss
.next-enter-active,
.next-leave-active,
.prev-enter-active,
.prev-leave-active {
  position: absolute;
  transition: all .3s;
}

.next-enter {
  transform: translateX(100vw);
}

.next-enter-to {
  // transform: translateX(0);
}

.next-leave {
  // transform: translateX(0);
}

.next-leave-to {
  transform: translateX(-50vw) scaleX(0.5);
  filter: brightness(0.5);
}

.prev-enter {
  transform: translateX(-50vw) scaleX(0.5);
  filter: brightness(0.5);
}

.prev-enter-to {
  // transform: translateX(0);
}

.prev-leave {
  // transform: translateX(0);
  z-index: 1;
}

.prev-leave-to {
  z-index: 1;
  transform: translateX(100vw);
}
```

# コンポーネント毎にアニメーションを設定
アニメーションを適用したい各コンポーネントにtransitionを指定。

```javascript
export default {
  transition (to, from) {
    // [1] 遷移元の階層によってページめくり方向を指定
    if (from && to.path.startsWith(from.path)) {
      // [2] オブジェクトで設定する
      return {
        name: 'next',
        mode: '',
      }
    } else {
      return {
        name: 'prev',
        mode: '',
      }
    }
  },
}
```

[1] 遷移元の階層によってページめくり方向を指定する
transition設定には関数が利用できます。
引数からパスがとれるので比較し、より深い階層からの遷移のみ「戻る」アニメーションになるようにしました。

[2] オブジェクトで設定する
設定オブジェクトを返してトランジション設定を行います。今回はnameとmodeを指定します。

*  **name** はトランジションの名前。
 * これが接頭辞となってページにクラスが適用されます。
*  **mode** はトランジションのモード。
 * デフォルトでは`out-in`、つまりゆくページの消滅と来るページの出現が順番にアニメーションします。
今回は同時に動かしたいので、空文字を返します。これはそういうルールです。

※補足：ページ遷移アニメーションは、遷移 **先** のコンポーネントの設定が参照されます。遷移 **元** ページの消えるアニメーションも、遷移 **先** の設定を参照します。

# 終わり
僕からは以上です。
え、本当に終わりか、ですって？本当ですよ！Nuxt.jsはすごいですね。
DDBJのスパコンにPerlのモジュールインストールしたかったけど途中で詰まった

### DDBJのスパコンでPerlのモジュールをインストールしたい
cpanを使おうと思ったらroot権限が必要とのことでインストール失敗した  
  
`sudo cpan`でリトライ

```
 [hoge]$ sudo cpan

あなたはシステム管理者から通常の講習を受けたはずです。
これは通常、以下の3点に要約されます:

    #1) 他人のプライバシーを尊重すること。
    #2) タイプする前に考えること。
    #3) 大いなる力には大いなる責任が伴うこと。
```
めちゃくちゃ怒られた。  
  
### cpanmを使えばローカル環境でモジュールがインストールできる  
ググっていたら以下のサイトにたどり着いた
https://kantaro-cgi.com/blog/perl/install-cpanm.html
これを参考に、サーバー上に以下のコマンドを入力
  
```
mkdir ~/bin
cd ~/bin
curl -L https://cpanmin.us/ -o cpanm
chmod +x cpanm
```

`$ vi .bashrc`で以下を記入


```
export PERL_CPANM_OPT="--local-lib=~/perl5"
export PATH=~/perl5/bin:$PATH;
export PERL5LIB=~/perl5/lib/perl5:$PERL5LIB;
export PATH=/usr/bin:$PATH;
```
アクティベート
`$ source .bashrc`



`cpanm hoge`でモジュールがインストールできるようになった！
と思ったが`DBD::Pg`　だけうまく行かない。


```
[hoge]$ cpanm DBD::Pg
--> Working on DBD::Pg
Fetching http://www.cpan.org/authors/id/T/TU/TURNSTEP/DBD-Pg-3.10.4.tar.gz ... OK
Configuring DBD-Pg-3.10.4 ... N/A
! Configure failed for DBD-Pg-3.10.4. See /home/ahosakanig/.cpanm/work/1582265437.43646/build.log for details.
```
**詰まった。**
【R ggplot2】データに複素数が入ってるとエラーするよ

# 解決方法

ggplotで描くグラフに複素数が入っていたらエラーするよって話です。

```
> ggplot(data = result_stft, mapping = (x = time, y = frequency, z = amplitude)) +
    geom_tile(aes(fill = amplitude))
Don't know how to automatically pick scale for object of type complex. Defaulting to continuous.
```

こんな感じで返ってきます。

短時間フーリエ変換をするのに`fft()`を使っていたのですが、

`fft()`の結果が`abs()`で処理しないと複素数のままであることを忘れていました。

`Don't know how to automatically pick scale for object of type complex. Defaulting to continuous.`

↑これが返ってきたら、複素数がデータに入っていないか確認しましょう。

object of type complexって書いてあるしね。

メモ程度に残しておきます。

## 参考文献
- [Rでbode線図を描いている事例を見つけました](https://niszet.hatenablog.com/?page=1499512189)

虚数部の描き方について少し触れてくれています。
『Unity C# 個人用メモ』 ガチ初心者の自分用の用語メモ

初心者の自分用のメモ
大体こんな感じだよって思ってればいいやつ


###MonoBehaviour(モノビヘイビア)
全てのスクリプトから派生するベースクラス

###ヒエラルキービュー
画面左。シーンビューに配置したオブジェクトの一覧、階層構造。

###プロジェクトビュー
画面下。ゲームで使う素材を管理。

###インスペクタ
画面右。選択しているオブジェクトの詳しい情報がわかる。 座標・オブジェクトの大きさ・配置など。

###メソッド
```
void Start()
{

}
```
メソッドとはこのvoid 〇〇のこと。上の物であればStart()がメソッドになる

アクセス修飾子
```
public　int = 1;
private int = 1;
```
アクセス修飾子とはこのpublicやprivateのこと

###変数・型
```
int a ;
```
int ←　型
a 　←　変数
intという型のaという変数を作るという意味になる

###引数(ひきすう)
```
Vector3 zahyou = new Vector3(〇,〇,〇);
```
new Vector3(〇,〇,〇);〇のことなど
初めてのLinearRegressionモデル作成２

#重回帰をしてモデル精度を上げる！
**重回帰**とは...説明変数が2個以上あるもの（今回は、**ピザの直径**と**トッピング数**を説明変数とする）

#モデル作成の基本4選
①リスト型の学習データを用意（説明変数、目的変数）
②モデル指定（誰にやってもらう？）
③学習（何を学ばせる？...①で作った学習データを学ばせる）
④リスト型のテストデータを用意（説明変数、目的変数）
⑤予測（④の説明変数を引数にして、目的変数との差を比べる）

```python
from sklearn.linear_model import LinearRegression

#①リスト型の学習データを用意（説明変数、目的変数）
x = [[12,2],[16,1],[20,0],[28,2],[36,0]]#[直径,トッピング数]
y = [[700],[900],[1300],[1750],[1800]]#[値段]

#②モデル指定(誰にやってもらう？)
model = LinearRegression()

#③学習（何を学ばせる？...①で作った学習データを学ばせる）
model.fit(x,y)#学習（何を学ばせる？）

#④リスト型のテストデータを用意（説明変数、目的変数）
x_test = [[16,2],[18,0],[22,2],[32,2],[24,0]]
y_test = [[1100],[850],[1500],[1800],[1100]]

#⑤予測（④の説明変数を引数にして、目的変数との差を比べる）
prices = model.predict(x_test)

for i, price in enumerate(prices):
    print('Predicted:%s, Target:%s'%(price,y_test[i]))

score = model.score(x_test,y_test)
print("r-squared:",score)
```

```出力.
Predicted:[1006.25], Target:[1100]
Predicted:[1028.125], Target:[850]
Predicted:[1309.375], Target:[1500]
Predicted:[1814.58333333], Target:[1800]
Predicted:[1331.25], Target:[1100]
r-squared: 0.7701677731318467
```

#結果
精度が **0.662005292942→0.7701677731318467**と少し上がった！
**重回帰**をすれば単回帰よりもモデル精度が上がることが直感的にも理解できた！
[Tips]俺のPandasノート

# はじめに
Pandasの操作をすぐ忘れてしまうのでメモを残します。自分が操作しようと思って調べたやつをどんどん追記するスタイルなので、記載内容には偏りがありますがご了承ください。

下記のようにimportされている前提です。

```python
import pandas as pd
```
# 表示系
## Jupyter notebookで列が省略されるのを回避する
max_columnsの値を大きめに設定する

```python
pd.set_option('display.max_columns', 100)
```
# ファイル操作関連
## csvのインポート
```python

data = pd.read_csv('filename.csv', parse_dates=['timestamp'])
```
parse_datesでdatetime型として読み込める

## csvへエクスポート
```python

data = pd.to_csv('filename.csv', index=False, sep='\t')
# index: 表示の有無
# sep: セパレータの指定
```

# 値の操作
## 同じ値が続く間は同じ連番とする操作

```python
df = pd.DataFrame(['a', 'a', 'b', 'b', 'c','c','c', 'd', 'e'])
df['idx'],_ = pd.factorize(df[0])
print(df)
   0  idx
0  a    0
1  a    0
2  b    1
3  b    1
4  c    2
5  c    2
6  c    2
7  d    3
8  e    4
```

## マルチインデックスのデータアクセス
```python
diff_df.loc['A', 'B'] # A=level1 B=level2
```

## テーブル同士のジョイン
on引数でキーを指定する。howでジョインの方法を選択する。

```python
pd.merge(a, b, on=['first_key', 'second_key'], how='left')
```
M5StickC UiFLOWのブロックプログラミングで倒立振子

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/8cb76bc4-b61f-93d9-c7a7-71fd76ec50e1.png)

##■はじめに
###以前 [実質500円&100Stepで作る超簡単「 ゆるメカトロ的 M5StickC 倒立振子」](https://qiita.com/Google_Homer/items/d0cdb2975491a5ea8129) という記事を書きました。この時はArduino IDEでやっていたのですが、今回のはこれをブロックプログラムのUiFLOWに焼き直したものです。

##■動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/M5StickC?src=hash&amp;ref_src=twsrc%5Etfw">#M5StickC</a> <a href="https://twitter.com/hashtag/UiFLOW?src=hash&amp;ref_src=twsrc%5Etfw">#UiFLOW</a> <br>ブロックプログラミングによる倒立振子。Arduino IDE版と比べ持続時間短いが、なんとか安定してきた。そろそろQiitaに放流しようかな。 <a href="https://t.co/Kb0vxiF4oj">pic.twitter.com/Kb0vxiF4oj</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1230697006835748866?ref_src=twsrc%5Etfw">February 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##■車体
##車体の構成は何も変更していないので、組み立て方は下記の以前の記事を見て下さい。
[実質500円&100Stepで作る超簡単「 ゆるメカトロ的 M5StickC 倒立振子」](https://qiita.com/Google_Homer/items/d0cdb2975491a5ea8129)

##■プログラム
UiFLOWのブロックプログラムのシェア方法がわからなかったので、とりあえずGoogle Driveに上げてみました。アクセスできない場合は連絡下さい。
ブロックプログラムを下記からダウンロードして、UiFLOWで読み込んで下さい。
[BalanceCar2.m5f](https://drive.google.com/open?id=1YL99y3_QHDv8Jj8rAWeGnWHufQhB3yFT)

##■とりあえずスクショも張っておきます
**UiFLOWにatan2のブロックが見当たらなかったので、ちょこっとだけPythonコードはいってます。また、加速度&ジャイロブロックのScale設定が不明だったので、とりあえず±250dpsとして扱いました。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/e91f68a0-8dfc-a9cf-b3a8-74044d63dd4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/ce2e1020-c505-73c3-d1a6-9e6203730c51.png)

##■調整方法
本記事冒頭で触れた以前の記事を参考に、ブロック先頭の下記の4つを調整して下さい。
同じ車体なのに、なぜか調整値は大きく異なっています。あいかわらず細かい事は理解できていません。あしからず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/a32f0bbf-ffea-e9e0-e4f5-332aae868f3c.png)

##■最後に
###今回衝動的にブロックプログラムでやってみましたが、処理スピードの関係なのかArduino IDE版の方が安定しているという印象です。また、計算が主体なのでブロックよりもコードの方が各段にプログラムしやすいです。でも、処理速度ベンチマーク及びネタとしてやってみたかった。ブロックでも倒立振子できるというのはカルチャーショック(古っ)でした。
正しいWindows Server 2016への.NET Framework 3.5のインストール方法

#なんでこのような記事を書くのか
.NET FrameworkとWindows Server OSの対応関係はMSのドキュメント(https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/versions-and-dependencies) に整理されていて、そこによると.NET Framework 3.5をWindows Server 2016にインストールすることは可能であると書いてある。
でも、機能追加を行おうとすると失敗してしまうので対応法を調べてみたのだが、個人のブログやフォーラムでのやりとりばかりが検索に引っかかってしまい、MSの推奨する方法がなかなか見つからなかった。
個人で管理しているサーバーならどのような方法で機能を追加してもいいのだが、企業で管理するサーバーの場合、公式な裏付けがない手法を用いて機能の有効化を行うことにためらいを感じる人が多いと思い、公式ページのリンクを参照しながら、機能の有効化の方法を確認していく。
つまりタイトルの「正しい」というのは、MSを参照しているという意味であり、実行する内容はブログやフォーラムに書かれている内容が間違っているわけではないので誤解なきようお願いします。

#現象の確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/756af759-2c89-ddbe-7602-02370f5df8e9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/08e828ca-f349-3ef0-b3aa-c1ea287aca61.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/6b45e164-2a3c-7a0f-43f9-be2610c3f442.png)


#MSの見解
https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/microsoft-net-framework-35-deployment-considerations
リンク先をあえて英語のサイトにしているのは、日本語サイトだと感じな参照パスの部分が不要に日本語化されてしまっていて意味がとりにくいからで、人に説明するときなどは日本語サイトでもいいかもしれません。
日本語、英語両方で確認して納得することが大事だと思います。

#実際の手順
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/94221146-0dc0-40c1-3334-394cb0411a75.png)

Dドライブの部分は、インストールメディアが入っているドライブを指定する。

#注意点
Windows Server 2019の場合にも、ここに示したのと同様の手順で.NET Framework 3.5をインストールできるというブログが確認できたので、実際インストールすることはできるのだと思う。
しかしこの記事で想定している読者は、企業などのサーバーにインストールする説明責任のある人物なので、MSのサイトにインストール可能と書かれていないWindows Server 2019に関してはインストールはしないことを勧めたい。
もし、MSがWindows Server 2019に対しての.NET Framework 3.5のインストールを保証しているようであれば、参考サイトなどを教えていただきたいと思います。
バッチファイルからPowerShellを実行する方法

## バッチファイルからPowerShellを実行する方法

Windows のコマンド手順をバッチファイルによる自動化する際に、
バッチファイル(コマンドプロンプト)でできることは限られるため、
部分的に他の技術に頼らざるを得ない場合があります。

ここでは、バッチファイルに記載のコマンドから変数等を渡して
PowerShell で実行する方法を紹介します。

```hoge.bat
rem ::: PowerShell一時スクリプトファイルパス定義 :::
set PS_FILEPATH=%TEMP%\hoge.ps1

rem :::: PowerShell一時スクリプトファイル作成 ::::
echo. >%PS_FILEPATH%

rem :::: PowerShellコマンド ::::
echo (PowerShellコマンド1) >>%PS_FILEPATH%
echo (PowerShellコマンド2) >>%PS_FILEPATH%
echo (PowerShellコマンド3) >>%PS_FILEPATH%

rem :::: PowerShell一時スクリプトファイル実行 ::::
powershell -NoProfile -ExecutionPolicy Unrestricted %PS_FILEPATH%

rem :::: PowerShell一時スクリプトファイル削除 ::::
del /q %PS_FILEPATH%
```

上記では具体的なPowerShellコマンドは記載しませんでしたが、
**(PowerShellコマンド?)**部分にも**変数**(%　～　%)を使用することが
可能です。

参考文献　[コマンドプロンプトから PowerShell を実行する](https://qiita.com/ww24/items/7d52df13fef5bc54e149)
プログラミングスクール（転職保証有）の説明を何箇所かで伺った感想まとめ（かなり雑）

自分は有料（転職成功で返金）スクールでRuby及びRailsを勉強しています。

スクールを選ぶ際に何箇所かでお話を伺ったので、その時の有料スクール（転職保証付）と無料スクール（転職保証付）の印象、比較をを自分の推測を交えてまとめました。（~~勉強の息抜きで書いてるのでかなり雑です~~随時追記していきます。)
ちゃんと根拠を含めた解説はもう探せばゴロゴロ出てきますので、本記事はあくまで初心者目線で話を伺った感想になります。

ちなみに予めネタバレをすると、結局有料か無料かの大きな違いは言語によるものだと思いました。質とかは正直実際に受講しないとわからないので触れていません。

じゃあ何について書いているかというと、「**どうしてその言語を勉強するのか？**」という点を重視して書きました。

スクールを選ばれる際にちょっとでも参考になれば嬉しいです。
## スクールを考える前に絶対やっておいた方がいいと思った言語（web系目指している人は絶対）
- HTML
- CSS
- Javascript

避けては通れない言語だと思います。なぜならサイトはこれらで構成されているようなものだから。
サイトのしくみを知っていれば当たり前なんだよなぁ！！自分は知らなかったけど。
ただ、HTMLとCSSは本当に取り掛かるにあたってとても優しい部類（プログラミングの結果がわかりやすい）なので、とりあえずこの二つを勉強して（余裕ならJavascriptも）、それから判断された方が良いかと。


## 有料のスクールはRuby
どのプログラミングスクールでも勉強すると言われたのは**Ruby**。
大体「現在人気の〜」と説明を受けていたけど、おそらく即戦力として勉強をするから。
そして並行して学ぶのがフレームワークの**Ruby on Rails**。Rubyから始めるスクールでRailsを学ばないという場所はなかったと思う。
つまり、**web系に特化したスクールが多い**という印象でした。

## 無料のスクールはPHP、またはJAVA
一方、無料プログラミングスクールで多かったのは**PHP**と**JAVA**だったイメージ。こちらはいわゆるプログラミングの基礎になるから、という印象。広く使われているのはこちら、という話。

そして**RubyやRailsから学ぶと今後痛い目をみる**、とどこかで言われました。
理由はおまじないが多いこと。
もくもく会でお会いしたRailsエンジニアさんも「Railsから入っちゃうと他の言語に移れるのかな〜って心配になります。あまりにも簡単にできちゃうから」とのこと。




…言葉にしづらいので自分の解釈だと
**Ruby及びRailsは「これやって」で通じるけどPHPやJAVAは「これをあーしてこーやって」まで指示する必要がある**
みたいなことを言われたのだと思う。もっと他に言い方あるやろと自分でも思うものの、いかんせん自分がPHPをふんわりとしか理解してないので言い換えても的を得られていない。そして本当にそういう意味かはちょっと自信ない。
ただ、paizaラーニングの動画でもSQLやweb基礎みたいな動画で使用されているのが**PHP**なので、やっぱり基礎にあたる言語、ということなのかと。

まぁ多分つまり、
・PHPやJAVAを勉強してからRuby、Rails
　→しっかりとプログラミングの基礎をおさえている
　→Rubyはそれを用途に合わせて簡易化してくれているから簡単！


・Rubyを勉強してからPHPやJAVA　
　→Rubyが予め指示してくれていた詳細部分までPHPでは指示する必要がある
　→わからないところがある、PHP（もしくはJAVA）めっちゃむずかしい

ということなんだと思います。

##この違いは？
こちらはあくまで本当に考察ですが、有料スクールは**「即戦力重視」**、無料スクールは**「汎用性重視」**ということなんだと思います。
Ruby-Railsが扱えるようになれば、少なくともそのRubyを扱う事業では働けるようになる→即戦力になる。
ただし本当にそれだけしか（スクール側は）保証ができないので、紹介できるのはRubyに特化したものになる。
しかも転職に成功しなければ返金しなければならないため、**難しいPHPよりもとにかく即戦力になるRuby！**ということなのかと。

一方PHPとJAVAは基礎にあたるため、エンジニア職としては多くの場所で募集をかけられているんだと思います。**実際に利用されている言語で多いのはこれらの言語**。
ただ、それだけ汎用的に使える言語だからこそ初心者が習得するのは難しい、と言われました。だから期限を設けて転職を保証する有料スクールではリスクになるのかと。本当に推測ですが。
ただ、長期的にみれば勉強しておくべき言語、という印象も受けましたので、漠然と「エンジニアになりたいな」と考えている人は挑戦してみるのも良いのではないでしょうか。
また、これは噂でしか知りませんがPHPを勉強していると**「何をしているのか分からなくなる」**という人が多いそうです。理由はおそらくその汎用性の高さだと思いますが。

##まとめ
「web系エンジニアになりたいんじゃ〜」という人はRuby-Railsを勉強するスクール
「とりあえずエンジニアになりたい！」という人はPHP、JAVAを勉強するスクール



蛇足：
プログラミング言語ってめっちゃあります。そしてそれらは目的に合わせて存在していますし、今後も増えるのだと思います。
Rubyはwebアプリ以外にも用途があると聞きますが、少なからずRailsはwebアプリに完全特化なので「Rails理解したから他の言語もやってみよう」はかなり危険です。せめて「Ruby自信ついたから他の言語もやってみよう」であるべきなのかなと。
その一方PHPやJAVAは基本をおさえられているので、エンジニアの方向性が決まった際に他の言語に取り掛かりやすいという利点があります。
スクールを考えるにあたって考慮してみてください。


最後まで閲覧いただき、ありがとうございました。
御指摘等があればコメントにてお願いいたします。

---
###### 今後追記する予定

正直どのスクールでも学ぶ方向性は同じでしたので、そちらについて書いていければなぁと考えています。ただし自分の課題が最優先で、こちらはあくまでも息抜きで書いているので遅くなると思います。ちなみに今スクールで勉強している自分の現在の心境は**「しんどい無理」**です。楽しいんですけどね。
GravitylinkがGoogleの新しいCoral製品を発売、企業のローカルAIソリューション構築を支援

GravitylinkはGoogle Coralの量販代理店としてGoogle Coral Edge TPUの全てのシリアルデバイスを発売する。Coralは、企業がローカルAIの製品を開発するのを支援するための完全なツールキットであり、エッジデバイス上のニューラルネットワークにハードウエア加速をもたらす。 

高効率、非公開、高速、オフラインのオンデバイス機能により、多くの企業は、ヘルスケア、スマートシティー、輸送から製造、STEM（科学、技術、工学、数学）教育などに及ぶ多様なアプリケーションを構築するため、その使用を開始している。

顧客のニーズに応えるため、Coralはプロトタイピング（試作品製造）から生産に至るまでのデバイス類を提供しており、これはスタートアップや大企業にとって十分に柔軟性がある。

プロトタイピングデバイスには、Dev Board（Miniバージョンが近くリリース予定）とUSB Acceleratorが含まれている。これらのデバイスを利用すれば、試作品のアイデアをスケッチから概念実証に移すのは容易である。

生産の整ったデバイスには、システムオンモジュール、3種類のPCIeモジュール、および近くリリース予定の新製品Accelerator Moduleが含まれている。これらのデバイスはどんな規模でも途切れなくプロセスに一体化され、諸産業にとって状況に応じたソリューションを開発するのに役立つ。

Edge TPUが内蔵されたこれらの全てのデバイスは、高効率のML（機械学習）推論を御社の製品にもたらすことができる。

さらに、Google CoralはカメラモジュールとEnvironmental Sensor Boardの2種類の検知製品もリリースした。

GravitylinkはGoogle Coralの量販代理店としてアジア、北米、欧州、その他の国・地域に広がる世界的販売網を構築している。その開始以来、多数の企業が生産開発のため、GravitylinkオンラインストアでCoralデバイスの大量購入をしている。

![alt](https://blogimg.goo.ne.jp/user_image/53/6f/9a0bac5c358e3ab5d477c08e6f63d36b.jpg)

詳細はhttps://store.gravitylink.com/ を参照。大量購入については割引が可能で、さらにどの製品でもGravitylinkで購入すれば、移行学習ツールやさまざまなAIモデルリソースが提供される。
Linuxの演習用環境を手軽に準備する方法のメモ

# Linuxコマンドを叩いたことのない人向けに、Linuxコマンドの演習用環境を用意した時のメモ

## 主な要件と状況
・手軽に用意したい
・別途費用が発生して欲しくない(純粋なマシン利用料含め、準備にかかるコスト)
・手元にあるLinuxマシンが１台だけ使える
  常用しているマシンのため荒らして欲しくない

## 結論
DockerコンテナでLinux環境を用意することで、一部の特権的操作を除き作業できる環境を用意する。

下記のようなdocker-composeファイルを作り、centosを使用できるコンテナを用意する。
centos/tools:latestイメージは、centosに基本的なツールを入れてあるイメージです。
普通のcentosイメージの場合、minimalな状態のため別途ツールを入れる必要があるため、こちらを利用する。
※ただ、このイメージを使ってもnetstatなどのコマンドが入らないため別途精査する必要はある。

```docker-compose.yml
services:
  cent:
    image: centos/tools:latest
    container_name: cent
    tty: true
```

あとは適当なLinuxユーザを作成して、dockerグループへ所属させる。
あとはコンテナへアクセスするためのdocker execコマンドを叩いてもらうだけ。

docker グループを明け渡すことも若干抵抗があるので、コンテナのsshポートを開けて接続してもらう方がいいかもしれない。


## 特権が必要なコマンドを実行する方法(未調査)
下記のようにprivilegedや/sbin/initなどを使うことで特権コマンドも使えるようになるっぽい。
今回のケースでは、ホストマシン側の影響を少なくしたかったので使用は避けたが、どうでもいいマシンならこの方法を取りたい。
docker run -it -d --privileged --name centos7 centos:7 /sbin/init
TECS単体テストフレームワーク TECSUnit の使い方


[TECS](https://www.toppers.jp/tecs.html)のTECSUnitの使い方です．

# 対象
TECSコンポーネント提供者

# TECSUnitとは

TECSUnitはTECS単体テストフレームワークです．
各セルについて以下をテスト出来ます

- セル変数
- 受け口関数

テスト項目は一度に複数指定でき、簡易データ記述言語「JSON」で記載．

例えば、ETロボコン用フレームワーク[mruby on ev3rt+TECS](https://tecs-docs.readthedocs.io/ja/latest/mruby-on-ev3rt+tecs/)で新たにTECSコンポーネント（セル）を実装した、もしくは既存のセルに新たな機能を追加したとします．
その際、コンポーネント提供者は各機能を詳細にテストする必要があります．
しかし、従来では対象一つ一つを手作業で接続しテストしなければならず、これは大きな負担となっていました．
TECSUnitを使うことで効率的なテストを実現します．

TECSUnitのコンポーネント図は以下の通りです．
![TECSUnit_Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207569/3d48bc39-8e94-6f77-1f9c-c8bcb345108c.png)

次にTECSUnitの利点を挙げます．

- JSONコードを用いた効率的なテスト
- テストケースが最小限の構成
- 再ビルド不要の動的テスト
- コンポーネント実装であること

それぞれについて詳しく見ていきます．

## JSONコードを用いた効率的なテスト
[JSON](https://www.json.org/json-ja.html)は、軽量のデータ交換フォーマットです．
人間にとって読み書きが容易で、マシンにとっても簡単にパースや生成を行なえる形式です．

以下、JSONコードの一例です

```:target.json
{
  "target1":{
    "region":"リージョン名",
    "cell":"セル名",
    "entry":"受け口名",
    "function":"受け口関数名",
    "pre_cond":{セル変数名:値, ... },
    "post_cond":{セル変数名:値, ... },
    "argument":[受け口関数の引数値, ... ],
    "exp_val":受け口関数の返り値
  },
  "target2":{
    /* 省略 */
  },
}
```

このように各テスト項目を記載できます．
regionからfunctionまででテストターゲットの指定をします．
次に、pre_condでセル変数の事前条件、post_condでセル変数の事後条件を指定します．
そして、argumentで受け口関数の引数の指定を行い、exp_valで返り値の期待値を設定しています．

## テストケースが最小限の構成
先のJSONコードは[TECSInfo](https://qiita.com/seito-zoso/items/54dd7bf9707e942eb893)を用いたことによってテストターゲットの指定が最小限の記載で行えています（本来であればセルタイプ、呼び口なども必要）．
また事前条件のセル変数の書き換えもTECSInfoにより行えています．

## 再ビルド不要の動的テスト

- TECSプラグインによりテストコードが自動生成
- ターゲットに動的結合で実効時に接続

これらによりテストケースが変更されたとしてもビルドし直す必要がありません．

## コンポーネント実装であること
TECSUnitはコンポーネントベースで実装されているので、テストケースの入力や結果の出力をターゲットに対して容易に変更できます．

# 実例 
実際にTECSUnitを使ってみます．
EV3RT+TECS用に実装した[github:TECSUnit](https://github.com/seito-zoso/TECSUnit)からダウンロードしてください．

    % git clone https://github.com/seito-zoso/TECSUnit.git
    % cd ev3rt+tecs/hr-tecs/workspace/TECSunit

TECSUnit.cdl にテスト対象となるセルを含んだCDLコードをインポートしてください．今回は"target.cdl"です．

```:TECSUnit.cdl
/* ターゲットのインクルード */
import( "target.cdl" );
```
インクルードしたらジェネレータに通します．
    % make tecs

これによりtecsgenディレクトリにプラグインによりテストコードが自動作成されます．
次にJSONコードを作成します

```:target.json
{
  "target1":{
    "region":"rDomainEV3",
    "cell":"Target",
    "entry":"eTarget",
    "function":"function",
    "pre_cond":{data1:1,data2:1},
    "post_cond":{data1:2,data2:2},
    "argument":[1,1],
    "exp_val":0
  },
  "target2":{
    "region":"rDomainEV3",
    "cell":"Target",
    "entry":"eTarget",
    "function":"function",
    "pre_cond":{data1:2,data2:2},
    "post_cond":{data1:4,data2:4},
    "argument":[2,2],
    "exp_val":0
  }
}
```

作成できたら

    % make

で、TECSUnitアプリケーションが作成されSDカードにuImage(バイトコード)とtarget.jsonがコピーされます．

後はSDカードをEV3に差し込み実行します．
テストケースを上から順に実行していきます．
Automation Anywhere の最新の日本語マニュアルをPDFで自動生成する方法

RPAツールであるAutomation Anywhere には日本語ドキュメントを提供しているサイトがあります。製品の最新情報はこのサイトの情報がマスターとなります。HTMLのオンラインドキュメントの形で提供されていますが、印刷したいという要望がある場合は、日本語の記事をまとめてPDFとしてダウンロードする方法があります。レイアウトはマニュアルのような形になるので、マニュアルがほしい人にも朗報です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/8e8893f6-9190-4573-c331-2c4a9a2b7498.png)


# マニュアルPDFのダウンロードのやり方

### マニュアルが欲しい製品/バージョンの製品ドキュメントページに移動

製品ドキュメントポータルを開いて、右上の言語ボタンを見て、**「日本語」**になっていることを確認してください。
https://docs.automationanywhere.com/?_LANG=jpjp

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/cb14b89c-352d-31e3-fa56-bf1a1c8b4c7e.png)

メニューの一番最初、**「最新情報 - 製品の概要とリリースノート」**をクリックします。
その後、**「リリースノート」**に表示されている製品が、マニュアルをまとめてPDF化できる製品となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/5a7a7f42-d403-aa13-6e7a-b396d103c81f.png)

ここでは

* [Enterprise A2019](https://docs.automationanywhere.com/bundle/enterprise-v2019/page/enterprise-cloud/topics/release-notes/cloud-release-notes.html?_LANG=jpjp)
* [Enterprise 11.3.x](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/release-notes/release-notes.html?_LANG=jpjp)
* [IQ Bot](https://docs.automationanywhere.com/bundle/iq-bot-v6.5/page/iq-bot/topics/release-notes/iq-bot-release-notes.html?_LANG=jpjp)

になります。


### 右ナビの「PDFを保存/すべてのトピック」を使う
いずれかのページに移動後、右側のナビゲーションを参照してください。
「PDFを保存」ボタンがありますので、このボタンをクリック後、ドロップダウンメニューから「すべてのコンテンツ」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/ab40c203-9275-46ad-ddfd-83e622da589b.png)


すると**「PDFジョブが進行中です。しばらくすると準備が完了します。」**というメッセージがページ上部に表示されますので、しばらく待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/1a1ac2b5-3694-5240-4514-b373dfd8a6fb.png)

しばらくすると、「ダウンロード」フォルダーに、以下のようにPDFが生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/a343959e-0ba2-4712-90c5-428f4499289d.png)

>注: オンラインでは英語のみのドキュメントでも目次に表示されることがありますが、PDFに落とされるものは日本語記事のみとなります。

PDFを開いてみると、以下の通り、製品ドキュメントのHTMLが表紙、目次、索引なども付いたマニュアル形式に変換されて保存されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/8e8893f6-9190-4573-c331-2c4a9a2b7498.png)

便利ですので、活用しましょう！
Firebase functions とJestの組み合わせで正しく終了させる

備忘録のメモです.
以下の環境でテストを書いてたら、Jestの終了に時間がかかりメッセージが出力されてました.

- @firebase/testing `0.16.5`
- @firebase/functions `0.4.29`
- Jset `24.9.0`

以下の様なメッセージになってるため、非同期処理がうまくできてない感じだけは分かった.

> Jest did not exit one second after the test run has completed.
> 
> This usually means that there are asynchronous operations that weren't stopped in > your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

Jestのドキュメントと、[@firebase/functions のコード](https://github.com/firebase/firebase-js-sdk/blob/4c2f8d1a4960edbde3aae2eb2736452df7b499d4/packages/functions/src/api/service.ts#L213-L214)を読みあさって以下の仕様を見つけました.


- [Jestは結果の取得に1秒以上かかると警告が出る](https://github.com/facebook/jest/blob/v24.9.0/packages/jest-cli/src/cli/index.ts#L135-L146)
- Jsetのテストのタイムアウトはデフォルトだと５秒
- `@firebase/functions` の `httpsCallable` のタイムアウトは70秒

1秒未満で終了させれば警告が出なくなるので以下の様に書き直せばOKです :tada: 
ここでは900msに設定しました.


```js
const testFuncs = firebase.initializeTestApp(config);
const functions = testFuncs.functions();
functions.useFunctionsEmulator("http://localhost:5001");

// timeoutを指定
const func = functions.httpsCallable('func', { timeout: 900 });
const res = await func({ path: "hello" });
```

1秒未満でどうしてもタイムアウトする場合は、 `--detectOpenHandles` を指定してタイムアウトを伸ばす方法もあります.
RailsでHamlを使う方法⭐︎

## RailsでHamlを使えるようにする方法

復習がてらにhamlを使ってコーディングしていたのでこの際アウトプットしておきます。

手順↓

- hamlのgemをインストールする
- 拡張子をerbからhamlにする

以上。超簡単


### Hamlのgemをインストールする

```ruby:Gemfile
gem 'haml-rails'
```

Gemfileに以上の記載をして
ターミナルで必ず `bundle install`を実行しましょう。



```
$ bundle install
```



この時点でhamlは使えるようになりますが拡張子も一気にerbからhamlに変更しておくと便利なので実行します。


### 拡張子の変更をターミナルで実行する

```
$ rails haml:erb2haml
```

実行するとターミナル上で何か聞かれますが`y`コマンドを押しておくとオッケーです。

以上。簡単
amplify パス変更したとき

amplifyのアプリでディレクトリ名変更や他の人のをコピーしてきてからamplify pushするとエラーが発生する。
私の場合はパス変更後、「amplify add storage」したあとにamplify pushしたらエラーになりました。

```bash
+0900 (GMT+09:00) Parameters: [bucketName, unauthRoleName, unauthPolicyName, authRoleName, triggerFunction, authPolicyName] must have values
```

「amplify/.config/local-env-info.json」のパスを正しく直せばうまくいくらしい。

* 参考：https://blog.mismith.me/entry/2019/10/13/212300
JAVAの依存性に対する簡単な説明

今回は**Javaの依存性**に対して扱って見ました。

## Javaにおいて依存性とは何？

**「依存性がある」**というのは簡単に言うと、**「他のクラスを利用している」**ということです。具体的には、以下の２つのどちらかに該当すると、依存性があると言えるでしょう。

- 他のクラスをローカル変数として持つ
- 他のクラスがメソッドの引数、戻り値になっている

例えば、弁当を例で説明してみましょう。弁当にご飯があります。他にもおかずなどいろいろありますが、例を簡単にするためにご飯だけを例にしてみましょう。そのとき、コードは以下のようになるでしょう。

- 弁当クラス

```java
//弁当クラス
public class Bento {
 private Gohan gohan;//ご飯
 
 //コンストラクタ
 public class Bento(Gohan gohan) {
  this.gohan = gohan;
 }
}
```
この弁当クラスは、ご飯を入れます。この弁当を作る(new)にはコードは以下のようになります。

- Mainクラス

```java

public class Main {
 public static void main(String[] args) {
   
  //ご飯の生成（インスタンス化）
  Gohan gohan = new Gohan();
 
  //弁当の生成（インスタンス化）
  Bento bento = new Bento(Gohan);
 }
}
```

このように、ある**クラスが別のクラスを利用するのこと**を**依存**と言います。

>引用 : [Dripcoke](https://dripcoke.com/)
>> [IT用語辞書-依存性](https://dripcoke.com/archives/1421)
自前PCにStyleGAN2の学習環境を作る(Win10+GTX1080ti)

StyleGAN2の学習環境を自前PC(Windows10+GTX1080ti)で構築した時の手順を紹介します。
ゲーミングPCなどローカル環境で学習させたい方の参考になればと思います。
GPUのメモリが16GBに満たない場合、1024x1024の解像度では出力できません。

ちなみに[こちら](https://hachioji-ai.connpass.com/event/164943/)の勉強会で発表した内容です。

# 全体の流れ
- ソフトのインストール
- ソース修正
- 動作確認
- 学習

# ソフトのインストール
## Visual Studio
Visual Studio 2017 Communityをインストールします。
※Visual Studio 2019だけが入った環境では動作しませんでした。適切なライブラリを入れればOKかもしれません。

インストール後、環境変数PATHに"vcvars64.bat"と"cl.exe"のフォルダまでのパスを通しておきます。

例えば下記のようになります。

- "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
- "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\"

## CUDA、cuDNN
CUDA 10.0とcuDNNをインストールします。
※CUDA 10.1では動作しませんでした。

インストール後の確認として、コマンドプロンプトで下記を実行します。

```
nvcc test_nvcc.cu -o test_nvcc –run
```

文字コードに関する警告が出ますが、最終的に下記が表示されればOKです。

```
CPU says hello.
GPU says hello.
```

## Pythonライブラリ
Anacondaで仮想環境を構築し、下記のライブラリをインストールしました。

```
conda install numpy=1.14.3
conda install tensorflow-gpu=1.14
conda install pillow
conda install requests
```

私の実行時にはpillowは7.0.0、requestsは2.22.0が入りました

インストール後の確認として、ライブラリをインストールした仮想環境のコマンドプロンプトで下記を実行します。
エラーが出なければOKです。

```
python -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))“
```

# ソース修正
## コンパイラのパスを環境に合わせる
custom_ops.pyの27行目あたりにコンパイラのパスが指定されているので、これを自分の環境に合わせます。
例）

```python:stylegan2\dnnlib\tflib\custom_ops.py
compiler_bindir_search_path = [
    ～
    'C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64',
    ～]
```

## 学習のさせ方に合わせて設定（任意）
出力する解像度を指定する場合、run_training.py 61行目のdataset_argsにresolutionを追加指定します。
2のべき乗の値を指定する必要があるのと、学習用画像の解像度よりも小さい値にする必要があります。

```python:stylegan2\run_training.py
dataset_args = EasyDict(tfrecord_dir=dataset, resolution=64)
```

学習経過のモデルと出力画像のスナップショットを取る頻度を指定する場合、run_training.py 51行目の値を変更します。

```python:stylegan2\run_training.py
train.image_snapshot_ticks = train.network_snapshot_ticks = 1
```

# 動作確認

以上までで動作するはずです。コマンドプロンプトで下記を実行します。
既存モデルで画像が出力されればOKです。

```
python run_generator.py generate-images --network=gdrive:networks/stylegan2-ffhq-config-f.pkl --seeds=66,230,389,1518 --truncation-psi=1.0
```

# 学習
あとは学習で使う画像を集めたり、画像を調整したりし、学習を実行します。

学習時には画像をtfrecord形式にする必要があります。コマンドプロンプトで下記を実行します。

```
python dataset_tool.py create_from_images tfrecord形式出力先フォルダ 入力元画像フォルダ
```

学習実行時にはconfigセット(a～f)を指定できます。
aとf(デフォルト)しか試していませんが、同じ学習時間でもaよりもfの方が本物っぽい画像が出力されました。

# 参考
[StyleGAN2 — Official TensorFlow Implementation](https://github.com/NVlabs/stylegan2)
aws ssm describe-instance-information の ComputerNameをいい感じにする

`aws ssm describe-instance-information` の出力項目に `ComputerName` というのがある。
これは、公式ドキュメントによると

https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-instance-information.html

> The fully qualified host name of the managed instance.

とのことで、FQDNが表示されるとのこと。
ところが、自分の現場ではこれの表示がlocalhostだったりしてうまく表示できていなかった。

```
$ aws ssm describe-instance-information --output table --query "InstanceInformationList[].[InstanceId,ComputerName]" --filters "Key=InstanceIds,Values=i-01234567890123456"
----------------------------------------------
|  DescribeInstanceInformation               |
+----------------------+---------------------+
|  i-01234567890123456 |  localhost          |  
+----------------------+---------------------+

```

これを解決した方法。

## hostname が適切でない場合

```
$ hostname 
ip-172-31-15-172
```

この様になっている場合は、ホスト名を変更する。
Ubuntu 18.04の場合は以下。

```
sudo hostnamectl set-hostname awesome-production
```
```
$ hostname 
awesome-production
$ hostname -f
awesome-production
```

となればOK。

```
$ aws ssm describe-instance-information --output table --query "InstanceInformationList[].[InstanceId,ComputerName]" --filters "Key=InstanceIds,Values=i-01234567890123456"
----------------------------------------------
|  DescribeInstanceInformation               |
+----------------------+---------------------+
|  i-01234567890123456 |  awesome-production |  
+----------------------+---------------------+
```

ただ、自分の環境ではこれでも解決しないケースがあった。
原因は `/etc/hosts` の設定だった。

## `/etc/hosts` が適切でない場合

まず、`ComputerName` に表示される内容は、自分の環境の複数インスタンスで確認した限りでは
`hostname -f` の出力と一致していた。
（ほんとはソースコードまで追っかけて裏取りたかったが、時間無く断念）

`ComputerName` が `localhost` になっていたインスタンスの `/etc/hosts` をみると
以下のようになっていた。

```
127.0.0.1 localhost awesome-production
```

いろいろ試したところ、localhost が単独行でないと、ダメらしく、以下のように修正した。

```
127.0.0.1 localhost 
127.0.0.1 awesome-production
```

こう修正したうえで `hostname -f` をすると、`hostname` と一致した。
（なぜこうなるか、までの理由はわからなかった）

```
$ hostname 
awesome-production
$ hostname -f
awesome-production
```

```
$ aws ssm describe-instance-information --output table --query "InstanceInformationList[].[InstanceId,ComputerName]" --filters "Key=InstanceIds,Values=i-01234567890123456"
----------------------------------------------
|  DescribeInstanceInformation               |
+----------------------+---------------------+
|  i-01234567890123456 |  awesome-production |  
+----------------------+---------------------+
```

ちなみに、上記hostname等修正後、 `aws ssm describe-instance-information` の出力に修正が反映されるまでは、少しタイムラグがある。
体感で数分程度。
おそらく SSM Agentが情報を取りに行くタイミングがあるのだろう。
[Flutter] image_pickerを使ってライブラリから画像を読み込めない時の対処方法[Android 10]

# 画像が読み込めない！
Flutterで写真にアクセスしようとしてimage_pickerプラグインを使用している
Android10の端末でファイルにアクセスしようとするとpermission denied
targetSdkVersionを29にしていると発生

#TL;DR
対処方法のみ記載
以下リンクにあるようにAndroidManifestにおまじないを書く

```xml
<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
    <application android:requestLegacyExternalStorage="true" ... >
      ...
    </application>
</manifest>
```
参考リンク：
https://developer.android.com/training/data-storage/compatibility
https://developer.android.com/training/data-storage/shared/media?hl=ja#storage-permission

issue
https://github.com/flutter/flutter/issues/41459
#
 実装などはあとで記載します。
Maya TransformAttributesの値だけをリセット（改良版）

以前記事を書いた
選択オブジェクトのTranslate, Rotate, Scaleを一度に初期化するMELの改良版です。

主にこのあたりを変更しました。
・locked状態のものはスルーして処理を続ける
・選択項目がない場合のエラー文追加


```
string $objs[] = `ls -sl`;
if(`size $objs` == 0){
    print "何も選択されていません";
}else{
    for ($objSel in $objs)
    {
        select $objSel;

        if(`getAttr -lock .tx` == 0){
            setAttr .tx 0;
        }
        if(`getAttr -lock .ty` == 0){
            setAttr .ty 0;
        }
        if(`getAttr -lock .tz` == 0){
            setAttr .tz 0;
        }

        if(`getAttr -lock .rx` == 0){
            setAttr .rx 0;
        }
        if(`getAttr -lock .ry` == 0){
            setAttr .ry 0;
        }
        if(`getAttr -lock .rz` == 0){
            setAttr .rz 0;
        }

        if(`getAttr -lock .sx` == 0){
            setAttr .sx 1;
        }
        if(`getAttr -lock .sy` == 0){
            setAttr .sy 1;
        }
        if(`getAttr -lock .sz` == 0){
            setAttr .sz 1;
        }
    }
}
```


後日、こちらも修正かけるかもしれません
・特定ノードを指定する
・選択オブジェクトの子もすべて初期化
・Connectedがある場合
・Expressionがある場合
Androidのソフトウェアキーボードの高さと表示状態をお手軽取得

# 概要
Androidのキーボードの高さと表示されているかを知る方法が標準で用意されていないので自作してみました．
そのままコピペすれば動きます．
コードは10行くらいです．
## ソースコード

```kotlin
    var layoutBottom: Int = 0 // 現在のlayoutのbottomを保存
    var isShowingKeyboard: Boolean = false // キーボードが表示されていればtrue
    var keyboardHeight: Int = 0 // キーボードの高さ
    override fun onCreate(savedInstanceState: Bundle?) {
        val mRootView = window.decorView.findViewById<ViewGroup>(android.R.id.content)
        layoutBottom = mRootView.height
        mRootView.viewTreeObserver.addOnGlobalLayoutListener {
            val rect = Rect()
            mRootView.getWindowVisibleDisplayFrame(rect)
            isShowingKeyboard = layoutBottom > rect.bottom
            keyboardHeight = abs((layoutBottom - rect.bottom))
            layoutBottom = rect.bottom
        }
    }
```