OmniAICreator/Qiita-1.07M huggingface dataset:
HHKB＋WindowsでMac式入力切替が動作しない原因

# 前提
HHKB TypeS(日本語配列)を購入した。
HHKBキーマップ変更ツールを使ってスペースキーの両隣にかな英数キーを配置した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/877de761-4312-5f55-8720-2c66232d11dc.png)
この設定ではMacの日本語キーボードのように、”かな”を入力すると日本語入力モード、”英数”を入力すると英数入力モードになる動作が期待できる。

>Windowsでは半角英数キーを使って、日本語と英数を交互に切り替える方式である。

## ところがどっこい
PCが2台あり(A/Bとする)、Aでは期待通りの動作ができた。
Bでは入力切替が動作しなかった。

## 原因
**GoogleIMEは標準では、HHKBかな英数キーに対応していない**

期待した動作をしなかったWindowsではGoogleIMEをデフォルトで利用していた。
Google日本語入力は細かく設定できるので、対応することも可能だが今回はとりあえず**MicrosoftIMEへ戻した。**
Macデフォルトのディレクトリ名を英語表示にする方法

Macのディレクトリ名はOS設定を日本語にしていると日本語表示になります。
`Documents` ⇔ `書類` 、 `Pictures` ⇔ `写真` とか正直わかりにくい。
実体は英語表記のディレクトリ名なので、ターミナルとかからいじるときに表記が別々で面倒なので統一したい。
けどOS設定は日本語が良い。

方法としては簡単で各ディレクトリに存在している `.localized` というファイルを削除する。

```
$ rm ~/Applications/.localized
$ rm ~/Documents/.localized
$ rm ~/Downloads/.localized
$ rm ~/Desktop/.localized
$ rm ~/Public/.localized
$ rm ~/Pictures/.localized
$ rm ~/Music/.localized
$ rm ~/Movies/.localized
$ rm ~/Library/.localized
```

サイドバーなんかはFinderを再起動させると反映されるようです。
![スクリーンショット 2020-12-05 17.11.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/3914310a-295c-8d0c-8d79-085c7073dc3b.png)


サイドバーに `アプリケーション` が残っているのでこっちも削除

```
rm /Applications/.localized
```



`.localized` はただの空のドットファイルなので、逆に

```
mkdir ~/Desktop/Documents
touch ~/Desktop/Documents/.localized
```

みたいなことをすると、デスクトップに `書類` というフォルダを作ることができる。
WindowsでRubyで作ったGUIのEXEを配布するときにlibuiを使う場合のメモ

メモ書き的な内容ですみません。機会があったら拡充します。この情報だけだと単なるヒントという感じなので、わからない部分は都度ググってください（書いた人も、試したら出来たから記事にして忘れないようにメモするという状態です）

## はじめに

　Rubyでプログラミングを覚えた後、GUIでWindows向けのツールを作成して、配布してみたいと思う方は結構いると思います。でも実際にはパーフェクトな方法がないのが現状です。

### 2021-03-15 追記
今でもこの記事を見ている人が割といるようなので宣伝。この記事に出てくるlibuiとは別に、自前でLibUIというGEMを作りました。こちらは下に書いてあるような工夫をしなくても、すぐに使うことができるようになっています。この記事の内容は少し古いです。何か問題がありましたら下のリポジトリのissueまでお寄せください。日本語でも構いません。

https://github.com/kojix2/libui

https://qiita.com/kojix2/items/1bf6b999973ea3bc17e6


### ocra

　まず、RubyのインストールされていないWindows環境でRubyを動かすとなったときに、Ocraというツールを使うことが多いと思います。

* https://github.com/larsch/ocra/

ocraはRuby処理系全体を圧縮してEXEファイルに詰めてしまい、Rubyを実行する際にはRuby処理系を解凍してそれを実行すると聞いています。（詳しいことはわかりません）Ruby処理系と一緒にGUIツールもocraでEXEの中に詰め込む必要があります。

　では、どのGUIツールキットを同封するか、という話になります。以前ならTkをお勧めしていたのですが、TkがRuby標準ライブラリから切り離されてしまった今、積極的にTkを勧める理由が以前に比べると薄くなってきたのかなという気がします。gtk2というのも鉄板ですが、いまさらversion2なのは気になります。そもそもgtkは重いのでOcraに詰め込むのは向いていないです。かといってjrubyは使いたくないですし。

### libui

　そこでもっと軽量なライブラリとなるとlibuiが候補に挙がります。

* https://github.com/andlabs/libui

libuiは、リリースページからバイナリを配布しているので、これをダウンロードしてきます。libuiのRubyバインディングは

https://github.com/jamescook/libui-ruby

です。しかし、Gemが十分に整備されていなくてそのままでは`libui.dll`を認識してくれないので、適当にソースコードを書き換える必要があります。またgemspecファイルもないのでインストールするのも面倒ではあります。

さて、`gem install libui-ruby` で libuiをインストールしたとして、libui.dllをソースコードと同じ位置に配布して、ext.rbを適当に書き換えて読み込めるようにしておきます。

```ruby:ext.rb
    ffi_lib File.expand_path("libui.dll", __dir__)
```

みたいな感じですかね。

これで試しにexampleのcontrol_gallery.rbをEXE化してみましょう。

```sh
cd example # https://github.com/andlabs/libui
ocra .\control_gallery.rb --dll ruby_builtin_dlls\libssp-0.dll
```

とします。おそらく実行ファイルができるはずです。自動的にffiなど必要なgemを検出していますね。
`--dll ruby_builtin_dlls\libssp-0.dll` は、libssp-0.dllがありませんとかいうエラーが出るので、これをつけて回避した痕跡なので、エラーが出なければなくてもかまいません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/da431069-f6b8-1290-f095-89ea8354c0e8.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/4622ccd6-413d-2022-ae5d-f3f4d466582b.png)


このファイルは2544KBと、RubyのEXEとしてはまあまあ小さなサイズで、なおかつGUIが起動します。起動が遅くね？と思うかもしれませんが、ぶっちゃけTkやGtkをocraで詰め込むのと比較したらすごく高速です。サイズが大きくなってもかまわないなら`no-lzma`（無圧縮）オプションでさらに高速にすることもできると思います。

一応、WindowsからRuby処理系を削除して、それでも起動することを確認したので、これで配布可能だと思います。

この記事は以上です。
3分で分かる！ワークテーブルとは

#テーブルとワークテーブルの違い
仕事柄OracleDBを触ることが多々あるのですが、
何かとよく耳にするのがワークテーブル。

初めて聞いた時は「？？？」な状態になったので、
ワークテーブルとは何かについてまとめてみました。

ワークテーブルとは文字通り、
<b>作業するためのテーブル</b>です！



テーブルといえば、顧客情報などの
絶対に削除してはいけないものをイメージされるかと思います。
データがずーっと保持されるってことですね。
※テーブルと言うワークテーブルとの違いがわかりにくいので、
今回は<b>マスターテーブル</b>と言いましょう！

対してワークテーブルはテーブルデータを一日だけ保持するイメージです。

#ワークテーブルの使われ方
例えば、ある一日に登録された顧客情報は
ワークテーブルで保持されます。

毎日夜間に実行されるバッチにより、
その日取得したデータはワークテーブルから
マスターテーブルへとinsertされます。

insert後は、ワークテーブルのデータは不要になるため、
データを削除、つまりはトランケートしてあげる必要があります。
※翌日も翌々日も毎日使えるようにするために、
この作業は必要となりますよね。

#まとめ
以上ワークテーブルについてでした。
明確にこうです！！っと定義されているわけでないです笑。

しかしざっくりイメージを知っておくだけでも、
かなり理解がしやすくなったのではないでしょうか！
batファイルで引用符を追記する

#はじめに
プログラミングが初心者が日常における業務の
ちょっとした効率化を図りたいと思い書き始めました。
（備忘録と成果の記録も兼ねて）

#本題
業務ではSalesforceを使い始め、
メッセージのやり取りをする時、一度テキストエディタ（メモ帳）を
用いて下書きしてからSalesforceにコピペするという作業をしています。
その時、テキストエディタではメッセージ相手の文章に引用符（>）を自動で
追記する機能がありません。

いままでは文頭に手動で「> 」を付けて文章を作成していました。
毎回発生する作業になるので手間だなと感じていました。

そこで手軽?に作成できるコマンドプロンプトを使用してbatファイルを
作ればいいんじゃない？と考えて作成しました。

#コード

```bat
@echo off

for %%f in (%*) do (
    for /f "delims=" %%i in (%%~nxf) do @echo ^> %%i >> test.txt
)

start "" "test.txt"
```

