OmniAICreator/Qiita-1.07M huggingface dataset:
re:dashのREDASH_MULTI_ORG機能の適用方法とデバッグ方法

# REDASH_MULTI_ORGを利用する
## 概要
- redashで複数組織を管理したい場合(互いにダッシュボードを見れないように管理したい場合)REDASH_MULTI_ORG機能を利用する必要がある。
- groupsは組織内でユーザ権限を分けることはできるが、組織単位で制御ができない。
- 今回はdocker-imageから引っ張って来たre:dashで検証
- REDASH_MULTI_ORGはドキュメントが少ないので、手順とデバッグの方法を記載する。

## REDASH_MULTI_ORGの適用手順
1. envにREDASH_MULTI_ORG=trueを追加する。
2. docker-compose downで一度コンテナを削除する
3. docker-compose up -d でコンテナを再生成する ←この時にenvが適用されるようでrestartだと適用されない模様
4. `http://{URL}/login`→ `http://{URL}/default/login`でアクセスする  
`organizations`テーブルの `slug`がpathに適用されるため、デフォが `default`になる。(←ここが分からずハマった。。)
5. `organizations`テーブルに  
```insert into organizations (updated_at,created_at,name,slug,settings) values (now(),now(),'Test','test_org','{}');```のように新しい組織を突っ込む
6. 5で突っ込んだ組織のidで `update users set org_id={5で追加したorg_id} where id={user_id};`ユーザを更新する。
7. `http://{URL}/test/login`で新しい組織でアクセス可能になる。



## デバッグ方法
- `docker exec -it -u root redash_server_1 bash`でappコンテナに入る
- `apt update; apt install vim`でとりあえずvimを入れる
-  `〜.py`を編集し、printなどを仕込む。編集したファイルと同名の `〜.pyc`を削除する
-  `python`→`import py_compile`→`py_compile.compile('〜.pyc')`でコンパイルし直す。
-  `chown redash.redash 〜.pyc `
-  コンテナからexitし、`docker restart redash_server_1`でコンテナをrestartする。
-  `docker logs -f redash_server_1`でログを出力する
-  `http://{URL}/default`などでアクセスしてログを確認する。


## まとめ
OSSのコード真面目に読んでデバッグしたことがあまりなかったので勉強になりました。
REDASH_MULTI_ORGの詳細な利用方法など、redashのドキュメントが充実していない仕様があるようなので、躓きポイントは記事などに落とし、シェアできると幸せになれる気がしました！
(↑我流でやったので良法があればコメントくださいmm)
TrailheadのPlaygroundにモバイルでログインするには

## 【事前準備】ログイン用のアカウント確認&パスワードを設定する
まずはPlayground側で、モバイルログインするためのIDの確認とパスワードリセットを実施します。
<a href="https://trailhead.salesforce.com/ja/content/learn/modules/trailhead_playground_management/get-your-trailhead-playground-username-and-password">Trailhead Playground のユーザ名とパスワードの取得</a>に記載の手順で確認＆設定。

## モバイルにてSalesforceアプリをダウンロード
App CenterないしはGoogle Playにて「Salesforce」で検索すればでてきます。

## アプリでログイン
・環境は「本番環境」のままでOK
・【事前準備】にて、Playground側で確認したIDと設定したパスワードでログイン！

別のPlaygroundにログインしたい場合は、その環境でそれぞれ【事前準備】が必要です。
Excel 2019 for Mac OS判定とAppleScriptTask利用方法

#Excel 2019 for Mac OS判定とAppleScriptTask利用方法

Excel 2019 からライセンス体系が変わり、永続版のWindows版とMac版両方をインストールする事が可能になりました。また Office365 でも同じようにインストールが可能になっています。OS の垣根を越えてアプリが使えるようになるのは素晴らしい事ですが、 VBAプログラマーの悩みが増えることも事実です。

Windows版のCreateObjectが全て使えないのは勿論、セキュリティ関連のダイアログにより操作性が失われる事も考慮しなくてはなりません。これらの問題を回避するのはAppleScriptを使用するしかありません。

##OS判定方法
OS事に処理を変える以上、判定方法が必要になります。私が開発しているAndroid ハンディターミナルアプリ [Forme](https://play.google.com/store/apps/details?id=com.suisya2015noriagmail.formelite)ではデータの管理の為にWindowsとMac両OSに対応したエクセルファイルFormeCollector2.xlsmをインクルードしています。そこで利用しているコードがこちらです。

~~~
If Not Application.OperatingSystem Like "*Mac*" Then
    Windowsの処理
else
    If val(Application.Version) < 15 Then
        Excel2011 for Macの処理
    else
        #If MAC_OFFICE_VERSION >= 15 Then
            Excel2016 for Mac以降の処理
         #end if
    end if
end if
~~~

Mac版ではExcel2011とExcel2016以降の判定分けをMAC_OFFICE_VERSIONで行っていますが、Excel2016以降のみを対応している場合は不要です。尚、コードが冗長になっていますが安定性重視でこのような形になっています。

実際に利用される際は独自関数にする事をお勧めします。私自身はいつかやろうと思いながら、ここまで放置していますが・・・。

##以前の方法 : MacScript関数

Excel2011ではVBA内にAppleScriptをインラインで記述し、MacScript関数で実行する事ができましたが、Excel2016以降、セキュリティ上の観点から廃止されました。Excel2019で実行するとエラーにはなりませんが、常に<b>FALSE</b>が帰ってきます。

~~~
Sub MacScriptTest()

//フォルダ選択ダイアログ（選択したフォルダの絶対パスが返ってくる）

Dim str As String
Dim appscript As String
appscript = "tell application ""Finder""" & vbNewLine & "try" & vbNewLine & "choose folder with prompt ""formeCSVmodule""" _
& vbNewLine & "on error number err_num" & vbNewLine & "False" & vbNewLine & "end try" & vbNewLine & "end tell"

str = MacScript(appscript)
If str <> "False" Then
    ActiveCell.value = Replace(str, "alias ", "")
Else
    ActiveCell.value = "False"
End If

End Sub
~~~

Excel2019結果
![mac2019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/8636d31c-df70-0133-0b3d-ed5e1aad8c7c.png)
Excel2011結果
![mac2011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/7ddca4d5-960d-c1c1-e181-fcc67e1c3761.png)
尚、Windows版で実行するとエラーが発生します。OS判定は必ず必要です。
![macscript.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/fb2054e3-c7f1-9c16-7031-52831f534a05.png)

##AppleScriptTaskの使い方

利用するまでの手順は主に２段階となります。

1. スクリプトファイルを ~/Library/Application Scripts/com.microsoft.Excel/に保存する。
2. VBA内でAppleScriptTaskからスクリプトファイルを呼び出す。

1.が特に厄介です。ライブラリーフォルダは通常操作ではみる事ができないので、ターミナルか Finder > 移動(optionを押して) から移動する必要があります。
![libraryfolder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/70536b59-5652-e091-3db0-8ecd58255044.gif)
配布の点ではかなりハードルが高くなります。次の2.VBA内でAppleScriptTaskからスクリプトファイルを呼び出すはそこまで難しくありません。

~~~
Sub ASTaskTest()

Dim dirpath As String

dirpath = AppleScriptTask("AppleScriptファイル名(拡張子不要)", "スクリプト名", "引数")

End Sub
~~~

もし存在しないAppleScriptファイルを呼び出した場合エラーが発生します。これもWindows版ではエラーが発生するのでOS判定は必ず必要です。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/1e52f032-ac32-ebbd-8f29-fe6cf5398cb3.png)