#コードの解説
１．最初のfor文でドラッグ＆ドロップでファイル名を取得します。

　　ファイル名+拡張子のみ取得したい場合
 　　　`%%~nxf`
　　　　⇒ 取得したファイル名の例）__test.txt__

２．2番目のfor文でテキストファイルを1行ずつ読み込み、
　　@echoの後に書いている「> 」の引用符を文頭に追記します。

３．その後、引用符を追記したファイルをtest.txtとして保存します。
４．最後にtest.txtを起動します。
UnicodeEncodeError: 'charmap' codec can't encode characters in position 51-61: character maps to <undefined>

# heorku環境でmysql操作でハマった(個人用)

ローカル環境で動作確認ができていたがheroku環境でエラーになりかなりハマってしまった。
もお忘れないと思うが一応記録。
もし同じエラーでつまづいている人のエラー解決の助けになればと思います。

##変更前ソース
```python:main.py
#heorkuDB接続
conn = MySQLdb.connect(user=DB_USERNAME, passwd=DB_PASSWORD, host=DB_HOSTNAME, db=DB_NAME)

#sql実行(一部切り取り)(エラー発生箇所)
conn.execute("SELECT name FROM user")
```

##エラー発生
```:エラー内容
UnicodeEncodeError: 'charmap' codec can't encode characters in position 51-61: character maps to <undefined>
訳)UnicodeEncodeError： 'charmap'コーデックは51〜61の位置の文字をエンコードできません：文字は<undefined>にマップされます
```

文字コードのエラーを確認。
色々調べてトライアンドエラーを繰り返しやっとたどり着いた解がこれ。

## 変更後ソース(接続時：charsetを指定)

```main.py
#herokuDB接続時にcharsetを指定する
conn = MySQLdb.connect(user=DB_USERNAME, passwd=DB_PASSWORD, host=DB_HOSTNAME, db=DB_NAME, charset="utf8")
```

以上。
Deno Standard Library Working Group について

Deno (ディノ) Advent Calendar 2020、5日目の記事です。

今日は Standard Library Working Group という会議体について紹介します。

# Deno Standard Library について