FormeCollector2.xlsmではスクリプトファイルがない場合は自動的に作成するようになっています。VBAではライブラリーフォルダにアクセスできないので、移動はユーザーにしてもらう必要があるのが難点ですが、別に[インストールアプリ](https://www.the-forme.net/collector.html)を配布するなどして工夫しています。
備忘録:(デプロイ後のデバッグ方法)

### herokuへのデプロイ後のエラー対処方法

+ エラーが発生していると、ブラウザ上に『We're sorry, but something went wrong.』という文字が表示される
+ このままではどのようなエラーかわからないのでエラーログを確認する

### heroku logsコマンド
+ Heroku上のアプリケーションが稼働したログを、表示するためのコマンド
+ ログは非常に長いため、かつ常にアプリケーションのログは更新し続けるため、--tailというオプションをつける

###  --tailオプション
+ ログの最後の10行を表示するためのオプション
+ Linuxコマンドにおけるtail -fというコマンドと同様の働き

```bash
% heroku logs --tail --app アプリケーション名

```
SalesForceのApexについて！

##まず最初に
trailheadの非同期Apex
https://trailhead.salesforce.com/ja/content/learn/modules/asynchronous_apex?trail_id=force_com_dev_intermediate

###非同期処理の基本
###futureメソッドの使用
###Apex一括処理の使用
###Queueable Apexを使用したプロセスの制御
###Apexスケジューラを使用
###非同期Apexの監視
Rails Credentials メモ

現場で用いていたため、言語化できるように調べる

##「Credentials」とは
**production(本番)環境**に関する特定の方式で管理される**秘密情報**のこと
また、**管理する仕組み**を指す

Rails5.2から導入された機能

APIの秘密鍵等の機密情報を管理するのは、難しい
・アプリが秘密情報を利用できるようにしたい
・開発者が必要に応じて、確認、変更したい。また開発者同士で共有したい
・リポジトリに機密情報を格納すると、漏洩の危険性がある

##使い方
production環境の秘密情報は、「**config/credentials.yml.enc**」
に記載する

このファイルは、常に暗号化された状態で保存される

ファイルは、Railsが用意している専用コマンドで動作する

Railsのアプリケーションがproduction環境で起動された際には
`master.key`ファイルもしくは、`RAILS_MASTER_KEY`環境変数から
キー情報を取り出して、秘密情報を内部的に復号して利用する

#参考記事、書籍
現場Rails
【Android】ラジオボタンを追加する方法

#プログラミング勉強日記
2020年12月26日
Androidアプリ開発でラジオボタンを作成したのでその方法を簡単にまとめる。

#ラジオボタンを利用するときに使うクラスとメソッド

- RadioButton
- RadioGroup
- onCheckedChangeListener
- void check(int id)
- int getCheckradioButtonId()
- void clearCheck()

　
　RadioButtonはそれぞれの項目に相当するクラス。
　RadioGroupは複数のRadioButtonを持ち、それらの1つだけ選択できる。
　OnCheckedChangeListenerは選択されている項目が変わった時に通知を受ける。
　void check(int id)は引数で指定したラジオボタンを選択するメソッド。
　int getCheckradioButtonId()は選択中のラジオボタンのIDを取得するメソッド。
　void clearCheck()は選択を解除するメソッド。

#ラジオボタンを配置する方法
　レイアウトエディタのパレットからRadioGroupを選択し、レビュー画面にドラッグする。次にRadioButtonをRadioGroupまでドラッグして追加する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/37ffea7f-a287-76af-640d-6de5f6d604b9.png)

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout_editor_absoluteX="154dp"
        tools:layout_editor_absoluteY="212dp"
        tools:ignore="MissingConstraints">

        <RadioButton
            android:id="@+id/radioButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="RadioButton1" />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="RadioButton2" />

        <RadioButton
            android:id="@+id/radioButton3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="RadioButton3" />
    </RadioGroup>

</androidx.constraintlayout.widget.ConstraintLayout>
```



#参考文献
[ラジオボタンで複数の選択肢から１つを選択させる / GETTING STARTED](https://techbooster.org/android/ui/9640/)
[Androidアプリ開発でRadioButton(ラジオボタン)を追加する方法](https://techacademy.jp/magazine/3501)
20日目：リストバンド型入場券で学ぶスクリプト装着

この記事はアドベントカレンダー「[【VCI】テーマパーク を作ろう](https://adventar.org/calendars/5855) 」の20日目の記事です。

# 今回の内容
今回は以下のリストバンド型の入場券を自動装着できるようにしていきます
<img width=75% src="https://pbs.twimg.com/media/EqI2bRJVEAAfNSi?format=jpg&name=medium">

ボタンを押すと出現し、自動的に腕に装着されるようにします。
今回は学ぶ技術は以下となります。
　・スクリプトでの自動装着


# Unity概要
今回はリストバンドを作成しますが、リストバンドを付ける位置(手首よりちょっと肘寄り)と装着可能ボーンな位置が異なっているという課題があります。(装着可能位置は各ボーンの始点であり、今回つけたい位置は肘ボーンと手首ボーンの中間です。)

普通にoffsetでも位置調整はできなくはないとは思いますが、今回は以下のように装着位置調整用オブジェクトを作りそこに装着機能をもたせます。
こうしておくと、スクリプトで位置調整用オブジェクトを動かすことで装着位置を自由に調整できて便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/2292e2ae-c0be-73a1-a2bd-336cad3c90e9.png)

また、腕輪型の装着VCIを作成する場合は装着対象は「～Hand(手首)」ではなく「～LowerArm(肘)」にしてください。
～Handに設定すると、以下のように手首を動かすと腕から外れてしまいます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Handにつけたときの挙動 <a href="https://t.co/uYeAc5zw8c">pic.twitter.com/uYeAc5zw8c</a></p>&mdash; ＃らいと（きょろ、ちょべりば→ぐ） (@lightjug) <a href="https://twitter.com/lightjug/status/1342715543229329408?ref_src=twsrc%5Etfw">December 26, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# コードの作成
装着VCIのスクリプトの書き方は以下の公式ページを御覧ください。
　・[ExportTransform](https://virtualcast.jp/wiki/vci/script/reference/exporttransform)(ページの下の方に乗っています)
装着するにはAttachToAvatar()を使いますが、その際にアイテムがちゃんと**装着可能な位置にある必要がある**のでご注意ください。

今回はボタンを押したら装着されるようにしたいと思います。
コードは以下のようになります。

``` lua
function onUse(use)
  if use == "Button_WristBand_Appear" then
    -- 出現対象とする腕輪を探す。関数はチュロスのときのものとほぼ作りは同じのため省略。
    local wristband   = fetchWristBand()
    -- リストバンドと同じnoの装着用子オブジェクトを取得する.
    if wristband then
      --位置調整用オブジェクトを取得
      local attachItem  = getAttachItem(wristband.GetName()) 
      --装着対象のボーンの位置を取得
      local avatar = vci.studio.GetLocalAvatar()
      local lowerArmBone = avatar.GetBoneTransform("LeftLowerArm")
      local handBone = avatar.GetBoneTransform("LeftHand")

      if lowerArmBone and handBone then
        --リストバンドをいい感じの位置(肘と手首の間の位置)に移動。
        local wristPos = lowerArmBone.position*0.4 + handBone.position*0.6
        wristband.SetPosition(wristPos)
        wristband.SetRotation(lowerArmBone.rotation)

        --装着用の子オブジェクトを肘の位置に移動
        attachItem.SetPosition(lowerArmBone.position)
        --装着させる。
        attachItem.AttachToAvatar()

      end
    end
  end
end

function getAttachItem(wristband)
  local no = string.match( wristband,"WristBand (.+)" )
  if no then
    return vci.assets.GetTransform("WristBand_Attach "..no)
  end
end
```

実際に動かすと以下のようになります。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">リストバンド型の入場券。<br>入場券としての機能がないのが特徴。 <a href="https://t.co/fjnF4Q5Qsi">pic.twitter.com/fjnF4Q5Qsi</a></p>&mdash; ＃らいと（きょろ、ちょべりば→ぐ） (@lightjug) <a href="https://twitter.com/lightjug/status/1342721079215681536?ref_src=twsrc%5Etfw">December 26, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 終わりに 
いかがでしたでしょうか？
今回はただ装着させただけですが、ゆくゆくはこのリストバンドを当てると動く仕掛けなどを作りたいと思います。
次回の内容は未定です。
Docker の Node.js イメージのバージョンについて

# 初めに
Docker Hub に公開されている Docker 公式の Node.js イメージにはさまざまなバージョンがあります．
(Node.js コンテナイメージ URL : https://hub.docker.com/_/node)

その中にはバージョン名が，```15.5.0-buster-slim```のように```15.5.0```等の数字と```buster-slim```等の文字列を組み合わせたものや，```dubnium-stretch-slim```のように文字列だけのものがあります．
数字部分はNode.jsのバージョンであることが予測できるのですが，文字列部分はどういった意味があるのかさっぱりわかりませんでした．

そこで今回は文字列部分にどういった意味があるのかをまとめました．

# 結論
文字列部分には，Node.js の LTS※ サポートのあるバージョンを表す単語と，Linux のディストリビューションを表す単語が含まれることがわかりました．

※ LTS = Long Time Support

## Node.jsのLTSサポートのあるバージョンを表す単語
|単語|意味|
|----|:---|
|fermium|Node.js 14.x.x の LTS のあるバージョン|
|erbium|Node.js 12.x.x の LTS のあるバージョン|
|dubnium|Node.js 10.x.x の LTS のあるバージョン|

## Linuxのディストリビューションを表す単語
|単語|意味|
|----|:---|
|alpine|ファイルサイズを重視したディストリビューション，非常にサイズが小さい|
|buster|Debian のバージョン 10|
|strech|Debian のバージョン 9|
|slim|処理系なしの軽量版，自身で必要なパッケージを取得する必要がある|

例えば，文字列部分が```buster-slim```となっているバージョンは，Debian のバージョン 10 の処理系なしの軽量版のディストリビューションを使ったイメージです．

また，コンテナのサイズは```alpine < slim < その他```となっています．
コンテナのサイズだけ考えると alpine が最も優秀なように思えますが，alpine はパッケージ管理ソフトが apt ではないことや，Python のイメージを使用する際は alpine を選択すると実行速度が大幅に遅くなる等の問題があるようです．
そのため，やりたいことに合わせてディストリビューションを使い分けるのが良いかと思います．

###### 参考資料
Debianのバージョン一覧 (URL : https://wiki.debian.org/DebianReleases)

# まとめ
Docker Hub に公開されているDocker公式のNode.jsイメージの文字列部分の調査をしました．

今回の調査で，例えば，```dubnium-stretch-slim```は，Node.jsのバージョンは10.x.xで，Debian9の軽量版であることがわかりました．

私自身Docker初心者でコンテナのサイズも気にしていないので，無難に```buster```を使用しようと思います．
NucleoをArduino言語で動かす@Atom編

# NucleoをArduino言語で動かす＠Atom編

## 概要

こんにちは、しろくま＠胡瓜です！

Nucleoは安価でスペックも高く今注目されているマイコンボードの一つで、耳にしたことがある人も相当多いと思います。僕もよく分からず購入したのですが、STM32Cubeとかいうやつを入れるのもめんどくさく（←失礼）、ほったらかしにしていたので、せっかくなのでArduino言語で記述できるような環境を構築しようと思います。

## 用意するもの

- Nucleoボード（僕はF446-REを使いました）
- Atomの入ったパソコン
- USBケーブル
- 愛情

パソコンにはNucleo用のUSBドライバが入っている前提とします。

## PlatformIOを突っ込む

拡張機能のところに「PlatformIO」と検索して、「platformio-ide」をインストールしましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/3af1320c-be61-6d0e-3883-389b7c94c808.png)

時間がかかるので、この間にコーヒーでも入れてゆっくりしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/0c52c6a7-ca1f-ff58-f758-da58f0d523a4.png)
ｷﾀ━━━━(ﾟ∀ﾟ)━━━━!!

というわけでなんとなくAtomを再起動します。

## プロジェクトを作成
再起動してしばらくたつと、こんな感じの画面になるので、`New Project`を押して新規プロジェクトを作成しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/c57af8db-3ba0-c065-0a2d-316f984ece11.png)
するとこんな画面が現れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/7cdda89e-b7a5-6ea8-461e-f565c4ecfae3.png)
Nameに**プロジェクト名**
Boardに**使用するボード**
Frameworkを**Arduino**
に設定してください。このFrameworkがArduinoになっていることが今回のポイントです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/fa946334-e8d9-4334-2a83-6195c50e82a7.png)
また待たされます。

終わったら、こんな感じにいい感じに開いてくれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/a62c12eb-7348-1900-0f1c-5e947bd3e5c8.png)

## コードを記述する

`src`フォルダの中に、`main.cpp`があるので、この中にプログラムを記述していきます。今回は適当にLチカにしておきます。

```cpp:main.cpp
#include <Arduino.h>

#define LED 13

void setup() {
  pinMode(LED, OUTPUT);     // セットアップ
}

void loop() {
  digitalWrite(LED, HIGH);  // LEDオン
  delay(500);

  digitalWrite(LED, LOW);   // LEDオフ
  delay(500);
}
```

## いざ書き込み！

では書き込んでいきましょう！とりゃぁ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/8f4d7434-925e-a23e-9efa-22f52b2d819e.png)
なんか動いています♡（変態）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/f29bef83-3d73-1fc9-fba9-d873ae1039ba.png)
初回のコンパイルは時間がかかるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/66c93412-7148-313e-ca03-a298bb0b92cc.png)

あれ？

## 原因
単純にビルドしてませんでした（）
初回のみ一回ビルドが必要らしいので、こちらを押してビルドします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/16102d76-185b-ac0f-201e-c9c59a9cacc3.png)
そのあともう一度アップロードボタンを押してみましょう。
![ezgif-7-45efb22db81d](https://user-images.githubusercontent.com/47915291/103146583-45179180-478f-11eb-9bbf-ad7d90a8a7be.gif)
**できたーーー　(≧◇≦)**

## まとめ
VScodeよりAtomはGitHubとの連携がいいので、こちらでも動作させることができてうれしいです！また今度デバッグにも挑戦してみたいと思います。

## 追記(2020/12/26)

> Morphoピン（Nucleoの両端の剣山的なところ）は使えますか？

全ての機能が使えるかどうかは試していませんが、先ほどのLチカはできましたのでおそらく対応しているものと思われます。

```cpp:
digitalWrite(13, HIGH);
```
の部分を、例えば

```cpp:
digitalWrite(PA12, HIGH);
```
とすることで対応できました。
Parallels上のWindows10からNASにホスト名でアクセスできなくなった件

#[※2020/12/27追記]
うまくいったのでParallelsの問題だと思い、このQiitaを投稿しました。
が！また接続できなくなりました。ノオオオオオ！
[Windows10バージョン2004以降でNASへの接続が拒否される](https://answers.microsoft.com/ja-jp/windows/forum/all/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B32004/28264d54-7c93-4ea1-82ab-045f4072c7eb)
と同じ現象と思われますので、エントリは残しておきますが、Microsoftの対応を待つしかないのかな…。

#現象
お題だけだと何のことやらという感じですが
Paralles DesktopのWindows10のWindowsUpdateを実行後、
BuffaloのNASに「ホスト名」でだけアクセスできなくなりました。
レアケースとは思いますが同様な現象の方の一助になれば。

#環境
MacBookAir(2020) macOS Big Sur(11.0.1)
Paralles Desktop バージョン 16.1.1 (49141)
Parallel上のWindows10 バージョン2004ビルド19041.685


##正確にいうと
1.IPアドレス直打ちだとアクセスは可能
2.ping ホスト名でpingは通る
3.MacからはNASにホスト名でアクセス可能
4.NASは古いsmb1.0では無い

こんな状態だったので訳ワカメな状態でした。

#Parallesネットワーク
Parallelsは頻繁にネットワークが変わるので「共有ネットワーク」です。
状態は以下の通りです。

```
   接続固有の DNS サフィックス . . . . .: localdomain
   IPv4 アドレス . . . . . . . . . . . .: 11.211.55.3(優先) 
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   リース取得. . . . . . . . . . . . . .: 2020年12月23日 14:47:47
   リースの有効期限. . . . . . . . . . .: 2020年12月23日 15:47:46
   デフォルト ゲートウェイ . . . . . . .: 11.211.55.1
   DHCP サーバー . . . . . . . . . . . .: 11.211.55.1
   DNS サーバー. . . . . . . . . . . . .: 11.211.55.1
   NetBIOS over TCP/IP . . . . . . . . .: 有効