Deno Standard Library は Deno の標準ライブラリ集です。ソースコード的には、[Deno 本体のレポジトリ](https://github.com/denoland/deno) の std/ ディレクトリ以下で開発されていて、基本的にはほとんどが TypeScript で実装されています (一部で wasm を使っています)。

Deno 本体は今年(2020年)5月に 1.0 がリリースされ、ある程度 API が固定化されましたが、Standard Library は 1.0 がまだリリースされておらず、現在は 0.79.0 というバージョンが最新です。

Standard Library はまだまだ発展途上で、モジュールによっては機能が全然足りていないものもあります。個人的には datetime モジュールなどは、現実的なアプリケーションを作成するためにはかなり機能不足と見ています。

Standard Library の趣旨は Node.js で多くの機能を npm (3rd party) にまかせてしまったことにより、依存の連鎖があまりにも肥大化し、node_modules が巨大化してしまったことへの反省と、それに対するソリューションとして、公式の大きなモジュール集を提供するという意図があります。

# Standard Library Working Group

Standard Library の安定化のために先月 Working Group が発足しました。これは Deno に興味がある人であれば誰でも参加が可能です。 https://github.com/denoland/deno/issues/8405

参加を希望する場合は Google Group の https://groups.google.com/g/deno-std に参加しましょう。

会議体としては2週に1回のペースで Google Meet で会議が開催されます。

議題としては毎回いくつかのモジュールが選ばれて、それらの API を安定とみなすか、安定化するためには何が必要か等の議論が行われます。

第一回はつい先日 12/3 に行われました。( YouTube で録画を閲覧可能です。 https://www.youtube.com/watch?v=V-eefQqjrPY )

# まとめ

今日は Deno の Standard Library Working Group の概要について紹介しました。
【備忘録】Laravel8でfactoryを使うには

##結論

`{モデル名}::factory()->create();`
複数作るときは
`{モデル名}::factory->count(10)create();`

##経緯

Laracastsのツイッタークローン作成の章で、
ファクトリーを使ってダミーのユーザーをデータベースへ登録するために

>`factory('App\User')->create()`をtinker叩く

と指示があるものの、

>`PHP Fatal error:  Call to undefined function factory() in Psy Shell code on line 1`

とエラーを吐いてしまう。
これはLaravel８ではfactoryの使い方が以前のバージョンとは異なることが原因だった。

参考にしたページ→[Please help: Call to undefined function factory()](https://laracasts.com/discuss/channels/code-review/please-help-call-to-undefined-function-factory/)
ドキュメント→https://readouble.com/laravel/8.x/ja/database-testing.html

各モデルがHasFactoryトレートを持っている状態で生成されるように

    <?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Factories\HasFactory;//この部分
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Fortify\TwoFactorAuthenticatable;
    use Laravel\Jetstream\HasProfilePhoto;
    use Laravel\Jetstream\HasTeams;
    use Laravel\Sanctum\HasApiTokens;

    class User extends Authenticatable
    {
        use HasApiTokens;
        use HasFactory;//この部分
        use HasProfilePhoto;
        use HasTeams;
        use Notifiable;
        use TwoFactorAuthenticatable;

    中略
        
    }

HasFactoryトレート

    <?php

    namespace Illuminate\Database\Eloquent\Factories;

    trait HasFactory
    {
        /**
         * Get a new factory instance for the model.
         *
         * @param  mixed  $parameters
         * @return \Illuminate\Database\Eloquent\Factories\Factory
         */
        public static function factory(...$parameters)
        {
            $factory = static::newFactory() ?: Factory::factoryForModel(get_called_class());

            return $factory
                        ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : null)
                        ->state(is_array($parameters[0] ?? null) ? $parameters[0] : ($parameters[1] ?? []));
        }

        /**
         * Create a new factory instance for the model.
         *
         * @return \Illuminate\Database\Eloquent\Factories\Factory
         */
        protected static function newFactory()
        {
            //
        }
    }
自分で画像を学習して、物体認識を行う　Part1

#物体認識を行う準備(環境構築)

初めまして。今回は１ヶ月間の物体検出学習で得たことをまとめたいと思います。

**まず初めに使用するツール、サンプルコードです。**

- YOLOv5
- labelImg
- roboflow
- google colaboratory


ほぼこれだけしか使用しません。




***PCスペック***

- MacBook Pro 13-inch, 2019
- メモリ　8GB 
- プロセッサ　1.4 GHz クアッドコアIntel Core i5

初めて書くので、他に何のスペック書けばいいかわからないので投稿するときに載せるといいものがあれば教えていただきたいです。





**まずは、環境構築を行って行きます。**

yolov5 github 
https://github.com/ultralytics/yolov5
このURLからソースコードをインストールします。

ページに移動すると![スクリーンショット 2020-12-05 16.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931014/6ec280e5-fb2c-bb50-21d9-48fe88a63a64.png)

この画面が表示されると思います。

右上にある**緑色の「code」をクリックし、「download zip」**で
zipファイルをダウンロードしてください。　

![スクリーンショット 2020-12-05 16.32.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931014/e49a97eb-c456-29f7-5da0-49f4497e7a20.png)

ダウンロードができたら、zipファイルを展開します。

そうすると、以下のようなものができると思います。

![スクリーンショット 2020-12-05 16.35.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931014/d015547e-8451-23d8-f545-009d30dd4529.png)

ここから、**README.md**を使用します。

- ターミナルを開きます。
- yolov5をダウンロードしたパスまで移動します。
- 今回の場合は、ディレクトリの移動させずにそのまま行います。

まずは自分場所を確認するために、list segmentsをします。

```ruby:ターミナル
ls
```

まあ実際ダウンロードファイルをどこに置いてもいいのですが、今回はそのまま行きます笑


```ruby:ターミナル
cd Downloads
```
でダウンロードフォルダに移動します。

```ruby:ターミナル
cd yolov5-master
```

おそらくフォルダ名がyolov5-masterになっていると思うので、そこに移動します。

そしたら、README.mdに書いてある通りに操作します。


```ruby:ターミナル
pip install -r requirements.txt
```
インストールが始まります。

pipでエラーが出たらpip3でやってみてください。


**次にlabelImgのインストールを行います。**

labelImgのgithubに飛びます。
https://github.com/tzutalin/labelImg

下にスクロールしていくと、セットアップの仕方が載っています。

yolov5と同様に、codezipをダウンロードします。

ダウンロードが完了したら、展開してください。


```ruby:ターミナル
cd ..
```

さっき、yolov5-masterのディレクトリにいたので移動します。

```ruby:ターミナル
cd labelImg-master
```
移動したら、labelImgのインストールをしていきます。


```ruby:ターミナル
brew install qt  # Install qt-5.x.x by Homebrew
brew install libxml2 
or using pip
pip3 install pyqt5 lxml # Install qt and lxml by pip

make qt5py3
python3 labelImg.py
```

インストールが始まります。

![スクリーンショット 2020-12-05 17.07.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931014/17f0dd5c-5a14-cb31-8f7e-1c31cb1f5140.png)

この画面が出たら、成功です。

これで第一段階の環境構築は完了です。

Part2で、google colaboratryの説明をしていきます。

閲覧ありがとうございました！
Visual Studio Code(Windows版)日本語化

## はじめに

Visual Studio Code を日本語化する際のメモをシェアします。

OS: Windows10
Visual Studio Codeのバージョン：1.51.1


### Visual Studio Code を立ち上げる
![vscode(英語).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/d37da6c6-5ed6-5585-67ee-cc9247ec502c.png)

### Command Palette　を開く
メニューのViewの中にある
![vscode_command_pallat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/2f1e34ba-7e80-080a-873e-e1a1bcae0d41.png)

### Configure Display Language を選ぶ
Command Palatte が表示されるとCommandがずらりと並んでいる
「config」と入力するとConfigure Display Language　が選びやすい。
![vscode_command_pallat_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/664b2b11-acda-a427-1bf3-8f8c6fdf37e5.png)

### Display LanguageにてInstall addtional Languagesを選ぶ
![vscode_display_language.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/b5b730c0-6713-b4bb-70f0-2bc52e6d1249.png)

### Japanese Language Pack for Visual Studio Code をinstall
![vscode_japanese_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/aea3c289-c292-cb74-7a77-c82f0767f27d.png)

### installが終わるとrestartボタンが現れるので押す
![vscode_japanese_installed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/1788ab34-e400-ac9b-6a91-b093eacec44c.png)

### 日本語化された
![vscode_japanese.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150699/9c9f6d70-c5d8-940a-4b9d-31122a29be4c.png)

## おわりに

以上がVisual Studio Codeを日本語化した時のメモとなります。

簡単で楽ですね。

おわり。
【Rails】Concernでコントローラーの重複した記述をまとめる

# Concernとは
結論から言いますと、コントローラーの重複した記述を防ぐための、拡張機能です。
アプリ作成が続くと、コントローラーの記述が増え、重複した記述になりがちです。
そこでConcernを利用してまとめていきましょう。

# やり方
### 1. `controller/concerns`ディレクトリにファイルを作る。今回は`common_actions.rb`と名前をつけます。
### 2. controllerで重複した記述を見つける
```ruby:controller/post_as_controller.rb
#省略
  def update 
    if @post.update(post_params)
      redirect_to user_url(current_user)    
    else
      render :edit
    end
  end
#省略
``` 
```ruby:controller/post_bs_controller.rb
#省略
  def update 
    if @post.update(post_params)
      redirect_to user_url(current_user)    
    else
      render :edit
    end
  end
#省略
``` 
### 3. `common_actions.rb`に共通処理を記述する
```ruby:controller/concerns/common_actions.rb
module CommonActions #moduleを定義する

  #これを記述することで、インクルード先で、クラスメソッドも使用することができる。今回の場合はあっても無くてもOK
  extend ActiveSupport::Concern 

  #以下に共通内容を記述
  def post_update 
    if @post.update(post_params)
      redirect_to user_url(current_user), notice: 'お気に入りを編集しました'
    else
      render :edit
    end
  end

end
```
### 4.　元のファイルから共通処理を消し、モジュールをincludeする

```ruby:controller/post_as_controller.rb
#モジュールをincludeする
include CommonActions

#ここから
  def update 
    post_update #includeしたインスタンスメソッドを使用
  end
#ここまで
``` 
```ruby:controller/post_bs_controller.rb
#モジュールをincludeする
include CommonActions

#ここから
  def update 
    post_update #includeしたインスタンスメソッドを使用
  end
#ここまで
``` 
### 5. おわりです
# まとめ
今までコントローラーに重複した記述を書いて可読性が低くなっていましたが、まとめることで読みやすくなりました。

この記事でもっと知りたい！と思った方は、下記の記事に詳しく載っておりますのでご参照ください。

[ActiveSupport::Concernの使い方としくみ](https://qiita.com/h-shima/items/d772b4cbe7368ddb8255)

最後まで読んで頂きありがとうございました。
⌘英かなでMacのUSキーボードを快適に使う

これまでの人生で2回詰まったのでメモる。

## やりたいこと

- 左コマンド１クリックで英数入力にする
- 右コマンド１クリックでかな入力にする
- 左コマンドダブルクリックで直前のかな入力を英数入力に変換する
- 右コマンドダブルクリックで直前の英数入力をかな入力に変換する


[注] 設定後も、4つ目はVS Codeでは有効ではなかった

## やりかた

以下のように設定する

### (1)英かな

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/6ccb50d9-b6b1-154e-b4d6-2a39102cbe88.png)



### (2)`System Preferences`＞`Keyboard`>`Input Sources`

Englishを`-`で削除する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/e625f0f1-0305-a853-8744-3c53b03750a8.png)
module 'tensorflow' has no attribute 'get_default_graph' 出たときの対処方法

## 発端
自社の解析サーバーのCICDを修正する際に、解析サーバーだけではなくローカルで動かしたいと思い、修正していたときの出来事。
モックも作成したし、うまくいくだろうと思ったら、次のようなエラーが発生した。 
```
module 'tensorflow' has no attribute 'get_default_graph'
```

tensorflow か・・・・・・

## 環境

```
Keras==2.2.0
tensorflow==2.3.0
```

## 対処方法

```
pip install Keras==2.3.1
```

すると以下のエラーが発生

```
module 'tensorflow.python.framework.ops' has no attribute '_TensorLike'
```

次に keras を使用しているスクリプトファイルにて以下のような修正をした

```
# Before: from keras.models import load_model
# After:
from tensorflow.keras.models import load_model
```

したら、うまくいった。
やれやれ。


## 参考文献
https://qiita.com/white1107/items/67ec0826a07a84442d31
https://stackoverflow.com/questions/53135439/issue-with-add-method-in-tensorflow-attributeerror-module-tensorflow-python
「ハッキング・ラボのつくりかた」備忘録　＃1

#はじめに
　この備忘録は[IPUSIRON](https://twitter.com/ipusiron)さん著の[ハッキング・ラボのつくりかた](https://www.amazon.co.jp/dp/4798155306)をたぶん最新バージョンで行ったものの備忘録です。
　今回は第二章の環境構築の際につまづいたところを中心にまとめます。
#私の環境
Windows 10 Home ver.1909
Virtual box ver.6.1.16
Kali Linux ver.2020.4
#環境構築のつまづいたところ
##µtorrentの問題
　Kali　Linuxのイメージファイルをダウンロードする際、µtorrent経由で実行すると早くできるとのことですが、[サポートサイト](http://s-akademeia.sakura.ne.jp/main/books/lab/faq.html)の通り、µtorrentのインストールはお勧めしません。
　部屋でも片付けながらダウンロードを気長に待ちましょう
##Kali LinuxのVersionが違う問題
　Kali LinuxのVersionが変わりました。諸行無常です。
####Rootユーザーが消えた
　Rootユーザーが消え、デフォルトのアカウント名はkali、パスワードもkaliになりました。これによって、kaliユーザーは一般ユーザーなので、root権限が必要なものはすべてsudoコマンドを置く必要があります。
　ちなみにデフォルトのアカウント名とパスワードは下の図のように確認できます。
![スクリーンショット (36).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/3bd5599a-1d58-5e0d-744d-e6250cdfa110.png)
###Kali　Linuxのカスタマイズ
　Settingを開きます。左上の小学生の彫刻刀セットみたいなデザインの小さいドラゴンのアイコンをクリックし、開いた画面の右下にある中途半端に食べた三色団子みたいなデザインのアイコンをクリックします。すると、設定画面が出てきます
![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_14_56_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/df04000c-ae0c-ce34-1b7e-e169c43ad750.png)
![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_15_06_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/9111da50-57ac-fa72-ab4d-41fc9cdddaf8.png)
　Power ManagerのDisplayを写真のようにして
　![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_15_07_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/b845e73e-cb74-1df0-ddd4-ca1eded1fe4f.png)
　Securityの自動ロックをNeverにします。そうすると、放置するのに便利になります。
![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_15_07_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/c4261d94-64e0-28a7-b60b-d8c2600a4ae7.png)
　日本語キーボードへの対応はLayoutにJapaneseを追加しEnglishを削除します。
![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_15_08_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/2719fcc4-d91a-2d0c-7939-c3d03ba67483.png)
　また、日本語表記にはする必要がないと判断しましょう。己の英語力を過信してください。
　タイムゾーンはSettingからPanelのClockを開き、Time Settingに国名を打ち込んで変更できます。
![VirtualBox_Kali-Linux-2020.4(64bit)_05_12_2020_15_27_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922191/37a3a06e-1af4-c2ae-c012-372dc6917e93.png)
###LANアダプターの設定
　Virtual　Boxは書籍のとおり設定します。アダプター2を設定するときには仮想OSが電源オフの状態になければなりません。
　続いて、LANアダプターの設定をKali Linuxで書き込むには、左上の白枠で黒い四角形のアイコンをクリックするとTerminalが開かるので、そこで操作します。この操作にはroot権限が必要です。そのためsudoコマンドで実行する必要があります。
```sudo vi /etc/network/interfaces```
終わったら、
```：wq```
で上書き保存します。
　ちなみに書籍の通りコマンドを打ち、ファイルを編集してしまった場合は
```E45: 'readonly' option is set (add ! to override)```
と出てきます。この時はESCキーを押した後
```:w !Sudo tee %```
を実行し、強制的に上書きして
```:q!```
で、終了します。コマンドの意味は調べてください。
</details>
#おわりに
　巨人の肩の上で座っているだけの私が、参考文献を示さないのは許可を取るのがめんどくさかったからです。スイマセン...
　しかし、つまづいた際にTwitterで[＃ハッキングラボ](https://twitter.com/search?q=%23%E3%83%8F%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%83%A9%E3%83%9C&src=typed_query)または[＃ハッキング・ラボ](https://twitter.com/search?q=%23%E3%83%8F%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%83%BB%E3%83%A9%E3%83%9C&src=typed_quer)や、Qiitaを探せばほとんど見つかりました。
　すべての先人に感謝:pray:
Railsでsvg画像つこてみた

# はじめに
皆さんこんにちは、駆け出しエンジニアのプージニアです！
先週初投稿を果たし、本記事２本目でございます！

本記事はRailsでsvg画像を読み込んでつこてみた記事になります😁

###対象の読者

・svgをRailsで使ってみたい！

###参考

ヘルパーメソッド参考
https://coderwall.com/p/d1vplg/embedding-and-styling-inline-svg-documents-with-css-in-rails

##Applicationヘルパーを作成する

```ruby:application_helper.rb
# viewでsvg形式のファイルを読み込む
  def embedded_svg filename, options={}
    file = File.read(Rails.root.join('app', 'assets', 'images', filename))
    doc = Nokogiri::HTML::DocumentFragment.parse file
    svg = doc.at_css 'svg'
    if options[:class].present?
      svg['class'] = options[:class]
    end
    doc.to_html.html_safe
  end
```

コードの詳細は以下の参考サイトご覧ください！
僕の知見が増えてきたらコードの解説も編集して投稿する予定です

##headerでつこてみる

以下サンプルコードはアプリケーションのロゴにsvg画像を採用する場面を想定しております

```erb:_header.html.erb
<%= link_to embedded_svg("application-logo.svg",
class: "application-logo",alt: "ApplicationName logo"), root_path %>
```
##挿入したsvg画像のいじり方
分かりやすい記事なので是非下記参考にしてください
https://qiita.com/yamaking/items/3e2528ef7960c3b6ed9a

##まとめ
皆さん無事にsvg画像表示されましたでしょうか？
表示されないよーって方はご質問頂ければわかる範囲でお答え致します👍

最後まで読んで頂きありがとうございます！

##参考文献
https://qiita.com/yamaking/items/3e2528ef7960c3b6ed9a
https://coderwall.com/p/d1vplg/embedding-and-styling-inline-svg-documents-with-css-in-rails
grid-template、グリットテンプレート

grid-template

```
//画像１
body {
  font-size: 2rem;
  width: 800px;
  margin: 0 auto;
  min-height: 100vh;
  display: grid;
  grid-template: 
    "... ...... ...... ...... ...... ...... ... " 10px
    "... header header header header header ..." 150px
    "... ...... ...... ...... ...... ...... ..." 10px
    "... left   ...... center ...... right  ..." 1fr
    "...  ...... ...... ...... ...... ...... ... " 10px
    "... footer footer footer footer footer ..." 300px
    "...  ...... ...... ...... ...... ...... ... " 10px

    /10px 150px 10px 1fr 10px 200px 10px;
}
```

簡単な余白は
gap: 10px

1frを
minmax(300px, 1fr)

でも良し




```
//画像２
header {
  grid-area: header;
}
main {
  grid-area: center;
}
nav {
  grid-area: left;
}
aside {
  grid-area: right;
}
footer {
  grid-area: footer;
}
```

レスポンシブ対応は

```
@media screen and (max-width: 1000px) {
  body {
    grid-template:
    "header"150px
    "center"1fr
    "left  "
    "right "
    "footer"300px;
  }
```



注意
Internet Explorerは非対応
VictoriaMetricsアーキテクチャ

業務で触れる機会のあったVictoraiMetricsというOSSを紹介します。

# VictoraiMetricsとは
以前、[Cortexアーキテクチャ](https://qiita.com/Hiroki1928/items/5c8642987b5f45a1f5e0)を紹介する際、Prometheus ServerのHA構成の問題点について紹介しました。
VictoriaMetricsも同様にPrometheus ServerのHA構成を実現できるOSSです。
Prometheus Serverのremote writeからメトリクスを取得し、ストレージに保存します。

VictoriaMetricsは主に、以下のコンポーネントで構成されます。

- vminsert
    - Prometheus Serverからメトリクス取得する
- vmstorage
    - メトリクスを保存するストレージ
- vmselect
    - Grafana等からメトリクスを問い合わせる

# 構成
VictoriaMetricsは以下のような構成で使用します。
LBはk8s SVCでも可能です。
vmselect / vminsertはstalenessなので、スケールアウト/スケールインの双方が可能です。
一方、vmstorageはstatefulでスケールアウトは可能ですが、スケールインは原則不可となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/a92e6f4c-daa3-86c3-1f08-b088f604ab6f.png)

# VictoriaMetricsの機能
## [Multitenancy](https://github.com/VictoriaMetrics/VictoriaMetrics/wiki/Cluster-VictoriaMetrics#multitenancy)
VictoraiMetricsの[URLフォーマット](https://github.com/VictoriaMetrics/VictoriaMetrics/wiki/Cluster-VictoriaMetrics#url-format)にある通り、accountID / projectIDを設定することが可能です。

例えば、prometheus-server-0とprometheus-server-1のメトリクスを明示的に区別したい場合、別accountIDを設定することでメトリクスを分けることができます。
accountIDとprojectIDは`accountID:projectID`の組み合わせで使用します。
(projectIDを指定しなかった場合、デフォルトで`0`になる）

Prometheus Serverのremote writeから`accountID: 0 / projectID: 0`でメトリクスを保存する場合のURLは以下のようになります。

```
http://<vminsert>:8480/insert/0/prometheus
```

vmselectから`accountID: 0 / projectID: 0`へメトリクス問い合わせを行う場合は以下のようなURLになります。

```
http://<vmselect>:8481/select/0/prometheus/query
```

## [Replication](https://github.com/VictoriaMetrics/VictoriaMetrics/wiki/Cluster-VictoriaMetrics#replication-and-data-safety)
vminsertの`-replicationFactor`というパラメータを設定すると、レプリケーションが有効になります。
vmstorage 3台に`-replicationFactor=2`を設定すると、メトリクスA / メトリクスBがそれぞれ別のvmstorageにコピーされます。
この場合、**vmstorage 1台**に障害が発生しても、データを損失しません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/8abf9ac7-288f-1a89-fbff-ae5f54ce4434.png)


`-replicationFactor=3`を設定するとすべてのvmstorageにメトリクスがコピーされます。
（もちろん、この場合は**vmstorage 2台**までの障害まではデータ損失が起きません）
トレードオフとして、高負荷やストレージ使用量増、Disk I/O増などが挙げられます。

この機能を使用した場合、vmselectでは`-dedup.minScrapeInterval=1ms`を設定し、重複排除を行う必要があります。

## [Deduplication](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/README.md#deduplication)
vmstorage内でも重複排除機能を使用することができます。
先述したvmselectの重複排除とvmstorage内での重複排除が2つあるようなのですが、この章では後者の重複排除について紹介します。

（Replicationの仕組みと矛盾を感じる部分があるので、個人的には使用していない機能です。なので、紹介もざっくりです…）

`-dedup.minScrapeInterval`というパラメータを使用して、重複排除を行います。
Prometheus Serverの`external_labels`で設定したラベルが同一のものを重複排除の対象とします。

## （おまけ）[バックアップ](https://github.com/VictoriaMetrics/VictoriaMetrics/wiki/vmbackup#smart-backups)
バックアップはvmbackupを使用して行うことができます。

# まとめ
VictoraiMetricsというツールがあります！！
[Crotex](https://qiita.com/Hiroki1928/items/5c8642987b5f45a1f5e0) / Thanosに比べてシンプルな構成でPrometheus Serverが冗長化できます。

# 疑問点
Replicationとvmstorage内での重複排除を同時に行った場合、Replicationしたデータを消してしまわないのだろうか。
プログラムで制約を作成する時の注意点

#結論
`translatesAutoresizingMaskIntoConstraints`を`false`にすることです！

#制約のコード
以下の様にコードでviewの制約を設定するとします。
このままだと、立ち上げても反映されていません。

```swift
   let margins = view.layoutMarginsGuide
        redView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
        redView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
        redView.heightAnchor.constraint(equalTo: redView.widthAnchor, multiplier: 2.0).isActive = true
```
そこで`translatesAutoresizingMaskIntoConstraints`が`false`であるコードを書きます。

```swift
   redView.translatesAutoresizingMaskIntoConstraints = false
        let margins = view.layoutMarginsGuide
        redView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
        redView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
        redView.heightAnchor.constraint(equalTo: redView.widthAnchor, multiplier: 2.0).isActive = true
```
こうすることで実装できるそうです。
#translatesAutoresizingMaskIntoConstraintsとは
Auto Layout以前に使われていたAutoresizingMaskのレイアウトの仕組みをAuto Layoutに変更するかを設定するものだそうです。
`translatesAutoresizingMaskIntoConstraints`をFalseにすることでコードでの制約が反映されます。
Dockerでよく使うコマンド一覧

##概要
Dockerを扱う際によく使いそうなコマンドをまとめた個人的メモです。


##コマンド一覧

###1.Dockerイメージのダウンロード
```docker
docker image pull イメージ名
```
※イメージとはDockerコンテナを作成するためのテンプレートのようなもの

###2.ダウンロードしたイメージの起動
```docker
docker run イメージ名
```
※ダウンロードされていない場合はイメージのダウンロードが先に行われた上で起動されます。
また、オプションを指定することで下記のような処理も可能です。

####イメージをバッググラウンド実行

```docker
docker run -d <イメージ名>
```

####コンテナに名前をつけてイメージを実行

```docker
docker run --name <コンテナ名> <イメージ名>
```

####環境変数を指定してイメージを実行

```docker
docker run -e <環境変数名>=<値> <イメージ名>
```




###3.イメージをビルドする
公開されているイメージだけでは、要件を満たせない場合は自分で必要なパッケージや各種設定を含んだイメージを自ら作成して使用することが可能です。イメージはdockerfileに定義することで下記のコマンドでビルドすることができます。

```docker
docker image build -t <イメージ名>  <Dockerfileのパス>
```

####Dockerfileでよく使うコマンド

|コマンド|処理内容|使用例|
|:---|:---|:---|
|FROM|ベースイメージをセットする|FROM ruby:2.7.0|
|RUN|ビルド時に指定のコマンドの実行する|RUN gem install bundler|
|CMD|コンテナ起動時に実行するコマンドを指定する|CMD ["cron", "-f"]|
|ENV|環境変数をセットする|ENV APP_ROOT /hoge|
|ADD|ホスト側のファイルをイメージにコピーする(右の使用例はhogeフォルダの全ファイルをコピーするというもの)|ADD . /hoge|
|COPY|ホスト側のファイルをイメージにコピーする|COPY Gemfile /hoge/Gemfile|
|EXPOSE|ポート番号を指定する|EXPOSE 8080|
|WORKDIR|作業ディレクトリを指定（ない場合は新たに作成）する|WORKDIR /var/www|
|VOLUME|ボリューム(ホスト側のデータをマウントするディレクトリ)を指定する※1|VOLUME /hoge/tmp|


※1：コンテナ内のデータはコンテナの削除と同時に消えてしまうため、データを永続化したい場合は、コンテナの外にデータを置く必要があります。その置き場所のことをボリュームと呼びます。





###4.イメージの一覧を取得する
ダウンロードもしくは自らビルドしたイメージの一覧を取得することができます。

```docker
docker image ls
```


###5.イメージを削除する

```docker
docker rmi <イメージ名> -f
```
※`-f`をオプション指定することで強制削除できる

#### イメージの一括削除
```docker
docker rmi `docker images -q`
```

####ゴミイメージの一括削除

```docker
docker image prune
```

dangling image だけを削除します。dangling image は、なにかの理由（予期せぬエラーなど）でゴミのように残ってしまったイメージのことです。


####未使用イメージの一括削除
```docker
docker image prune -a
```

###6.コンテナの一覧を取得する

```docker
docker container ls
```

###7.コンテナを起動する
```docker
docker start <コンテナID>
```

###8.コンテナを停止する
```docker
docker stop <コンテナID>
```

###9.コンテナを再起動する
```docker
docker restart <コンテナID>
```

###10.コンテナを削除する
```docker
docker rm <コンテナID>
```

###11.コンテナ、イメージ、ボリューム、ネットワークといった全てのDockerリソースを一括で削除
```docker
docker system prune
```

###12.実行中のコンテナをシェル経由で操作

```docker
docker exec -it <コンテナID>  sh
```


###13.ファイルのコピー(コンテナ内 ⇄ ホスト)

```docker
docker cp <コンテナID>:<コンテナ内のコピー元ファイルパス> <ホストのコピー先パス>
docker cp <コンテナID> <ホストのコピー元ファイルパス> <コンテナID>: <コンテナ内のコピー先パス> 
```

###14.docker composeによるマルチコンテナの実行

docker-compose.ymlファイルを作成しdocker-composeコマンドを実行することで複数コンテナの生成・起動が可能となります。コンテナ構築と同時に環境変数の設定やdockwerイメージのビルドも同時に行うことができるため使いこなせば非常に便利です。

例えば
・Webサーバー用コンテナ
・アプリケーション用コンテナ
といった各コンテナ同士を通信させる必要がある場合に、docker composeを利用させることでアプリケーションの実行環境を一括で構築することができます。


docker-compose.ymlファイルに各種設定を記載した状態でそのファイルと同じディレクトリで下記コマンドを実行することで複数コンテナに対する作業が可能となります。

####全コンテナの生成と起動
```docker
$ docker-compose up -d
```

####全コンテナの停止
```docker
$ docker-compose down
```

####全コンテナの起動
```docker
docker-compose start 
```

####全コンテナの再起動
```docker
docker-compose restart 
```

####全コンテナの削除
```docker
docker-compose rm
```
Apache Beam でウィンドウ分割後に連番インデックスを割り当てる StatefulDoFn

[Apache Beam] (https://beam.apache.org/) で、ステートフル (StatefulDoFn) を使用すると、各イベントの処理時に共通して使える状態を持たせることができる。

## 0. テストデータ

次のような8個のイベントデータを処理していくことにする。

```python
events = TestStream().add_elements([
    TimestampedValue(0, 1600000000),
    TimestampedValue(1, 1600000001),
    TimestampedValue(1, 1600000002),
    TimestampedValue(2, 1600000003),
    TimestampedValue(3, 1600000004),
    TimestampedValue(5, 1600000005),
    TimestampedValue(8, 1600000006),
    TimestampedValue(13, 1600000007),
])
```

## 1. `IndexAssigningStatefulDoFn` を用いて各イベントに連番でインデックスを割り当てる

`IndexAssigningStatefulDoFn` は以下のリソースを参考にして次にように作成した。

- Beamのステートフル処理を紹介している公式ブログ記事: [Stateful processing with Apache Beam](https://beam.apache.org/blog/stateful-processing/)
- Beamのテストコード: [beam/sdks/python/apache_beam/transforms/userstate_test.py](https://github.com/apache/beam/blob/30f9a607509940f78459e4fba847617399780246/sdks/python/apache_beam/transforms/userstate_test.py)

この DoFn は、`INDEX_STATE` というインデックスを保持しておくステートを持っていて、イベントを1つ処理するごとに現在のインデックスを割り当て、インデックスを1インクリメントする。

```python
class IndexAssigningStatefulDoFn(beam.DoFn):
    INDEX_STATE = CombiningValueStateSpec("index", sum)

    def process(self, element, state=beam.DoFn.StateParam(INDEX_STATE)):
        unused_key, value = element
        current_index = state.read()
        yield (current_index, value)
        state.add(1)
```

次のようなコードで、0. で作ったテストデータに対して `IndexAssigningStatefulDoFn` を適用 (ParDo) させるようなパイプラインを実行すると、各イベントに連番でインデックスを付けることができる。

**パイプラインコード**

```python
_ = (p
    | events
    | beam.Map(lambda x: (None, x))
    | beam.ParDo(IndexAssigningStatefulDoFn())
    | beam.Map(print))
```

**出力**

```
(0, 0)
(1, 1)
(2, 1)
(3, 2)
(4, 3)
(5, 5)
(6, 8)
(7, 13)
```

※ タプルの1個目がインデックスで、2個目がイベントデータ本体

## 2. 【問題】ウィンドウへ分割後のデータに対するインデックス割り当てがうまくいかない

元のデータを Fixed window (サイズは2) へ分割後に各ウィンドウごとのイベントデータをリストにまとめて、各リストに対して連番でインデックスを割り振ろうとするとうまくいかない。

**パイプラインコード**

```python
_ = (p
    | events
    | beam.WindowInto(beam.window.FixedWindows(size=2))
    | beam.CombineGlobally(beam.combiners.ToListCombineFn()).without_defaults()
    | beam.Map(lambda x: (None, x))
    | beam.ParDo(IndexAssigningStatefulDoFn())
    | beam.Map(print))
```

**出力**

```
(0, [0, 1])
(0, [1, 2])
(0, [3, 5])
(0, [8, 13])
```

全部のイベントデータにインデックス 0 がついてしまう。

## 3. 【解決法】ウィンドウ分割後に再度グローバルウィンドウに入れる必要がある

Fixed windows へ分割後のデータを再度 Global window へ入れると解決する。

**パイプラインコード**

```python
_ = (p
    | events
    | beam.WindowInto(beam.window.FixedWindows(size=2))
    | beam.CombineGlobally(beam.combiners.ToListCombineFn()).without_defaults()
    | "Global Windows" >> beam.WindowInto(beam.window.GlobalWindows())  # ここが差分
    | beam.Map(lambda x: (None, x))
    | beam.ParDo(IndexAssigningStatefulDoFn())
    | beam.Map(print))
```

**出力**

```
(0, [0, 1])
(1, [1, 2])
(2, [3, 5])
(3, [8, 13])
```

ちゃんと連番でインデックスが振られる。

## Appendix

フルのソースコードはこちら:
https://gist.github.com/kotarot/1da48904557b2e2cbd5a159fa1acf9fc
BlynkとM5Stackをつなぐ

# 概要
BlynkでUIを作成し、ボタン入力をM5StackがBLE通信で受け取れるようにします。
[Blynk](https://blynk.io/)はiOSやAndroidのアプリで、簡単にUIを作成しマイコン等のデバイスと簡単に通信してごにょごにょできるありがたいやつです！

# 開発環境
* OS: MacOS Mojave
* エディタ:Visual Studio Code
* IDE: PlatformIO (VSCodeの拡張機能)
* マイコン: M5Stack GRAY

# Blynk側設定
いろんな記事があるので詳細は割愛しますが、以下のような手順で設定していきます。

###　手順
1. New Projectをタップ
2. Project Nameを入力
3. CHOOSE DEVICEは`ESP32 Dev Board`を選択
4. CONNECTION TYPEは`BLE`を選択
5. CREAATE PROJECTをタップ
6. `BLEウィジェット`、`ボタンウィジェット`を置く
7. ボタンウィジェットのPINを`Virtual`にし、V0等のピン番号を選択する

**authkeyをメールで受け取るか設定画面で確認しておきます。**

### BlunkのUI
(ラジコン作る過程だったのでそういう感じになっています)
右上にRUNボタンがありますが、BluetoothはRUNしていない状態で接続しておく必要があります。

![IMG_7231.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84072/64c4a28a-29b8-3f16-2e05-f2019e8a9b56.png)


# M5Stack側プログラミング
こちらと同じくVSCode+PlatformIOを使用している方は、HOMEから`Blynkライブラリ`を導入しておいてください。

Blinkのボタンを押したときにバーチャルピンに値を書き込むように設定しており、それを受信するコードは`BLYNK_WRITE`だったということにたどり着くのに時間がかかりました...
`BLYNK_READ`だと`param`が宣言されていないと怒られます。

```cpp:blynk_test.cpp
#include <Arduino.h>
#include <M5Stack.h>
#include <BlynkSimpleEsp32_BLE.h>

char blynkAuth[] = "auth keyを入力";

// 変数
int v1 = 0;
int v2 = 0;
int v3 = 0;

// blynk functions
BLYNK_WRITE(V1){
  v1 = param.asInt();
}

BLYNK_WRITE(V2){
  v2 = param.asInt();
}

BLYNK_WRITE(V3){
  v3 = param.asInt();
}

void setup(){
  // LCD設定
  M5.begin();
  M5.Lcd.setBrightness(100);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(WHITE, BLACK);

  Blynk.setDeviceName("M5Stack");
  Blynk.begin(blynkAuth);
}

void loop(){
  M5.Lcd.setCursor(0, 20);
  M5.Lcd.printf("V1:%d  V2:%d  V3:%d", v1, v2, v3);
  Blynk.run();
  delay(100);
}


```

# 動作確認
M5Stackへソースコードを書き込みます。
Blynkアプリから作成したUIを開き、BLEウィジェットをタップしてM5Stakとコネクトします。
RUNボタンでBlynkを動かし、ボタンを押したりすることでM5StackのLCDの値が変化することを確認できたら成功です！

![IMG_7232.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84072/9ab11c3e-d2e3-55c9-b4b9-3af33f4fe0b3.jpeg)
MacHDをエラーで消去（初期化）できない時の対処法

これまで使用していたMac（OS Catalina）のTime machineバックアップデータを古いMac(OSがSierra)に入れた際にエラーが起こりました。初期化するためMachintoshHDを消去しても実行できず、First Aidもエラーで実行できません。
こういう場合、**HDに新しいボリュームを上書きする**ことで解消することがあります。

MacOSユーティリティの一番下「ディスクユーティリティ」をクリックして開きます。
![スクリーンショット 2020-12-05 15.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254733/2aecd79d-d099-833d-0416-45b69a89a212.png)


メニューバーにある「表示」から「すべてのデバイスを表示」を選択すると、Macハードディスク内のボリュームをすべて確認できるようになります。

![IMG_8482.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254733/d6904439-e2c8-6c92-ee45-2d00272698ca.jpeg)


HDの本体を選んで二本指タップで「パーティションを作成」を選択します。
![IMG_8493.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254733/23205831-c481-b2d8-a117-6bd5db7732de.jpeg)

**パーティションの数を追加せずに新しいパーティションのフォーマットを指定**します（macOS 10.13以上を入れるときは APFS、それ以前のOSの場合はMac OS拡張（ジャーナリング）を選ぶ）。
![IMG_8496.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254733/57a5b34b-ebff-dc04-5538-c9100e36792a.jpeg)


実行すると「APSF（またはMacOS拡張）のHDデータは消去されます」と出るので続けて実行すると、元のエラーの出ていたHDディスク領域は消去されて新しいディスク領域に置き換わります。

MacHDのフォーマットを <id="APFSからMacOS拡張(ジャーナリング)に変更する">**APFSからMacOS拡張(ジャーナリング)に変更する**</id>のも同じ方法で実行できます。

検索しても解決できなかったので、共有のために書いておきます。
Firebaseのメッセージ受信からアプリ起動までの覚書

本記事は[Android Advent Calendar 2020](https://qiita.com/advent-calendar/2020/android)の2020/12/05分です。

PUSH通知受信のためにFirebaseを使うことが多いと思いますが、
私毎回業務でやるたびにアプリ起動でハマるので2020年で終えれるようこちらの記事を書かせていただきます。

# サンプルプロジェクト

実務でのコードを使うことはできないので、類似のサンプルプロジェクトを作成しました。
[FirebaseSample](https://github.com/shinya-takano/FirebaseSample)
※google-servies.json はサーバにUPしていませんのでビルドはそのままだとできないです。

Firebaseの導入〜メッセージ送信までは[公式ガイド](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ja#kotlin+ktx)に丁寧に記載があります。
(本当ありがたいです...ちなみに最近ドキュメント変わった？BoM めっちゃ便利ですね..)

# 本題: 通知とデータペイロードが両方ある場合のアプリ起動について

こちらの[ページ](https://firebase.google.com/docs/cloud-messaging/android/receive?hl=ja)に全てまとまっています！

抜粋すれば、このスクリーンショットにも収まります..

![summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/472c46c1-81b9-a538-e3f8-027ee1230db3.png)

この
**バックグラウンドでかつ両方**
**通知： システムトレイ、データ: インテントの追加部分内**

が曲者でした。

## 当時のアプリの構成

### 主なActivity

- SplashActivity スプラッシュ画面を表示して、MainActivityに遷移する
- MainActivity MainのActivityとして各種画面を表示する

### PUSH通知の要件

- 通知は notification を表示する
- payload に type や ログ集計するためのパラメータが渡され、起動時にログ集計や画面の出し分けをする

### 困ったこと（ハマったこと）

- アプリが起動している場合はパラメータをきちんと取得できて、要件通りの挙動をするが、アプリキルされている場合にパラメータを取得できずログ集計や画面の出しわけができなかった

### 原因

```
この場合、通知はデバイスのシステムトレイに配信され、データ ペイロードはランチャーアクティビティのインテントの追加部分に配信されます。
```

公式ドキュメントにしっかり書いてありますが、バックグラウンドからのアプリ起動時はランチャーアクティビティのインテントに設定されていたため...

つまり、画面を出しわけするMainActivityに以下のようにだけ実装するのは不十分で..

```kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(findViewById(R.id.toolbar))

        val date = intent.extras?.getString("date") ?: ""
        val screen = intent.extras?.getString("screen") ?: ""
        Log.d("MainActivity", "$date=$screen")
    }
```

SplashActivityからデータを渡してあげる必要がありました..

```
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        val date = intent.getStringExtra("date")
        val screen = intent.getStringExtra("screen")
        Log.d("SplashActivity", "$date=$screen")

        GlobalScope.launch {
            delay(2000)
            val intent = Intent(this@SplashActivity, MainActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
            intent.putExtra("date", date)
            intent.putExtra("screen", screen)
            startActivity(intent)

            finish()
        }
    }
```

### 解決策

今回は上述の通り、SplashActivityからもMainActivityにインテントのデータを渡すことで解決しました。
特定の場合のみ変わるとかハマりそうですが、Firebaseからの実装の仕組み見ると理解できるんだろうなぁ..

あと、自分の場合は上記のような形で困ったことがありましたが、アプリの実装によって再現したりしなかったり..
別の解決方法もあると思います。

# まとめ

android で Firebase でPUSH通知することがよくありますが、
アプリ起動に関する処理は複雑になりがちで Firebase の仕様もあいまって
ちょいちょいハマるのでまとめてみました。

来年は同じことでハマる時間が短くなる（覚えていること）といいです..
【入門】React概要

# はじめに
Reactを学ぶ機会があったので、個人的にまとめようと思います。
マサカリお待ちしております。

# Reactとは？
・Reactとはユーザーインターフェースを構築する為の（UI）javascriptライブラリです。
・宣言的で効率的かつ柔軟性が優れている為「コンポーネント」と言われる孤立したコードから複雑なUIを作成できます。
・Facebook社が開発したライブラリ

# コンポーネント
ReactはUIを「コンポーネント」という部品単位で構築する。
コードを含むことができてプログラムとして再利用できる
### 関数コンポーネント
状態を持たないコンポーネント

```js
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

### クラスコンポーネント

```js
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

Hooks導入前はクラスコンポーネントでは以下の物が使えた
・状態管理(State)
・[ライフサイクルメソッド](https://reactjs.org/docs/react-component.html)

現在ではHooksが導入されたことによりFunction ComponentでもuseState、useEffectなどを使って、Stateやライフサイクルに相当するものが使えるようになっている。

[Hooksの概要](https://ja.reactjs.org/docs/hooks-overview.html)



# props
Propertiesの略でコンポーネントのプロパティ。
基本的に親コンポーネントから子コンポーネントに渡される値のことを指す

```js
<child props={value}/>
```
親コンポーネントから子コンポーネントに値を渡すときは上記のような書き方をする。
このとき子コンポーネントでは、もらった値（value)をpropsという名前として扱うことが可能です。

具体的には下記のような書き方をします。 ※Todoアプリを例に書きます。

```App.js
import React from 'react';
import Child from '../../components/Form.js'; //子コンポーネント

class App extends React.Component {　//親コンポーネント
  constructor(props) {  //初期値をセット
    super(props);　　//明示的に記述

　　 this.state = {　//stateの初期値をセット
      value: '',
      todos: [],
  }
}

handleChange = (e) => {
    this.setState ({ value : e.target.value })  //入力された文字
  }

handleSubmit = (e) => {
    e.preventDefault();
    if(this.state.value === '') return  //空文字の登録を不可にする
    this.state.todos.push(this.state.value)  //todosにvalueを追加
    this.setState({  //setState()内でstateの値を変更
      todos: this.state.todos,
      value: '',  //フォームに入力されている文字を空にする
    })
  }

  render(){
    return(
      <React.Fragment>
        <Form   //Formコンポーネント(子)に関数とstateを渡す
          handleChange={this.handleChange}
          handleSubmit={this.handleSubmit}
          value={this.state.value}
        />
      </React.Fragment>
    )
  }
}

export default App;
```
```Form.js
import React from 'react';

const Form = props => {   //引数でAppコンポーネントからpropsを受け取る。
  return (
    <form onSubmit={props.handleSubmit}>
      <input
        type="text"
        onChange={props.handleChange}
        value={props.value}
      />
      <button type="submit">Add</button>
    </form>
  )
}

export default Form;
```

上記の例では、親コンポーネントから下記をもらっています。
・フォームに入力された文字
・登録ボタンを押した時の挙動
　- フォームをから文字にする
　- todoのvalue
　- 空文字登録不可
・value

```js

<Form
    handleChange={this.handleChange}
    handleSubmit={this.handleSubmit}
    value={this.state.value}
  />
```

# State
コンポーネントの状態
State自体はコンポーネントからコンポーネントへは渡されず各コンポーネント自体で管理

constructorで初期値を割り当てる

```js
constructor(props) {
  super(props);//親のconstructorを呼び出し
  this.state={ //superによってthisが使えるようになる
    value: '',
    todos: [],
  };
}
```

子コンポーネントからもらった値を元にsetStateで値を変更します。

```js

this.setState({  //setState()内でstateの値を変更
   todos: this.state.todos,
   value: '',  //フォームに入力されている文字を空にする
})
```


# JSX
・JSXとは「JavaScript XML」の略で、XML風に作られたJavaScriptの拡張シンタックス（構文）です。
・見た目がHTMLやXML寄りなので可読性が高い

#### メリット
・トランスパイルという処理が施されjavascriptに変換される
・JSX、javascriptを用いた場合表示は同じ
・比べると最終的に表示させたい時に、JSXの方がHTMLと書き方が似ている為、直感的に表現できる


# 最後に
随時更新中です。
数値型について【Swift】

# 数値型とは
数値型は、名前の通り数値を表します。
Swiftの数値型を大きく分類すると`整数型`と`浮動小数点型`に分けることができます。


# 整数型
整数型は、整数を表す型になります。主に`Int型`、`UInt型`があります。

### 1. 整数型の最大値と最小値
スタティックプロパティ（型に紐づくプロパティ）が用意されています。

```Swift
// 最小値
let a = Int8.min // -128
// 最大値
let b = Int8.max // 127
```
### 2. 整数型の範囲
|      | 範囲 |
| ---- | ----- |
| Int（ 実行環境32bit ） | -2147483648 〜 2147483647 |
| Int（ 実行環境64bit ） | -9223372036854775808 〜 9223372036854775807 |
| Int8 | -128 〜 127 |
| Int16 | -32768 〜 32767 |
| Int32 | -2147483648 〜 2147483647 |
| Int64 | -9223372036854775808 〜 9223372036854775807 |
| UInt（ 実行環境32bit ） | 0 〜 4294967295 |
| UInt（ 実行環境64bit ） | 0 〜 18446744073709551615 |
| UInt8 | 0 〜 255 |
| UInt16 | 0 〜 65535 |
| UInt32 | 0 〜 4294967295 |
| UInt64 | 0 〜 18446744073709551615 |

* `Int型`は符号あり、`UInt型`は符号なしになります。
* `Int○`や`UInt○`の`○`に入る数字は`bit数`になります。またパソコンは`2進数`を使います。


# 浮動小数点型
浮動小数点型とは、浮動小数点方式で小数を表す型になります。主に`Float型`と`Double型`があります。
* `Float型` ・・・ 32bit（およそ10の38乗の正負の値まで表すことができる）
* `Double型` ・・・ 64bit（およそ10の308乗の正負の値まで表すことができる）

### 1. 浮動小数点型の特殊な値（無限大）
値が大きくなりすぎて`Float型`や`Double型`で扱えない数を表す。
* `infinity` ・・・ 無限大を表すスタティックプロパティ
* `isInfinite` ・・・ 無限大かどうかを判定するインスタンスプロパティ（`Bool型`）

```Swift
import Foundation

let a: Double = Double.infinity
a.isInfinite // true

let b: Double = pow(10, 309) // 10の309乗
b.isInfinite // true
```

### 2. 浮動小数点型の特殊な値（非数）
不正な値で演算をし、演算できなかったことを表す。
`Not a Number`を略して`NaN`と表現される。
* `nan` ・・・ `NaN`を表すスタティックプロパティ
* `isNaN` ・・・ 値が`NaN`かどうか判定するインスタンスプロパティ（`Bool型`）

```Swift
let a: Double = Double.nan
a.isNaN // true

let b: Double = 0.0 / 0.0
b.isNaN // true
```
設計に使えるツール ~drawio~

#はじめに
なにか作るとき、フローチャートとかＵＭＬ図を描く手時に便利なツール[drawio](https://app.diagrams.net/)を紹介します！


#便利機能
・フロチャ～ＵＭＬ様々な図に対応
ほとんどの設計図に対応した図形が用意されている。

・GoogleDriveに対応
作った図や一緒に開発する人へ図をgmailを通じて共有できる。
グループワークや知識の共有に役立つ！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/2da34179-e93f-d2fe-0d41-75a426d96bd8.png)

・GoogleDriveに対応
作った図や一緒に開発する人へ図をgmailを通じて共有できる。
グループワークや知識の共有に役立つ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/41c9353b-1734-55f2-48ac-0e271b81604e.png)



#所感
ちょっとしたものでもこれを使って、設計から入る癖をつけたいと思う。
Ruby on Rails rails db:migrateが出来ない An error has occurred, this and all later migrations canceled:  エラー文SQLite3::SQLException: duplicate column name: ID


Railsでカレンダーアプリを作成していた際、rails db:migrateをしたところ、```An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: ID```というエラーが発生し、テーブルを作成出来ませんでした。

エラーを調べていくと、テーブルの中に同じカラムデータがある、との事。
今回の場合は、「ID」というカラムが被っているらしい。

そこで、作成されたマイグレーションファイルを見ると、
IDが被っている様子は無さそうだが、、、

```20201205064441_create_tasks.rb

class CreateTasks < ActiveRecord::Migration[6.0]
  def change
    create_table :tasks do |t|
      t.integer :ID
      t.string :title
      t.datetime :start_day
      t.datetime :Finish_day
      t.string :time

      t.timestamps
    end
  end
end
```

と、考えていたら、

そもそも、IDって自動で作成されるよな、と思い、ID部分をコメントアウト。

```20201205064441_create_tasks.rb

class CreateTasks < ActiveRecord::Migration[6.0]
  def change
    create_table :tasks do |t|
      #t.integer :ID
      t.string :title
      t.datetime :start_day
      t.datetime :Finish_day
      t.string :time

      t.timestamps
    end
  end
end
```

これで、rails db:migrateしたら成功致しました。

アホでした。。。
Rails ユーザー編集機能の実装

#はじめに
ユーザー管理機能(ログイン/ログアウト)を実装したあとに、ユーザー編集機能を実装しました。バリデーションで少してこずったので、書き記します。

**開発環境**
ruby 2.6.6
rails 6.0.0

#目次
1.ルーティング
2.コントローラー
3.モデル

#1.ルーティング
編集機能実装にあたり、「edit」及び「update」アクションをルーティングとして追加する。

```ruby:config/routes.rb
resources :users, only: [:edit, :update]
```
#2.コントローラー
ターミナルでuserコントローラーを作成する。想定として、一度ユーザーの「nickname」、「email」、「パスワード」を新規登録しており、後から「nickname」と「email」を編集できるようにする。

```bash:ターミナル
rails g controller users
```

作成したコントローラーに下記記述を追記する。deviseはインストール済みなので、「current_user」メソッドが使用できる。userテーブルには「nickname」と「email」がカラムとして既に存在している。

```ruby:app/controllers/users_controller.rb
def edit
    end

def update
  if current_user.update(user_params)
    redirect_to root_path
  else
    render :edit
  end
end

private
def user_params
  params.require(:user).permit(:nickname, :email)
end
```

#3.モデル
パスワードに関するバリデーションに「on: :create」を追加する。このオプションによりパスワードに関するバリデーションは新規登録のみ適用される。ちなみにこのcreateオプションを追加しないと、「nickname」、「email」を正しく更新できない。(パスワードの入力がないためバリデーションで拒否される)

```ruby:app/model/user.rb
with_options presence: true do
---------------中略-----------------
    PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i.freeze
    # 半角アルファベット（大文字・小文字・数値）
    validates :password, format: { with: PASSWORD_REGEX, message: 'はアルファベットと数字を含めてください' }, length: { minimum: 6 }, on: :create
  end
```
以上
[JavaScript] JasmineからJestへの移行

4年ほど前に作ったAWS Lambdaプロジェクトがありました。
もろもろ更新しようとAWS SAMでプロジェクトを作り直したところ、テストライブラリとして [Jest](https://jestjs.io/ja/) が入っていました。

移行する必要があるのか？
と言われると、ないですけれど、
趣味なのでやってみます。

# テストファイルの場所を移動する

テスト対象ファイルとテストファイルを同一ディレクトリに置いていました。

```
src/lib/myclass.js
src/lib/myclass.spec.js
```

Jestは賢いからか、このままでもきちんとテストを見つけて実行してくれます。

ただここは、AWS SAMの流儀に従って場所を分けました。

```
src/lib/myclass.js
__tests__/lib/myclass.spec.js
```

## `require` を書き換え

テストファイルの場所を移動したので、`require`を書き換えました。

```js:Before
const myclass = require('./myclass')
```

```js:After
const myclass = require('../../src/lib/myclass.js');
```


# ファイル名を変更……する？

テストファイルには `*.spec.js` という拡張子をつけていました。

`*.test.js` のほうが、流儀っぽいです。

ここは、~~面倒なので~~そのままにしておきます。


# モックの書き換え

Jasmineのスパイを、Jestのモックへ書き換えます。

## モックの作成

作成部分はこうなりました。

```js:Before
const dbx = jasmine.createSpyObj('Dropbox', [
    'filesListFolder',
    'filesListFolderContinue',
    'filesGetTemporaryLink'
]);
```

```js:After
const dbx = {
    filesListFolder:jest.fn(),
    filesListFolderContinue:jest.fn(),
    filesGetTemporaryLink:jest.fn()
};
```

## 戻り値の設定

Jasmineは`and.returnValue()`で戻り値を設定していました。

```js:Before
dbx.filesListFolder.and.returnValue(
    new Promise(resolv => {
        resolv({ entries: [], has_more: false });
    })
);
```

Jestは`mockReturnValueOnce()`を使うようです。

```js:After
dbx.filesListFolder.mockReturnValueOnce(
    new Promise(resolv => {
        resolv({ entries: [], has_more: false });
    })
);
```

## 複数回呼び出されたときの戻り値の設定

Jasmineは戻り値を複数個並べていました。

```js:Before
dbx.filesListFolderContinue.and.returnValue(
    new Promise(resolv => {
        resolv({ entries: [], has_more: true, cursor: dummyCursor2 });
    }),
    new Promise(resolv => {
        resolv({ entries: [], has_more: false });
    })
);
```

Jestは`mockReturnValueOnce`を必要回数呼び出せばよいようです。


```js:After
dbx.filesListFolderContinue.mockReturnValueOnce(
    new Promise(resolv => {
        resolv({ entries: [], has_more: true, cursor: dummyCursor2 });
    }));
dbx.filesListFolderContinue.mockReturnValueOnce(
    new Promise(resolv => {
        resolv({ entries: [], has_more: false });
    })
);
```

# 非同期関数のテスト

`async`関数の戻り値は`expectAsync()`で待ち受けて、`toBeResolvedTo`でテストしていました。

```js:Before
await expectAsync(actual).toBeResolvedTo('http://hoge.example.com/');
```

Jestは`expect()`にして、`resolves`プロパティの値をテストすればよいようです。

```js:After
await expect(actual).resolves.toBe('http://hoge.example.com/');
```

# 実は自動的に移行できたかも？

終わってみてから気づきました。

[移行するためのコマンド](https://jestjs.io/docs/ja/migration-guide)がありました。

```console
npx jest-codemods
```

これを使えば、何もすることなかったかも？