```
#何をしたか
結果的にはMac側の/etc/hostsファイルに追記したらアクセスできるようになりました。

```sh:/etc/hosts
192.168.1.15	nashostname
```
仮想のDNSサーバである「11.211.55.1」がMac側のhostsを参照するということなのかな。
めでたしめでたし。

#ダメだったこと
Windowsのhostsファイルに追加するだけではだめでした。
お得意の「C:\Windows\System32\drivers\etc」にある「hosts」ファイルです。

```hosts
192.168.1.15	nashostname
```
化合物によるGCNのさまざまな実装コードをまとめてみる

#はじめに
化合物によるGCNのさきがけとなる、David Duvenaudらの論文 "Convolutional Networks on Graphs for Learning Molecular Fingerprints" (https://arxiv.org/abs/1509.09292) を元にGCNを実装し、遊んでみようとしたところ、元の論文がAutogradというマイナーなライブラリで開発されており、そのまま修正するのは厳しかったので、他のオープンソースの実装コードを色々調べてみた時のメモ

#調べた実装コード
- 論文の著作者の実装(オリジナル)
- DeepChem
- Chainer-Chemistory
- OpenChem

#調べた箇所
今回調べたのは、原子や結合のコード化ではなく、ニューラルネットの組み方の部分である。


#論文の著作者の実装(オリジナル)
- 利用DLフレームワーク：Autograd 
- URL: https://github.com/HIPS/neural-fingerprint
- GCNの実装コード：https://github.com/HIPS/neural-fingerprint/blob/master/neuralfingerprint/build_convnet.py
- コメント(論文の実装との違い等)：
論文の著者が書いたコードなので、当然ながら論文と同じ実装です。


#DeepChem
- 利用DLフレームワーク：TensorFlow
- URL: https://deepchem.io/
- GCNの実装コード： 
 - https://github.com/deepchem/deepchem/blob/master/deepchem/models/graph_models.py
の GraphConvModel　および _GraphConvKerasModel　クラス
- コメント(論文の実装との違い等)：
 - 元の論文では```return sum(all_layer_fps), atom_activations, array_rep``` のところで各レイヤーの出力を加算するところがあるが、この実装では最終レイヤーの出力のみを利用している。
 - コンボリューションの各レイヤーの最後に、周りのノードと合わせてのプーリング操作が入っているが、元の論文にはない。

#Chainer-Chemistory
- 利用DLフレームワーク：Chainer-Chemistory
- URL: https://github.com/chainer/chainer-chemistry/
- GCNの実装コード：
このあたり。
 - https://github.com/chainer/chainer-chemistry/blob/master/chainer_chemistry/models/nfp.py
 - https://github.com/chainer/chainer-chemistry/blob/efe323aa21f63a815130d673781e7cca1ccb72d2/chainer_chemistry/links/update/nfp_update.py#L9
 -  https://github.com/chainer/chainer-chemistry/blob/efe323aa21f63a815130d673781e7cca1ccb72d2/chainer_chemistry/links/readout/nfp_readout.py#L7
- コメント(論文の実装との違い等)：
 - 元の論文では```return sum(all_layer_fps), atom_activations, array_rep``` のところで各レイヤーの出力を加算するところがあるが、この実装では各レイヤーの出力をConcatinateしている。
 - この実装が一番、元論文を忠実に実装している気がする。

#OpenChem
- 利用DLフレームワーク：PyTorch
- URL: https://github.com/Mariewelt/OpenChem/
- GCNの実装コード：
 このあたり。
 - https://github.com/Mariewelt/OpenChem/blob/master/openchem/modules/encoders/gcn_encoder.py
 - https://github.com/Mariewelt/OpenChem/blob/9e2c98040377cfa0ba4ebf1df159b2f638c6fe7c/openchem/layers/gcn.py#L11
- コメント(論文の実装との違い等)：
 - この実装は別の論文の実装を参考にしているような気がする。そのためか、各レイヤーの中でmaxをとる等、元論文にない操作が見られる。
 - DeepChemと同様、元の論文では```return sum(all_layer_fps), atom_activations, array_rep``` のところで各レイヤーの出力を加算するところがあるが、この実装では最終レイヤーの出力のみを利用している。

#おわりに
- 手法１つとっても様々な実装の仕方があることが分かった。
- Chainer-Chemistoryの実装が最も気に入っている。ただ、フレームワークはPyTorchを使いたいため、Chainer-Chemistoryのソースを参考にしながらPyTorchで実装することとしたい。
M1 MacBookでApple SiliconネイティブなElectronアプリを作成

M1 MacBookでElectronアプリを作ったのですが、Rosettaを使用して開くにチェックをつけたTerminalでNode.js環境を構築しているためか、ElectronアプリもIntelモードになってしまいました。そこで、Apple Siliconネイティブで動かせないか調べてみた話です。

# サンプル作成

https://www.electronjs.org/docs/tutorial/quick-start

公式の手順に沿って作成します。

* 適当なフォルダを作る。
* ```npm init -y```を叩いてpackage.jsonを作成。
* ```main.js```と```index.html```を公式からコピペしてフォルダ直下に作成。

# electron & electron-builderをインストール

electron-builderは以下を参考にPre-release版をインストールします。

https://qiita.com/sprout2000/items/0ced1fa89c1b3cf0fec0


```
npm i -D electron
npm i -D electron-builder@22.10.4
```

#package.jsonの編集

+がついている部分を追記します。"main"がmain.jsになっていなかったらmain.jsにしてください。

```json
{
  "name": "適当なフォルダ名",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
+    "start": "electron .",
+    "build": "electron-builder --dir",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^11.1.1",
    "electron-builder": "^22.10.4"
+  },
+  "build": {
+    "mac": {
+      "target": {
+        "target": "dir",
+        "arch": "universal"
+      }
+    }
  }
}
```

# 動作確認

```npm start```でまずは動くことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/d7c47686-4411-4784-ff7b-c1bed85199fe.png)

# パッケージ作成と起動

```npm run build```を実行すると、```dist/mac/```というフォルダの下にパッケージが作成されていますので、Finderからダブルクリックして起動します。

アクティビティモニタを開いてアーキテクチャを確認してみます。

あれ？　Intelのまま？　おかしい・・・

。
。
。

インストールしていたNode.jsがApple Silicon未対応のv14.15.xだったことに気づきました。

# Node.js v15.xをインストール

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

の後半部分「v15.xのインストール(2020/12/26 追記）」に従ってインストールします。

# 再び、パッケージ作成と起動
再度```npm run build```を実行すると今度は```dist/mac-arm64/```というフォルダができています。Finderから起動後、アクティビティモニタを見るとちゃんとAppleで動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/36438787-a0a9-608c-8d76-953ea43730c6.png)
以上
bulk_createはなぜ早いのか

bulk_createを実際に使用してみたのでそれがなぜ早いのか調べてみました。

- [github](https://github.com/django/django/blob/master/django/db/models/query.py#L463)

- [document](https://docs.djangoproject.com/ja/2.2/ref/models/querysets/#bulk-create)


公式ドキュメントより


> This method inserts the provided list of objects into the database in an efficient manner (generally only 1 query, no matter how many objects there are):


ざっくり、オブジェクトのリストをDBに効率的に入れます。クエリは一つです。とのこと。

結論から言うと、**トランザクション**として処理されているからです。

## トランザクションとは

トランザクションは一言で言うと**処理のまとまり**

処理を具体例とともに見ます。

1. AさんはBさんに1万円送る。

2. Bさんの口座に1万円入る。

これはこの順番で両方とも実行完了されるか、両方とも実行完了されないと口座の計算が合わなくてとんでもないことになります。

この両方とも実行完了するか、両方とも実行完了されないという特性を原子性と言います。

少し道はそれましたがこの1, 2が処理です。

このまとまりがトランザクションです。

## トランザクションはどのように作られるのか

1. 開始文を書く
2. SQLを書く
3. 終了文を書く

このようにして作られます。

例

```
START TRANSACTION; # 1. 開始文を書く
INSERT INTO user (name) VALUES ('hoge'); # 2. SQLを書く
COMMIT; 3. 終了文を書く
```

### COMMIT
トランザクションを確定させる処理。

### ROLLBACK
トランザクションを取り消す処理。


## ACID特性

トランザクションには4つの特性があります。

- 原子性(Atomicity)

トランザクションが全て実行されたか、全て実行されていない状態で終わることを保証する性質。
COMMITするかROLLBACKするかのどっちか。

- 一貫性(Consistency)

トランザクションに含まれる処理はそれぞれの制約(Not Null, primary keyなど)を満たす性質。


- 独立性(Isolation)

トランザクションが実行中の場合、その他のトランザクションの影響を受けない性質。
この辺はRDBMSがうまくやっているらしい。ここでは触れません。


- 永続性(Durability)

トランザクションが完了した後、そのデータ状態が保存され失われることは無いという性質。
何か怒ってもそれまでの結果は保証しますよ。


この4つの特性があります。


## `create`と`bulk_create`の違い
`bulk_create`を説明する上で`create`を引っ張ってきて説明する方が楽なので比べました。

例えば以下のようなモデルがあったとします。
models.py

```
from django.db import models


class Person(models.Model):
  name = models.CharField(max_length=30)
```

レコードを挿入しようとするときDjangoでは以下のように書く。

```
Person.objects.create(name='hoge')
```

次に、最初にユーザーを1万人入れておきたい。となった場合どうするだろうか。
一番考えやすいのは以下のようなコードだと思います。

```
for i in range(10000):
  User.objects.create(name='fuga') #ここでDBに問い合わせ
```

これで1万人のfugaさんが入る。
ただ、これには欠点があります。とても時間がかかることです。

bulk_createの場合は以下のようになる。

```
users = []
for i in range(10000):
  user = User(name='fuga')
  users.append(user)
User.objects.bulk_create(users) #ここでDBに問い合わせ
```

bulk_createの内部実装

```
...(略)
with transaction.atomic(using=self.db, savepoint=False):
...
```

https://github.com/django/django/blob/master/django/db/models/query.py#L499

そう、ここにトランザクションを生成している。

## まとめ

DBに問い合わせをしているため処理に時間がかかるが、bulk_createの場合、トランザクションとしてDBの問い合わせは一回なので時間早い。


[どうなってるの？Djangoのトランザクション](https://speakerdeck.com/denzow/dounatuterufalse-djangofalsetoranzakusiyon?slide=94)
絶対に役に立たない拡張機能24個

# たまにはこういうのもいいじゃないか

こんな拡張機能が便利なんだ！とか、これ使っとけば間違いない！とか、ユーザビリティを考えた情報で世の中は溢れています。

そんな世の中に、嫌気がさした人間が一念発起して書いた記事です。

# 湯婆婆

[VisualStudioCode拡張婆婆](https://qiita.com/plcherrim/items/d026e1f9d9cf2cff390f)は湯婆婆です。もうすぐ「鬼滅の刃」に追い越されそうなジブリスタジオの大ヒット映画「千と千尋の神隠し」。この映画に出てくるワンシーンを再現する拡張機能です。ネタバレ注意です。本稿でも拡張機能作者のQiita記事ネタバレになるので、ここまでの紹介とさせていただきます。

ちなみに、この拡張機能はプログラミングを補助するという役割を、もはや放棄しています。

# テーマ変更

[VSCodeのデザインをアニメや映画のモデルに変更できる拡張機能まとめ](https://qiita.com/hummershin/items/8e0873952b34e4f1fb24)では、カッコいい外観に仕事環境を整えることでモチベーションアップしてくれる拡張機能を紹介しています。

個人的にはゲーム「Cyberpunk 2077」っぽい見た目に変えてくれる、[Cyberpunk 2077](https://marketplace.visualstudio.com/items?itemName=Carlos18mz.cyberpunk-2077-rebuild)が好きです。

# 霊感

[寺生まれで霊感の強いChrome拡張機能](https://qiita.com/kcpoipoi/items/238df3d0492c4631aa77)
なんだかよくわかりませんが、こういうのもあります。

# 背景変更

[vscodeの背景にカバー画像を表示できる拡張機能background-coverについて](https://qiita.com/hotsun/items/e83f89e26003867dc565)
[Visual Studio Codeの背景を透過する(Windows版)](https://qiita.com/suzuki_sh/items/534b8952d74c3a64010c)
これらは背景を自分の好きな画像に変更したり、透過したりといったことが出来る拡張機能です。

# Power Mode

この記事の目玉です。
[Power Mode](https://marketplace.visualstudio.com/items?itemName=hoovercj.vscode-power-mode)は名前の通り、プログラマーのパワーを見える化してくれる拡張機能です。タイピングに合わせてエネルギーがほとばしります。

自分のパワーが可視化されると、なんか強くなった気がしますね。実際の効果は不明です。プログラミングが捗りそうです。

# まとめ

いずれも、本質的にはプログラミングに不要な拡張機能です。それでもこれらは、「こんなこともできる！」という可能性を広げたり、イマジネーションを加速させてくれたりします。脳のリフレッシュには最適なのではないでしょうか。

ユーザビリティを無視しているので、タイトル回収できていません。
「24個くらいあるだろう」と書き始めたけれど、ありませんでした。

たまにはこういう記事を書くのもありですね。

**Excelsior!**
Laravel で ValueObject を最も簡単に導入する方法

## はじめに
`ValueObject`を導入する方法を探す必要なんてなくて、`app/ValueObjects`ディレクトリ作ればおしまいではあるのですが、`Laravel`らしく`php artisan make:value-object`コマンドでファイルを自動生成するところまでをパッケージにして公開しました。

ソースコードは[こちら](https://github.com/imunew/laravel-value-objects) です。
`composer require imunew/laravel-value-objects` で導入できます。

## こんな`ValueObject`がいい
`ValueObject`に求めるものは、以下のとおりです。

- `immutable`
  - 必要なデータは`__construct`でのみセットして
  - `setter`は`public`にしない
  - `@property-read`なプロパティにアクセス可能
- `Eloquent Model`みたいに
  - `getter`をいちいち書かなくていい
  - `Accessor`（`get{Attribute}Attribute`）を実装できる
  - `artisan make:value-object`コマンドでファイル作れる

一応、`packagist`でパッケージを探してみましたが、条件を満たすものはありませんでした。
[chalcedonyt/laravel-valueobject](https://packagist.org/packages/chalcedonyt/laravel-valueobject) は、`immutable`だし、`make`コマンドも用意されていて、いい感じなのですが、残念ながら、`2015-11-13`を最後に更新が止まっていて、`Laravel 6.x`以降には対応していませんでした。

## こんな感じで使えます
### 例1） Rangeクラス

```php
namespace App\ValueObjects;

use Imunew\Laravel\ValueObjects\ImmutableObject;

class Range extends ImmutableObject
{
    /**
     * Range constructor.
     * @param int $start
     * @param int $end
     * @param int $step
     */
    public function __construct(int $start, int $end, int $step = 1)
    {
        $this->setAttribute('start', $start);
        $this->setAttribute('end', $end);
        $this->setAttribute('step', $step);
    }

    /**
     * @return array
     */
    public function getRangeAttribute()
    {
        return range($this->start, $this->end, $this->step);
    }
}
```

```php
$range = new Range(1, 10);
echo $range;
// [1,2,3,4,5,6,7,8,9,10]
```

### 例2） DirectoryTreeクラス

```php
namespace App\ValueObjects;

use Imunew\Laravel\ValueObjects\ImmutableObject;

class DirectoryTree extends ImmutableObject
{
    /**
     * Range constructor.
     * @param array $directoryTree
     */
    public function __construct(array $directoryTree)
    {
        $this->attributes = $directoryTree;
    }
}
```

```php
$directoryTree = new DirectoryTree([
    'app' => [
        'Http' => [
            'Controllers' => [],
            'Middleware' => [],
            'Requests' => [],
            'Resources' => [],
        ],
        'ValueObjects' => []
    ]
]);

echo json_encode($directoryTree->get('app.Http'));
// {"Controllers":[],"Middleware":[],"Requests":[],"Resources":[]}
```

## おわりに
我ながらいい感じの`Laravel`パッケージができました。
ぜひ使ってみてください。
ではでは。
Java (データベース接続周り)


# Java (データベース接続周り)

アプリケーションからデータベースに接続する上で、Java では Tomcat 等のアプリケーションサーバ経由、かつ、jdbc ドライバーで接続することが多いと考える。tomcat のデータソース周りの設定や各 jdbc ドライバー自体に独自の設定があるため、その辺りの挙動を調査、及び、検証してまとめていく。

## Tomcat

Tomcat9 だと以下がJDBC Connection Poolのマニュアルとなっている。
https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html

主要と個人的に考えるパラメータ達。

### Common Attributes

- `type`
    - javax.sql.DataSource 固定値で一旦 OK
- `factory`
    - Tomcat JDBC Connection Pool 利用時は org.apache.tomcat.jdbc.pool.DataSource 
    - Common DBCP 利用時は org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory
    - Tomcat JDBC Connection Pool の方が機能や性能がエンハンスされているらしいのでこちらを利用したい。
    - ${CATALINA_HOME}/lib 配下にある tomcat-dbcp.jar が本体。
- `driverClassName`
    - 利用する jdbc ドライバーのクラス名を指定する。
    - MySQL では、com.mysql.jdbc.Driver。jar ファイルを展開すると、com/mysql/jdbc/Driver.class というクラスファイルがあり。
- `url`
    - jdbcプロパティ識別子。jdbc ドライバーの設定をクエリストリングのような形で指定する。
    - 例: jdbc:mysql://localhost:3306/db01?socketTimeout=30000
- `username`
    - DB ユーザー名
- `password`
    - DB ユーザーのパスワード
- `initialSize`
    - Tomcat起動時にDBへのTCP接続をESTABLISHさせるコネクション数。
- `minIdle`
    - プール内のコネクション数をminIdle以上保持。
    - ただDB側の再起動でコネクション数が0になったときにこの値まで底上げしてくれるわけではない。逆にアイドルコネクションがminEvictableIdleTimeMillisで破棄される時はこの値までは残してくれる。
- `maxIdle`
    - プール内のコネクション数をmaxIdle以下に制限。あまり意味がないかも...?
- `maxActive`
    - プールから同時点で貸し出すコネクションの最大数
- `maxWait`
    - プール内のコネクションが不足したときの最大待ち時間（ミリ秒）
- `testOnConnect`
    - コネクションが最初に確立される際にvalidationQueryで検証するかどうか
- `testOnBorrow`
    - コネクションを貸し出す際にvalidationQueryで検証するかどうか
- `testOnReturn`
    - コネクションを返却する際にvalidationQueryで検証するかどうか
- `validationQuery`
    - コネクションが有効かどうかを検証するためのSQL
- `validationQueryTimeout`
    - validationQuery が失敗するまでのタイムアウト時間（秒）
- `timeBetweenEvictionRunsMillis`
    - アイドル状態のコネクションの破棄実行間隔   
- `minEvictableIdleTimeMillis`
    - どの程度プール内で連続してアイドル状態だったらtimeBetweenEvictionRunsMillisの破棄対象になるか。
- `defaultAutoCommit`
    - コネクションを確立するときに autocommit を有効化するかどうか。(コネクション確立時の set autocommit 文の値を1にするか0にするか？)
    - setAutoCommitメソッドが JDBC ドライバー側で呼ばれない場合に発行。
- `removeAbandoned`
    - コネクションクローズ漏れでプールにコネクションを返していない接続をremoveAbandonedTimeout経過後にabondonedと判定して破棄(TCP接続終了)させるかどうか。
- `removeAbandonedTimeout`
    - コネクションクローズ漏れでプールにコネクションを返していない接続をabondonedと判定する秒数。

### Tomcat JDBC Enhanced Attributes

- `initSQL`
    - コネクション確立時に一度だけ発行される特定のSQL
- `validationInterval`
    - プール内の同一のコネクションに関して前回の検証処理からこの時間(ms)経過していなければ検証は実施しない。
    - デフォルト 30000 ms。
- `fairQueue`
    - true の場合、プール内のコネクションの貸し出しをFIFOで行う。
- `maxAge`
    - プールからのコネクション貸し出し時、コネクションの確立からこの時間(ms)経過していたら貸し出す前にそのコネクションを再TCP接続する。
    - プールへのコネクション返却時、コネクションの確立からこの時間(ms)経過していたら返却後にそのコネクションを再TCP接続する。
    - プール内コネクションがアイドル状態時、かつ、minEvictableIdleTimeMillis経過していた場合で、コネクションの確立からこの時間(ms)経過していたらそのコネクションを再TCP接続する。
    - DB側の障害などでコネクションが貸し出されても腐っていた場合に有用な気がする。
Vue.js 算出プロパティとメソッド

## はじめに
一通りvueを触ってみて理解できなかった項目の一つが「算出プロパティとメソッドの違い」です。ようやく理解できたので詰まっている方のためにアウトプットも兼ねてまとめます。ここではそもそも算出プロパティとは何かをコードを用いて説明し、その後算出プロパティとメソッドの違いを明らかにします。

## 算出プロパティとは？
算出プロパティが何なのか理解できている方はここを読み飛ばしてもらって構いません。
まず、このようなコードがあったとします。

```vue:App.vue
<template>
  <div>
    <p>{{ random + 3 }}</p>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      random: Math.random()
    }
  }
}
</script>

```

これは０から１の間のランダムな数に３を足しているコードです。テンプレート側の{{ }}にはjavascript式を埋め込む事ができます。

![スクリーンショット 2020-12-26 12.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/81685a05-1afb-2b05-0adb-a526e6f158c3.png)

動作をしては全く問題ないのですが、望ましいコードとはいえません。もし仮にこの
{{ random + 3 }}と言うコードを他のコンポーネントなどでも使用していた時に変更が入ったらどうなるでしょう。この処理が記述されている部分全てを書き換える必要があります。そうすると手間がかかるので算出プロパティに切り出すという方法があります。

```vue:App.vue
<template>
  <div>
    <p>{{ plusThree }}</p>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      random: Math.random()
    }
  },
  computed: {
    plusThree() {
       return this.random + 3
    }
  }
</script>

```

このように改修すると変更が入った際にはplusThreeメソッドを変更するだけで良くなるだけでなく、コードの見通しも良くなります。

## 算出プロパティとメソッドの違い

先ほどのコードではplusThreeはcomputedオプション内に記述していましたが、別にmethodsオプションを追加してメソッドとして記述しても問題なく動作します。

では算出プロパティとメソッドの違いってなんでしょう？
大きく三つ違いがあります。

#### 算出プロパティは引数を受け取れない

算出プロパティは引数を受け取る事ができません。確かに算出プロパティをテンプレート側で呼び出す際には
{{ plusThree }}として引数を渡す余地はありませんが、メソッドを同じように呼び出すときには
{{ plusThree() }}というふうに記述しなければなりません。算出プロパティはscriptで定義する時にはメソッドと同じように記述しますが、呼び出すときにはその名の通りプロパティ(変数)のように呼び出します。

#### 算出プロパティは加工のみ

算出プロパティはあるデータがあってそれを加工したり、演算する用途で使われます。それゆえ、算出プロパティには引数が必要ないのです。メソッドは引数を受け取ってデータを取得、操作更新を行う事ができます。

#### 算出プロパティはキャッシュされる

```vue:App.vue
<template>
  <div>
    <input type="button" value="クリック" @click='onClick'>
    <div>{{ randomA }}</div>
    <div>{{ randomB() }}</div>
    <div>{{ current }}</div>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      current: new Date().toLocaleString()
    }
  },
  computed: {
    randomA() {
      return Math.random()
    }
  },
  methods: {
    onClick() {
      this.current = new Date().toLocaleString()
    },
    randomB() {
      return Math.random()
    }
  }
}
</script>

```

![スクリーンショット 2020-12-26 14.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/1254334b-d584-271f-5aa3-a8b32301c8fb.png)



![スクリーンショット 2020-12-26 14.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/465a883a-afba-e6e9-8141-56c04bd92ae1.png)

クリックボタン押下時、再描画が行われrandomBは値が変更された一方で算出プロパティとして定義されているrandomAに関しては値が変更されていない事がわかります。算出プロパティは他のプロパティに依存しないので一度呼び出されると二度と変更されることはありません。


## 最後に
まとめると、算出プロパティがメソッドと異なる点は引数を取る事ができない、値を加工、演算をしたりするときにしか使用できない、キャッシュされるの三点でした。
１．Mac入門〜画面編（Dock）

# 前置き
Macbookを初めて使うことになったので、自分の理解をアウトプットするために作成。

## 環境
* macOS Big Sur 11.1
* MacBook Pro (13-inch)

# Dock（ドック）とは
iPhoneでいう一番下のアプリのエリアで、アプリを素早く起動するためのショートカット集を指す。
![「１．Mac入門〜画面編（Dock）」を編集_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/8c4f34ee-3b17-bc77-5bd9-75e83861aa61.png)

![「１．Mac入門〜画面編（Dock）」を編集_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/a732e2a9-ad32-8a3b-a747-ad561ca64ca2.png)
ショートカットの下のマークは、今アプリを起動してますよ、の意味となる。
アプリを終了すればこのマークも消える。
よく使うアプリはDockの中に入れておくと便利である。

# Dockのエリア説明
Dockはパーティションで3つのエリアに区切られている。
![「１．Mac入門〜画面編（Dock）」を編集_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/62e19f86-0aff-8502-3a1d-f426a0532beb.png)

## ①一番左のエリア
自分でショートカットとして登録したアプリケーション一覧表示エリア
## ②中央のエリア
アプリケーションとして登録はないが、最近起動したアプリケーション一覧表示エリア
## ③一番右のエリア
特定のフォルダのショートカットを置けるエリア

# Dockへのアプリの追加方法
Macの上の画面のメニューバーの「移動」→「アプリケーション」で、Macにインストールされているアプリケーションの一覧が表示される。
※Macのメニューバーはアクティブウィンドウによって表示が変わるので、デスクトップ背景をクリックしてからメニューバーを操作する。
![スクリーンショット_2020_12_26_20_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/1cb0768c-30d5-240e-f573-2c4ae7271ef6.png)

アプリケーション一覧
![アプリケーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/400ea430-ce2f-0c2f-e561-15d9231a67e1.png)

追加したいアプリケーションアイコンをDockにドラッグ&ドロップで登録できる。
# Dockからのアプリの削除方法
Dockのアプリをドラッグし、Dock外まで持っていくと削除できる。

# Dockのカスタマイズ
Dockは自己流にカスタマイズできる。
ここでは、よく使いそうな項目だけピックアップして説明する。

## カスタマイズのためのメニューの開き方
画面右上のAppleマーク→「システム環境設定」→「Dockとメニューバー」
![スクリーンショット_2020_12_26_20_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/898b08e3-72d0-a6c0-b91d-415d4b481770.png)

![システム環境設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/1af80ebc-c464-2e95-5ee6-e79e27c3f9e6.png)

Dockとメニューバーの詳細設定画面
![Dockとメニューバー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/b8fa4ac9-4d32-6bb0-dddb-396d596ecc63.png)


## サイズ
Dockエリアの大きさを調整できる。
Dockのパーティションにマウスオーバーし、ドラッグでも調整可能。

## 拡大
チェックをつけると、Dockにマウスを持っていくとアプリケーションアイコンが拡大表示される。拡大のサイズを最小〜最大バーで調整できる。

拡大をONにした時の画面イメージ
![スクリーンショット_2020_12_26_20_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222238/3df662bb-f8b0-e537-2b85-e472c7fd129a.png)

## 画面の位置
Dockの場所を左、下、右のどこに固定するかを決める。

## Dockを自動的に表示/非表示
ONにすると、普段は非表示となるが、Dockの配置位置にマウスを持っていくと自動的にDockが表示されるようになる。Windowsでいうタスクバーを隠す動きと一緒である。

## 最近使ったアプリケーションをDockに表示
OFFにすると、Dockのパーティションが１つ減り、最近起動したアプリのエリアが消える。
rubyで二次元配列を4分割する方法



諸事情あり誰得なメソッドを作成しました。
文字だとさっぱりだと思うので、絵を書きました！

例えばこういう任意の二次元配列があるとします。
![スクリーンショット 2020-12-26 14.20.49 2 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425910/f9e7682d-a547-2c74-5df7-488e95588cad.png)

以下のように(1,1)のように任意の座標を指定し、４分割したいです。
![スクリーンショット 2020-12-26 14.20.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425910/db989410-a574-426f-4379-e95c954693a5.png)



コードはこちらです。

```ruby
def divide_2d_array(array, x, y)
    temp1 = []
    temp2 = []
    array.each do |a|
        temp1 << a[0..y]
        temp2 << a[(y+1)..-1]
    end
    a,c = temp1[0..x], temp1[(x+1)..-1]
    b,d = temp2[0..x], temp2[(x+1)..-1]
    return a,b,c,d
end

# 実行してみます
arr = [[1,2,3],
       [4,5,6],
       [7,8,9]]

p divide_2d_array(arr, 1, 1)
# =>[[[1, 2], [4, 5]], [[3], [6]], [[7, 8]], [[9]]]
```

できていますね！！！
もっといい方法あったら教えて下さい！
既存プロジェクトで Gemfile → gems.rb してみる

# はじめに

Ruby on Rails の既存プロジェクトを Bundler2.x以降で
Gemfile → gems.rbしたので、その手順を書いておきます。


# Gemfile -> gems.rb 、Gemfile.lock -> gems.locked する(オプション)

Gemfile、Gemfile.lock、から ファイル名を変更します。

```
mv Gemfile gems.rb
mv Gemfile.lock gems.locked
```

このままでは、プロジェクトの bin 下にあるスクリプトの実行に
失敗するので、次の手順を行います。

## プロジェクトの bin 下と config 下にあるスクリプトを変更する

`config/boot.rb` を、
開いて`../Gemfile` -> `../gems.rb` するか、
`gems.rb`と`Gemfile`の両方に対応するように書き換える必要が
あります。

https://github.com/asip/easel-back/blob/main/config/boot.rb

上の変更は、ad hoc かもしれません？が、自分の環境では動作している
ので、問題ないはずです。

::: note info
Rails6の頃までは、config/boot.rb 以外のファイルも変更する
必要がありましたが、Rails7以降は、config/boot.rb のみ
変更するだけで済むようになっています。
:::
::: note info
Rails で利用する gem の中に`Gemfile`のみ考慮していて、
`gems.rb`を考慮していないモノがあるので、注意が必要です。
:::

# 最後に

移行手順は以上です。
備忘録(Herokuを使用したデプロイの方法)

### 事前準備
+ Herokuでアカウント作成
+ 必須項目、パスワード入力
+ 使用するDBによってはクレカ登録
+ Heroku CLIをインストール

```bash
% brew tap heroku/brew && brew install heroku
ターミナルからHerokuへアクセスができるようになる
```

+ バージョンの確認方法

```bash
% heroku --version
```

#### ターミナルを使用してログイン

```bash
# Herokuへログインするためのコマンド
% heroku login --interactive
  => Enter your Heroku credentials.
# メールアドレスを入力し、エンターキーを押す
  => Email:
# パスワードを入力して、エンターキーを押す
  => Password:

```

### Heroku上にアプリケーションを作成する
+ heroku createコマンドを作成する

```bash
% heroku create 作成したいアプリケーション名

正しく設定できたかの確認方法
% git config --list | grep heroku
```

### Heroku上でMySQLを使えるようにする
+ ClereDBアドオン

```bash
% heroku addons:add cleardb
ClearDBというデータベースサービスが提供しているアドオン
```

Ruby on Railsを使う場合は、MySQLに対応するGemについて考慮する必要があり、そちらの設定を変更

```bash
% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`

ClearDBデータベースのURLを変数heroku_cleardbに格納
```

```bash
% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}

これでデータベースのURLを再設定
```

### Heroku上で非公開の値を管理する仕組み
+ サーバーのアクセスキーやAPIキーなど、外部に漏らしたくない情報はセキュリティの観点から暗号化する必要がある
+ 暗号化された情報は開発環境、本番環境で予め用意した鍵を用いて複合する
+ credentials.yml.encファイル(Railsのバージョン5.2以降)

Railsにて、外部に漏らしたくない情報を扱う際に用いるファイル
credentials.yml.encと対になるmaster.keyが存在する場合、credentials.yml.encの暗号文を復号し、ファイル内の記述を確認できる

+ master.keyファイル

credentials.yml.encの暗号文を復号する、鍵の役割を持ったファイル
特定のcredentials.yml.encと対になっているため、その他のcredentials.yml.encへは、効果を発揮しない

確認方法

```bash
EDITOR="vi" bin/rails credentials:edit

credentials.yml.encをmaster.keyによって復号
確認後は、「escキー」→「:」→「q」と入力し、「enterキー」を押して credentials.yml.encを閉じる
```

### 環境変数
+ 「どのディレクトリ・ファイルからでも参照できる変数」
+ 一般的な用途の1つとして、「外部に漏らしたくない情報を環境変数にセットする」というものがある

### heroku configコマンド

```bash
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`

Heroku上に環境変数を設定

% heroku config
Herokuの環境変数一覧を表示をするコマンド
```
### アプリケーションをプッシュ

```bash
% git push heroku master
```

+ 開発環境のアプリケーションに追加機能を実装し、その変更をHeroku上のアプリケーションにも反映したい場合は、同じ様にmasterブランチにコミットし、Herokuにプッシュする必要がある

### Heroku上でマイグレーションファイルを実行
+ Heroku上で実行したいコマンドの頭には、heroku runをつける

```bash
heroku run rails db:migrate
マイグレーションファイルの実行
```

### DBのリセット
+ herokuはデータベースが定期的にリセットされ画像ファイルが壊れて表示されない。そのため画像を表示させるにはDBをリセットすることが必要

```bash
heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop db:create db:migrate

```

### アプリケーションの情報を確認
+ heroku apps:infoコマンド

```bash
% heroku apps:info
```

2021.01.22追記
### herokuで利用する環境を指定する
+ 2021年以降デフォルトのStackは「Heroku-20」になっているためrubyバージョンが2.6.5の場合は、

```bash
% heroku stack:set heroku-18 -a アプリケーション名
```

ターミナルで実行してから、pushする
AWS AMI とは

## 勉強前イメージ

EC2の中にあるスナップショット的な・・？
「これと同じやつ起動する」ってときに出てくるイメージ？

## 調査

### AWS AMIとは

Amazon Machine Image の略で、
インスタンスを起動するのに必要なOSやボリュームの情報などのテンプレートのことです。
インスタンスを立ち上げるときにOSを指定しますが、それはAMIを指定しているのです。

![2020-12-26インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/650df918-d658-7f09-ef47-73fba59b9f46.png)


AMIは自分で作成もでき、別アカウントや他リージョンへのコピーも可能です。


### AWS AMIを作ってみよう

- 作り方
	- インスタンスから作成
	- スナップショットから作成

作り方として2種類あり、インスタンスから作成も出来ますし、スナップショットから作ることも出来ます。

#### インスタンスからAMIを作成

EC2から特定のインスタンスを指定し、
アクション > イメージとテンプレート > イメージを作成

![イメージの作成インスタンス _ EC2 Management Console - Google Chrome 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3479b71f-3755-04cb-f609-b171305ad31d.png)

イメージ名と説明を記載
インスタンスを再起動させない場合は、`再起動しないを有効化` にチェックを入れる必要があります。

![AMIを作成イメージを作成 _ EC2 Management Console - Google Chrome 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f74be074-81d0-0f00-38c4-2d2d97d9d2ec.png)

AMIを確認すると、mine EC2が作成されています。

![EC2AMI _ EC2 Management Console - Google Chrome 2020-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/63c551f8-d59b-e505-58bf-3705ebd4263d.png)

EC2を作成するときに、mine EC2を指定することも出来ます。

![111インスタンスウィザードを起動 _ EC2 Management Console - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f6243bc8-65db-ce24-f2a9-a4c924461393.png)


## 勉強後イメージ

知ってたようで知らなかったAMI。
テンプレートのことなのか・・・なんとなくOSを指定してたんだと思ったけど、
OSを含んだ諸々のテンプレートのことを言ってたのね。

## 参考

- [Amazon EC2編 AMIの利用① ～インスタンスからの作成編～](https://recipe.kc-cloud.jp/archives/10045)
重いファイルの転送・小技集

# 最初に
サーバー間で、重いデータを転送したい時がある。
ローカルを経由するとバカみたいに通信を食う。
また、VPNでつないでる時なんかは、途中でVPNが落ちちゃったりしたら目も当てられない。
ということで、基本戦略は下記となる。
 - 分割して送ること
 - rsyncで同期すること
 - 分割ファイルを戻すこと
 
# (1) まず圧縮

```bash
tar zcvf hoge.tar.gz hoge  # 圧縮
tar zcvf --use-compress-prog=pigz hoge.tar.gz hoge  # 圧縮（並列版）
```

# (2) 分割する (1000m = 1GB)

```bash
split -b 1000m hoge.tar.gz hoge.grd.tar.gz-
```

# (3) rsyncする (スクリプトを準備しよう)

```bash
#!/bin/sh
rsync -av ./sender/  ?????@????????.jp:/work/hoge/reciever/
```

# (4) 元に戻す

```bash
cat /work/hoge/reciever/hoge.tar.gz-* > hoge.tar.g
```

これで元に戻せた。この年になるまで、ファイル分割を知らなかった。
splitとcatのコンボが強力です。
ExecJS::RuntimeErrorの解決法。

AWSのCloud9で作っていたポートフォリオをローカルのVSCodeで動くようにしようと、
git cloneしてきた。

bundle install, 
rails db:setup, 
rails s

すると、ExecJS::RuntimeErrorと出た。

色々と調べると
``
gem 'mini_racer', platforms: :ruby
``
を導入すればうまく行った。

再度、　bundle install.
rails sでOK!
macでのGoogleChrome開発者ツール起動ショートカット


mac初心者のため、いろいろな機能を使いこなせるよう、メモを残していきたいと思います。
最初はショートカットなどが多いかと思います。

・GoogleChromeの開発者ツール起動ショートカット
option + command + i

以上です。
画像から化学構造式を抽出するソフトウェアについてざっくり調べてみた

#はじめに
pdfで書かれた特許文書内の化合物をどうにかSDFやSMILES形式で簡単にゲットできないかということで、掲題の件調べてみた。

参考文献からたどった程度であるが、あまりにも種類が多かったため、商用化されていないものなどはいくつか端折った。

PS. あんまり人に教えたくないけど、最新論文の序論や、レビュー論文読むのが情報収集にめちゃ効率的ですね。

#OSRA: Optical Structure Recognition Application
https://cactus.nci.nih.gov/osra/

WEBまたはコマンドラインで利用できる。
画像以外にもPDFに対応している。
上はNCIで開発されたVersion1であり、フリーソフトである。

Version2も以下で継続的に開発されている。
https://sourceforge.net/p/osra/wiki/Download/
Vervion2は認識率が上がっているがバイナリ版は有償となっているようだ。

#CLiDE
http://www.keymodule.co.uk/products/clide/index.html

Keymoduleで開発された商用ソフトウェア。画像の他にもPDFやHTML, ワード等様々な形式に対応している。
Standardでは1つずつだが、Professionalでは1度に大量の化合物を処理できるようだ。またこれらGUI版の他コマンドライン版のBatchというラインナップもある。

#ChemoCR
URL:https://www.scai.fraunhofer.de/en/business-research-areas/bioinformatics/products/chemocr.html

SCAI社が提供する商用の化学構造式の認識プログラム。パターン認識技術と高度な機械学習の概念を組み合わた手法による。GUI、バッチ処理ともに可能とある。

#Kekule: OCR-optical chemical (structure) recognition
199年代にJoe R. McDaniel, Jason R. Balmuth らによって開発された化学構造式の認識プログラム。詳しくは以下論文参照

論文：https://pubs.acs.org/doi/abs/10.1021/ci00008a018

#ChemInfty
URL:http://www.inftyproject.org/jp/ChemInfty/

科学技術振興機構　研究成果最適展開支援事業（育成研究）平成21〜23年「文献や特許データベース中の化学構造式の認識と検索」のプロジェクトで開発された。

#DECIMER: towards deep learning for chemical image recognition
URL: https://jcheminf.biomedcentral.com/articles/10.1186/s13321-020-00469-w

化学的な前提知識を一切(とまでは言い過ぎか?)用ないDeepLearningのみによる手法の論文。
論文では、5,000万から1億の構造の学習データで、ほぼ正確な予測を達成できる可能性があることが示唆されている。
OSSとオープンデータに基づいており、いかなる目的にも利用可能とある。githubにも公開されているため、機会があれば試して紹介したい。

#参考
- [画像から構造式を抽出せよ!! (構造式をOCR?)](http://pc-chem-basics.blog.jp/archives/1039462.html)
- [A review of optical chemical structure recognition tools](https://jcheminf.biomedcentral.com/articles/10.1186/s13321-020-00465-0)
[RSpec] テストコード 書き方

今回はRSpecを用いて"ユーザー新規登録機能"の、
モデルのテストコードの書き方を説明していきます。

#テストコードの基本形
```spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'ユーザー新規登録機能' do
    context 'うまくいく場合' do
      it '全てのカラムに値が存在すればユーザー新規登録ができる' do
       # 処理
      end
    end

    context 'うまくいかない場合' do
      it 'nicknameが空では登録できない' do
       # 処理
      end
    end
  end
end
end
```

上記がテストコードの"基本形"です。
使っているメソッドや、関連する語句の意味を１つづつ解説していきます。

---
`describe`
テストコードのグループ分けを行うメソッドです。
「どの機能に対してのテストを行うか」をdescribeでグループ分けし、
describe do ~ end中に各テストコードを記述します。

入れ子構造を用いてdescribeの中にdescribeを記述する。
といったことも可能です。

---
`context`
特定の条件を指定してグループ分けを行うメソッドです。
使用方法はdescribeと同じですが、describeには "何についてのテストなのか" 
を指定するのに対し、contextには "特定の条件" を指定します。

---
`it`
こちらもテストコードのグループ分けを行うメソッドです。
itの場合はより詳細に、「describeメソッドに記述した機能において、どのような状況のテストを行うか」を記述します。

---

`example`
it do ~ end内に記述した内容、もしくはitで分けた、グループそのもののことを指します。
上記で言えば "全てのカラムに値が存在すればユーザー新規登録ができる" と、
"nicknameが空では登録できない" がexampleということですね。

---

テストコードの書き方
---

```spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'ユーザー新規登録機能' do
    context 'うまくいく場合' do
      it '全てのカラムに値が存在すればユーザー新規登録ができる' do
        expect(@user).to be_valid  
      end
    end

    context 'うまくいかない場合' do
      it 'nicknameが空では登録できない' do
        @user.nickname = ''       
        @user.valid?             
        expect(@user.errors.full_messages).to include("Nickname can't be blank") 
      end
    end
  end
end
end
```
実際に上記のようなテストコード を書きました。
前提として、FactoryBotでインスタンスを予めまとめ、それを@userに代入しております。
つまり、@userには "ユーザー新規登録成功に必要な値" が全て入っています。

それではコードの意味を解説していきます。

---
`各コードの意味`
expect(@user).to be_valid 
これは、値が全て入っている@userをまとめてテストしている。
という意味です。

@user.nickname = ''
これは@userからnicknameカラムを取得して、
その値を空っぽとしています。

@user.valid?
@userの中のnicknameが空の状態では、エラーがあるかどうかを確認しています。

expect(@user.errors.full_messages).to include("Nickname can't be blank") 
@userにエラーがある場合、エラーメッセージを配列として取り出します。
そして、そのエラーメッセージの中に"Nickname can't be blank"が含まれているか、
を確認しています。

---
以上が大まかなコードの意味です。
以下では、このコードを構成しているメソッドやマッチャの解説をしていきます。
それではどうぞ↓

メソッドとマッチャ
---
`valid?`
バリデーションを実行させて、エラーがあるかどうかを判断するメソッドです。
エラーがない場合はtrueを、ある場合はfalseを返します。
エラーがある場合は、エラーの内容を示すエラーメッセージを生成します。

---
`be_valid`
valid?メソッドの返り値が、trueであることを期待するマッチャです。
expectの引数に指定されたインスタンスが、バリデーションでエラーにならないものであれば、valid?の返り値はtrueとなりテストは成功します。

つまり今回の "expect(@user).to be_valid" という記述を要約すると
「@userの中身は全部成功だよね、一応確認しておくよ！」　です。

---
`expectation`
検証で得られた挙動が想定通りなのかを確認する構文のことです。
"expect(　).to　matcher(　)"が雛形です。
テストの内容に応じて引数やmatcherを変えて記述します。

---
`errors`
インスタンスにエラーがある場合、その内容を返すメソッドです。

---
`full_messages`
エラーの内容から、エラーメッセージを配列として取り出すメソッドです。

---
`include`
「expectの引数」に「includeの引数」が含まれていることを確認するマッチャです。
今回のコードに当てはめると、(@user.errors.full_messages) の中に
("Nickname can't be blank") が含まれていることを確認している
ということです。

---
`eq`
「expectの引数」と「eqの引数」が等しいことを確認するマッチャです。
今回のコードには使用しておりません。

---
【Rails】プルダウンで数字を簡単に実装する方法

＜この記事について＞
自作のマッチングアプリ製作中に、ユーザー登録機能を実装しています。
その中で、「年齢」の項目は手打ちではなく、プルダウンで実装できれば
UXが向上して良いのではと考えました。
調べてみると、いとも簡単に実装できたので備忘録として投稿します！

[環境]
・Ruby 2.6.5
・Rails 6.0.0
・macOS

＜前提＞
ユーザー管理機能は、「device」gemを用いて導入済みとします。

app > views > devise > registrations > new.html.erb

元々は、手打ちでの実装のため以下のように記述していました。

```ruby
<%= f.text_field :age, autocomplete: "off" %>
```

"text" → "number"に修正してみましょう！

```ruby
<%= f.number_field :age, autocomplete: "off" %>
```

簡単に実装できました！