OmniAICreator/Qiita-1.07M huggingface dataset:
【spring-boot】DB接続先動的変更

# 1.はじめに
 開発・本番環境リリース時に同じソースコード(war)をリリースするためのメモ書きです。

# 2.環境
 - 開発環境
    - Java 8
    - SpringBoot
    - DB:SQLServer
 - サーバ(本番:1台、検証:1台)
    - OS:WindowsServer
    - apatch-tomcat
    - apatch

# 3.作業内容
　Spring Bootは、アプリケーションプロパティファイル(application.properties)を読み込む仕組みになっています。アプリケーションプロパティファイルを指定しない限りデフォルトのファイル(application.properties)を読み込みます。今回はアプリケーションプロパティファイルを本番環境・検証環境を別々に作成＆指定することで接続先を動的に変更できるようにする。

## 3-1. アプリケーションプロパティの作成
　本番環境(pro)と検証環境(st)環境を作成する。各プロパティファイル名称の末尾にproやstをセットするだけで完了となる。

```properties:application-pro.properties
##本番DBの接続情報を設定
spring.datasource.primary.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.primary.url=jdbc:sqlserver://000.000.000.000:1433;databaseName=ProDB
spring.datasource.primary.username=name
spring.datasource.primary.password=password
```

```properties:application-st.properties
##検証DBの接続情報を設定
spring.datasource.primary.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.primary.url=jdbc:sqlserver://000.000.000.000:1433;databaseName=StDB
spring.datasource.primary.username=name
spring.datasource.primary.password=password
```

## 3-2. サーバ設定
　各サーバの「コントロールパネル>システム>システムの詳細設定>環境変数」よりシステム変数"SPRING_PROFILES_ACTIVE"を登録する(本番:pro、検証:st)。

![spring-pro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743063/23b5f842-525c-3d73-a6a4-f2639047ebe3.png)

#4 .おわりに
今回はDBの接続のみを例にしたが、各プロパティファイルで記載する内容を変えることで様々な設定を変更することができる。

# 参考サイト
 - https://qiita.com/kazuki43zoo/items/0ce92fce6d6f3b7bf8eb
Mozilla Hubs 2021.1.26 UIの大幅UPDATE

昨晩、2021/1/26 1:48、Mozilla HubsのUPDATEがあったとの記事が公開された↓
[A New Year, A New Hubs](https://blog.mozvr.com/hubs-interface-update/)

早速、本家サイト[Mozilla Hubs](https://hubs.mozilla.com/)に行ってみたら、
<b><font color="Red">垢ぬけた感ある。。！！！</font><b/>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/a6029cbc-c169-55c7-d39b-4f00029fe5dd.png)



大幅なUIの刷新があったんだね。
今回はそれをまとめたい。
まあ、上記記事読んで実際のサイト触ってみた感想記事みたいなところ。

# 更新個所
### チャットスライダーの追加
デスクトップは上のキャプチャを見ての通りで、
スマホ版だとこんな感じ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/688e61f0-6905-dd1e-8eec-59a497407a66.png)


Clusterには以前からあるやつだけど、
これまでのHubsにはチャットの板が部屋のなかに無く
書かれたメッセージは数秒間表示されてフェードアウトしていくという仕様だった。

Discord連携すればチャットをそっちに残せるという話はあったけど、
今回のブラッシュアップによって、移動無しで会話の内容を見返せる様になった。

### 各端末形態に合わせたUI
これまではVRを標準としてデザインし、デスクトップ版、アプリ版に統一感を持たせる形で展開してきたが、ほぼほぼのHubsユーザーはVR端末利用者で無い為、
デスクトップとアプリ版用のUIを別に用意した様だ。

例えば、部屋からメニューを開いたとき、デスクトップだとこんな感じで右の方にメニューパネルが出るが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/62a7b2cb-7d75-cbe6-c9e3-6d57f108ddfb.png)

アプリで開くと画面全体にメニューパネルが表示されるといった形で最適化されている↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/c4b78a25-49a5-27d5-04d0-9c457bf3ab5a.png)


触ってて思ったが部屋にいるときの画面も全体的にすっきりした印象。

実際のところHubsを積極的に触ってカスタマイズしている自分でさえ、
ぶっちゃけVR端末で操作したことが無いので、今回の様なHubsの現実志向は好きなところである。

### サポートフォーラムが出来た
現状、質問を上げるのは英語のみFireFoxブラウザのみでの対応。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/2cb89394-f4eb-d1ee-b45a-e125bc5f4589.png)

以前から日本語版のサポートサイトもあるが、[こちら](https://support.mozilla.org/ja/products/hubs)は質問は非対応とのこと。
といったも丁寧に利用方法とか基本的な内容は書いてあるので初めて触る人には役には立ちそう。


記事に書かれていた内容は以上となる。
シンプルさが良いHubsだったけど、最近は少しシンプル過ぎて退屈なUIな感じがあった。
今回のUI刷新でぐっと華やかになったのでとても嬉しい！！

今後も期待！
[WIP] WLS2で画像開発環境を整える

# やりたいこと
wsl2 + python3 + opencv + vscode + docker

# 環境
Windows10

# DONE
* WSL(ubuntu20.04)：略
* docker for windows インストール：略

## docker image 作成

Ubuntsu のイメージをダウンロードして docker 起動

```
$ sudo docker run -it ubuntu:20.04
```

ちな、イメージの保存は以下
* `ctrl + p, ctrl + q` でdockerコンソールを抜ける
* `sudo docker ps` で コンテナの ID を調べる
* `docker commit <コンテナID> <イメージ名>` でイメージを保存


## python3 で opencv を使ええるようにする

コンテナに入ったらapt を最新に

```
$ apt update
$ apt upgrade
```

python

```
$ pip install python3 python3-pip
```

ビルド済みopencv

```
$ pip install opencv-python
```

その他 opencv に必要なもの

```
 $ apt install -y libsm6
 $ apt install -y libxext6 libxrender-dev
 $ apt install -y libglib2.0-0
 $ apt install ffmpeg
 ```

確認

```
python3
> import cv2
```

# VSCode
Windows 側にインストールして使うのが楽
立ち上げて、リモートエクスプローラーをクリック↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62319/0f078a4e-d363-4aa7-acd6-b483c7d288cd.png)
Ubuntu-20.04 の表示にある「Connect to WSL」をクリック
新しいウィンドウが立ち上がり、Ubuntu内での作業が可能になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62319/bd69af1e-101c-97d3-51cb-512f82098f33.png)
VSCodeからターミナルを立ち上げてばdockerもそこからrunできるので、windowsからWSLを立ち上げるという操作はいらなくなる

```
docker run -it <image名>
```

# TODO
* sample 実行
UnityEditorなんかおかしい。。

<dl>
Unityバージョン
<dd>：2020.1.9f1</dd>
<Br>
こまった事
<dd>・シーンビューを拡大すると消えていく</dd>
<dd>・エディターでアスペクト比変えれない</dd>
<dd>・Canvasでアンカープリセット展開されない</dd>
<dd>などなど</dd>
<Br>
エラーメッセージ
<dd>UnityEditor.PopupWindow.Show (UnityEngine.Rect activatorRect, UnityEditor.PopupWindowContent windowContent, UnityEditor.PopupLocation[] locationPriorityOrder, UnityEditor.ShowMode showMode)I</dd>
<Br>
解決した方法
<dd><strong>=>デフォルトのレイアウトを設定してみてください（ウィンドウ->レイアウト->デフォルト）</strong></dd>
</dl>

--

https://answers.unity.com/questions/1779660/unity-bug-unityeditoreditorwindowclose.html
Ghidra を使ってみよう

## Ghidra is 何

Ghidra は NSA が開発したリバースエンジニアリングツールです。
"ギドラ" と読むそうです。名前といい、開発元といい、とても強そうですね（何が）。

## インストールと最初の起動

Mac の場合は Homebrew でインストールできます。

```sh
brew install java  # JDK がインストール済みの場合は不要
brew install ghidra
```

このままでも起動はするのですが、途中 GateKeeperでエラーになります。

![スクリーンショット 2021-01-26 6.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9549/746bad42-3d1b-3986-c0cd-d27615435051.png)

[issueは提案されていて](https://github.com/NationalSecurityAgency/ghidra/issues/1559)いくつか回避策はあるようですが、いまいちな気がしたので以下のようにしました。

```
xattr -d com.apple.quarantine /usr/local/Caskroom/ghidra/9.2.1,20201215//ghidra_9.2.1_PUBLIC/GPL/DemanglerGnu/os/osx64/demangler_gnu_v2_33_1
xattr -d com.apple.quarantine /usr/local/Caskroom/ghidra/9.2.1,20201215/ghidra_9.2.1_PUBLIC/Ghidra/Features/Decompiler/os/osx64/decompile
```

`ghidraRun` コマンドで起動します。
初回の起動時のみ JDK HOME を聞かれます。Homebrew でインストールした場合は `/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home` になります。

```
$ ghidraRun
******************************************************************
JDK 11+ (64-bit) could not be found and must be manually chosen!
******************************************************************
Enter path to JDK home directory: /usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home
Saved changes to /Users/user/.ghidra/.ghidra_9.2.1_PUBLIC/java_home.save
```

## Hello World!

Hello World!を解析してみましょう。

適当に対象のプログラムを作っておきます。

```
$ cat main.c
#include <stdio.h>

int main(void) {
	printf("Hello World!");
	return 0;
}

$ cc main.c
```

Ghidra を起動して、プロジェクトを作成します。

1. File > New Project
2. Non-Shared Project
3. Project Directory/Name は適当に。

**File > Import File** からこのプロジェクトに先程の a.out を登録します。
でもって登録した a.out をダブルクリックするとコードの解析画面になります。
左に３つ並んでいるパネルの **Symbol Tree** パネルで、Functions > Entry をクリックすると、main 関数にジャンプできます。

![entry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9549/e9ae3b9e-5c34-809c-d58f-57248a599ce9.png)
Swiper Slider Space matter on Smartphone. Swiperのスライダーでスマホ表示の時にできる余分なスペースの解消。


To make space smaller Swiper slider when viewing on smartphone. 
Swiperのスライダーを利用したときにスマホ（縦）表示で余分なスペースを解消。

Too much of space like below.
以下のようにスライダーの上下にスペースが。。。
<img width="400" alt="20210126_002546.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/750408/3f278d44-6572-14a3-48c2-4b593bbddfc1.jpeg">
There is a solution to make like this.
こんな感じに解決できます。
<img width="400" alt="20210126_002522.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/750408/ed3b044a-3fef-5054-fdbd-5e18f14964e1.jpeg">


The problem is this CSS code. you can just change this code to like below.
このコードだけではレスポンシブに対応できないので下に書いたスマホとPCでの表示を変えるコードにします。

```ruby:css
.gallery-top {
            height: 85%;
            width: 85%;
        }
````

Replace the code above with this code. 
以下のコードに書き換えます。

```ruby:css
        @media screen and (min-width: 751px) {
            .gallery-top {
                height: 85%;
                width: 85%;
            }
        }

        @media screen and (max-width: 750px) {
            .gallery-top {
                max-height: 85%;
                width: 85%;
            }
        }
git fetchとmerge、pullの関係をわかりやすく説明する【Gitコマンド解説②】

Gitコマンドはたくさんありますよね。git addとcommit,pushなどは良く使うコマンドだからわかるけど、

**fetch**、**merge**、**pull**になると「どういう意味かわからない...」という方は多いのではないでしょうか。


```
git fetch
git merge 
git pull
```

今日は3つのGitコマンドについて、できるだけわかりやすく解説していきます。<br><br>

そもそも**git addとcommit,pushがわからない！**という方は、こちらの記事を読んでくださいね。
↓↓↓
[git addとcommit、pushの関係をわかりやすく説明する【Gitコマンド解説①】](https://qiita.com/atsushi101011/items/96054ebbd876e378cac4)<br><br>



##git pullは、fetchとmergeの両方を組み合わせたコマンド

上記の記事で、ローカルリポジトリの内容をリモートリポジトリに送信（アップロード）することを**「push」**と呼びましたね。

反対に、リモートリポジトリからローカルリポジトリを更新することを**「pull」**と呼びます。

[![Image from Gyazo](https://i.gyazo.com/e16d11bd866d300ed92a4e248fc9a5df.png)](https://gyazo.com/e16d11bd866d300ed92a4e248fc9a5df)
画像引用:https://backlog.com/ja/git-tutorial/intro/02/

例えば、A君とB君がチーム開発しているとします。A君が更新したファイルをBくんにも反映させたいです。

これを実現する流れは、以下のようになります。

1.A君がローカルリポジトリの内容をリモートリポジトリに送信（アップロード）する(push)
2.B君がリモートリポジトリからローカルリポジトリを更新する(pull)<br><br>

これがpullの役割です。見出しには**「git pullは、fetchとmergeの両方を組み合わせたコマンド」**と書きました。以下のような関係式が成り立ちます。

```
pull = fetch + merge
```
ここでfetchとmergeの意味がわからない！となったと思うので、それぞれ解説していきます。<br><br>


##git fetchでリモートからローカルに持ってきて、git mergeでローカルを更新する

リモートリポジトリから最新情報をローカルリポジトリに持ってくることを**「fetch」**と呼びます。また、fetchを使ってローカルに持ってきた最新情報を更新することを**「merge」**と呼びます。mergeには「統合する、融合させる」という意味があります。<br><br>


さきほどの関係式をわかりやすくすると、こんな感じです。

```
pull(リモートから持ってきて更新) = fetch(リモートから持ってくる) + merge(ローカルを更新)
```

「**pull**と**fetch**なにが違うの？」と思ったかもしれません。

pullとfetchの違いは、**実際にファイルを更新するかどうかの違い**です。mergeをしないとローカルが更新されないわけですね。<br><br>

※個人開発の場合でも、ブランチを分けて作業することが多いと思います。ブランチで作業していた内容を統合させたいときにmergeコマンドを使うことになります。リモートリポジトリを共有するチーム開発だけで使うコマンドじゃないってことです。

##まとめ
```
1.リモートリポジトリから最新情報をローカルリポジトリに持ってくることを**「fetch」**と呼ぶ
2.fetchを使ってローカルに持ってきた最新情報を更新することを**「merge」**と呼ぶ
3.**「pull」**はmergeとfetchをまとめて行うコマンド<br><br>
```

これで、git fetchとmerge、pullの関係について理解が深まったかと思います。
次回は、git clone、log、branch、statusあたりのコマンドについて解説します。<br><br>


この記事の説明がわかりやすかった！ここ間違ってるよ！次こんな記事を書いて欲しい！などあればコメント、DMよろしくお願いします。LGTMもぜひ。


Twitterもやってますので、フォローしていただけたらうれしいです。
卓球、心理学、哲学、Webサービス、好きな音楽、カメラ、登山、ランニング、読んだ本などなんでもつぶやいてます。

[https://twitter.com/atsushi101011]
CentOS7 Visual Studio Codeを導入する

# 目的

- CentOS7のPCにVisual Studio Code（以後VScode）を導入する方法をメモ的にまとめる

# 方法

1. 下記にアクセスする。
    - [https://code.visualstudio.com/download](https://code.visualstudio.com/download)
1. 「.rpm」をクリックする。

    ![Download_Visual_Studio_Code_-_Mac__Linux__Windows.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/874c005f-edaa-72cd-f04d-df9298c13122.png)

1. ダウンロードフォルダを開き、只今ダウンロードしたVScodeの.rpmが存在していることを確認する。
1. 下記コマンドを実行してダウンロードフォルダに移動する。（言語設定によってダウンロードディレクトリ名が異なるため下記には二種類のコマンドを記載する。みなさんの環境に合わせてどちらか片方を実行すれば良い。）

    ```terminal
    $ cd ~/ダウンロード
    $ cd ~/downloads
    ```

1. 下記コマンドを実行してVScodeのインストールを行う。

    ```terminal
    $ sudo yum install code-X.XX.X-XXXXXXXXXX.XXX.x86_64.rpm
    ```

1. インストール確認が表示されたら「パッケージ」「バージョン」「リポジトリ」を確認し問題なさそうなら「y」を入力してEnterを押下する。
1. インストールが完了したら下記コマンドを実行してVScodeを起動する。

    ```terminal
    $ code
    ```

1. VScodeのウインドウが起動すれば正常に導入する事ができている。
GraphQLでresolverごとのパフォーマンスを計測する方法

GraphQLはresolverを再帰的に実行するため、仕様としてN+1問題を起こしやすく、パフォーマンス・チューニングは重要になってくるかと思います。

そして、実際のデータ操作を行うのがresolverになりますのでresolverごとにパフォーマンスがわかれば便利です。

僕はLaravelでGraphQLを扱うために便利なLighthouseというライブラリを使っているので、例としてはLighthouseでresolverごとにパフォーマンスを計測をする方法について、簡単にまとめました。

クエリー自体の重さを計測するのは別のライブラリとかでできるので、それと組み合わせていければはかどる気がしています。

Apollo TracingというGraphQL自体の拡張機能を使っているので、node.js, Ruby, Scala, Java, Elixir, .NET等でも使えるみたいです。


まだまだ理解が足りない部分や誤解している箇所がありましたらぜひ教えていただけると助かります！！

**開発環境**

- 言語：PHP7.4.8
- フレームワーク：Laravel7.28.3
- DB：MySQL8.0.22
- Lighthouse:4.15

# やり方

この`config/app.php`に下記の記述を加えるのみです。

```
'providers' => [
    \Nuwave\Lighthouse\Tracing\TracingServiceProvider::class,
],
```
そうすると、こちらのようにクエリーの下のほうにextensionsという項目ができ、それぞれのresolverの重さを計測をしてくれます。

https://lighthouse-php.com/master/performance/tracing.html

```
  "extensions": {
    "tracing": {
      "version": 1,
      "startTime": "2017-07-28T14:20:32.106Z",
      "endTime": "2017-07-28T14:20:32.109Z",
      "duration": 2694443,
      "parsing": {
        "startOffset": 34953,
        "duration": 351736,
      },
      "validation": {
        "startOffset": 412349,
        "duration": 670107,
      },
      "execution": {
        "resolvers": [
          {
            "path": [
              "hero"
            ],
            "parentType": "Query",
            "fieldName": "hero",
            "returnType": "Character",
            "startOffset": 1172456,
            "duration": 215657
          },
          {
            "path": [
              "hero",
              "name"
            ],
            "parentType": "Droid",
            "fieldName": "name",
            "returnType": "String!",
            "startOffset": 1903307,
            "duration": 73098
          },
```

pathや自分の型、フィールド名、返却する型等を取得をできます。
startOffsetのところの時間の単位はRFC3339の形式です。

重要なのはdurationで、こちらの単位はナノ秒です！


下記のページがGraphQLの拡張機能のapollo-tracingのページになり、詳細が記載されているので参考になります。
https://github.com/apollographql/apollo-tracing#response-format

# 今までのやり方（参考）

clockworkでクエリー自体の重さはわかるのですが、クエリーで取得をする量が多くなってくると、似たようなクエリーが多くなり、どこで発行をしているのかがあまり分からなくなってきてしまいました。

そこでどのresolverが重いか判別をするためには、計測したいクエリーをコメントアウトして、キャプチャのような感じで毎回chromeのdevツールでTimeがどれくらい変わるかを計測をしていました。
かなり微妙な気もしていて、とても面倒でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451174/80484193-4b77-0efc-1959-77418b513bd7.png)

最終的にクライアントにextentionsを見せないようにするとか考慮する必要はあると思いますが、他のツールと組み合わせればパフォーマンス・チューニングが今までよりかかなりはかどりそうです！！
udemyによるAWSの勉強② - IAMについて

#◆udemyの教材
本記事を作成するにあたって、参考にしたudemyの教材は以下のものになります。

これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）
https://www.udemy.com/share/101WKk/

#◆受講の目的
私はアプリを開発して、始めたいサービスがあります。
そのアプリでは動画を保存する必要があり、堅牢なサーバが必要となります。

どうにかならないかと調査していた時に、AWSのS3というファイルサーバを使えば、セキュリティ的にも容量的にも解決できることを知りました。

本講座で、AWSについて情報収集をし、アプリ開発に生かす予定です。

#◆IAMとは
Identity and Access Managementを略してIAMと呼びます。
このサービスはAWSでもかなり多く使う部類に入ります。

#◆IAMでできること
「認証」と「認可」の設定を行うことができます。
IAMによってこれらを正しく設定することで、AWSの利用者やAWSのサービスがアクセスできる範囲を制御することが可能になります。

#◆IAMポリシー
ユーザなどへのアクセス権限を付与するための設定ドキュメントを指します。
IAMポリシーはJSON形式の文書になります。

#◆IAMユーザ
IAMポリシー内でAWSサービスを利用できるユーザを指します。
基本相曽はIAMユーザで実施することになります。

#◆ルートユーザ
IAMユーザはIAMポリシーによって制限がかけられますが、ルートユーザはすべての権限を保有するアカウントになります。
このアカウントはAWSアカウント作成時に作られます。

#◆ルートユーザではなくIAMユーザを使う理由
ルートユーザはすべての権限を保有しているため、間違えて設定を変更した場合、システム上大きなトラブルを生む可能性があります。
そのため。IAMポリシーによって、ルートユーザでしかできない権限と切り分けて作業するのが推奨されます。

#◆IAM権限のベストプラクティス
ベストプラクティスとは、最も適した運用方法を指します。
IAMを利用する際のベストプラクティスは以下のようなものがあります。

+ AWSアカウントのルートユーザのアクセスキーをロックして通常はルートユーザを使用しない
+ 個々のIAMユーザを作成して、IAMユーザで管理を行う
+ IAMユーザへのアクセス認可の割り当てには、IAMグループを利用する
+ IAMユーザやIAMグループには最小権限のみを割り当てる
+ 新しくポリシーを作るのではなく、AWS管理ポリシーを利用する
+ ・・・・

#◆まとめ
②ではIAMについて記載しました。
このサービスはほとんどのパターンで利用されるかと思いますので、重要なサービスになると思います。
YML読み込み

yaml:
  name: foo
  aliases:
    - abc
    - xyz


package com.example.util;

import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@ConfigurationProperties(prefix = "yaml")
@PropertySource(value = "classpath:foo.yml", factory = YamlPropertySourceFactory.class)
public class YamlFooProperties {

    public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<String> getAliases() {
		return aliases;
	}

	public void setAliases(List<String> aliases) {
		this.aliases = aliases;
	}

	private String name;

    private List<String> aliases;

    // standard getter and setters
}

package com.example.util;

import java.io.IOException;
import java.util.Properties;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

public class YamlPropertySourceFactory implements PropertySourceFactory {

	@Override
	public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource)
			throws IOException {
		YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
		factory.setResources(encodedResource.getResource());

		Properties properties = factory.getObject();

		return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
	}

}
BERTで行う文章分類 PART2（データ編）

今回の文章分類で用いるデータは以下からダウンロードできます。
https://drive.google.com/drive/folders/1-m2pJzWDlZTVIZsl0OBj7UwVs0liOMi_?usp=sharing

![イラスト- data.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053943/7b122308-3e81-f7df-74e3-a2d490aee5a0.jpeg)
Python Classのまとめ

#0. はじめに
　クラスを継承後、サブクラスでメソッドをオーバーライドする。この時スーパークラスのメソッドはどうなっているだろうか。
　上記の疑問を解決すると同時に、クラスの定義、クラスメソッドとインスタンスメソッド、継承とオーバーライドをまとめる。
#1. クラスの定義
Pythonでは`class クラス名`でクラスを定義することができる。

```python

class SuperClass:
```

#2. クラス変数とクラスメソッド
クラス変数は`変数名 = 値`で定義が可能だが、クラスメソッドを作成する際はdef宣言の前に`@classmethod`とメソッドがクラスメソッドであることを宣言する必要がある。
また、引数として`cls`を渡し、クラス変数は`cls.変数名`で呼び出すことが可能だ。

```python
count = 0     #クラス変数の定義

@classmethod     #クラスメソッドの定義
def ClassMethod(cls):
    cls.count += 1
    return cls.count
```

#3. インスタンスメソッド
インスタンスメソッドは`def __init__(self)`内に`self.変数名 = 値`で定義し、呼び出す際も`self.変数名`で呼び出す。
インスタンスメソッドは`def メソッド名(self)`で定義が可能である。

```python
def __init__(self, i):     #インスタンス変数の定義
    self.count = 0
    self.i = i

def InstanceMethod(self):     #インスタンスメソッドの定義
    self.count += self.i
    return self.count
```

#4. 継承
クラスを継承する際は`class クラス名(スーパークラス名)`とすることでスーパークラスの継承が可能だ。
また、スーパークラスのインスタンス変数をそのまま使用したい場合は、`super().__init__(変数名)`で継承される。

```python
class SubClass(SuperClass):

def __init__(self, i):
    super().__init__(i)    #スーパークラス変数の継承
    self.count()
```

#5. オーバーライド
スーパークラスのインスタンスメソッドをオーバーライドすることも可能だ。オーバーライドする際は`def メソッド名(self)`の後に新しい処理を記述すれば良い。

```python
def InstanceMethod(self):
    self.count += self.i + 1
    return self.count
```

#6. 実行して比較
上記で作成したクラスを実際に使ってみよう。今回はクラスメソッド、スーパークラスのインスタンスメソッド、サブクラスのインスタンスメソッドすべてを5回呼び出し値を比べてみる。なお、サブクラスでオーバーライドしたメソッドはスーパークラスではどうなっているのか確認するため、サブクラスのメソッドを先に呼び出している。

```python
SubInstance = SubClass(1)    #Class2のインスタンス作成
SuperInstance = SuperClass(1)    #SuperClassのインスタンス作成
c = []    #クラスメソッド用リスト
i1 = []    #SuperClassのインスタンスメソッド用リスト
i2 = []    #SubClassのインスタンスメソッド用リスト
for _ in range(5):
    c.append(SuperClass.ClassMethod())
    i2.append(SubInstance.InstanceMethod())
    i1.append(SuperInstance.InstanceMethod())
print(c, i1, i2)
```

```python
[1, 2, 3, 4, 5][1, 2, 3, 4, 5][2, 4, 6, 8, 10]
```

#7. まとめ
　継承したクラスのインスタンスメソッドを先に作成し実行しても継承前のインスタンスメソッドの実行結果は作成通りの挙動をする。つまりメソッドをオーバーライドしてもスーパークラスのメソッドは上書きされていないことがわかる。
rails resources

#resourcesとは
railsで定義されている7つのアクションのルーティングを自動で作成するメソッド
具体的には

|アクション名| 役割 |
|:-:|:-:|
|  index |  リソースの一覧を表示させる |
|  show |  リソースの詳細を表示させる |
|   new|   投稿フォームを表示させる|
|  create | リソースを追加させる  |
|  edit |  更新フォームを表示させる |
|  update | リソースを更新させる |
|  destroy |  リソースを削除する |

```
resources :tweets
```
と

```
get 'tweets'     => 'tweets#index'
    get 'tweets/:id' => 'tweets#show'
    get 'tweets/new' => 'tweets#new'
    post 'tweets' => 'tweets#create'
    get 'tweets/:id/edit' => 'tweets#edit'
    patch 'tweets/:id'  => 'tweets#update'
    delete 'tweets/:id' => 'tweets#destroy'
```
は同じ意味

複数の場合はコントローラー名を続けて書く

```
 resources :コントローラー名, :コントローラー名
```
した二つは同じ意味。onlyはそれのみを許可する。exceptはそれのみを拒否する。

```
 resources :tweets, only: [:index, :snow]
 resources :tweets, except: [:new, :create, :edit, :update, :destroy]
```

#参考サイト

[こちら](https://pikawaka.com/rails/resources)
WordPressエラー


#概要
現在WordPressのテンプレートを使ってブログ運営を行っています。
先日ふとページを見たとき、見慣れないエラーを発見しました。「テンプレートを使ってエラーが出ることなんてあるの？」と思いながらも、現状エラーが出ているので記録として記事に残します。
ちなみにPHPは初学者です！

##エラー内容

![スクリーンショット 2021-01-26 3.48.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792954/9017374d-966d-910b-64ee-9e112360cde9.png)

上記の写真の中段あたりにエラーが出ています。

Warning: sprintf(): Too few arguments in /home/ponponponta/pontyblog.com/public_html/wp-content/themes/blog-prime/inc/breadcrumbs.php on line 259

こちらのエラーは置換文字列と対象文字列が違うというものです。


##エラー部分
ファイルの該当部分は以下の記述です。

```php
sprintf( '<a href="'.esc_url( $link_item ).'" itemprop="item">%s</a>', $item );
```

そして、この記述を以下の記述に変更するとエラーを消すことができます。

```php
sprintf( '<a href="%s" itemprop="item">%s</a>', esc_url( $link_item ), $item );
```

##追記
このエラーはWordPressやテーマのアップデートで解決することも可能です。またPHPのバージョンを下げることでエラー解消することもあるそうです。
私はエラー解決しをした後、結局別テーマに変更して運用しています。

テーマエディタを触ることに慣れていない方や、エラーがどうしても解決できない方は、テーマの変更やアップデートをお勧めします。
変数とif文

userが存在するかどうか判別が可能

```terminal
> user = User.first
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at:, updated_at:, password_digest: >

> if user
>   puts "user exist"
> else
>   puts "user don't exist"
> end
user exist
=> nil

irb(main):012:0> user = nil
=> nil

> if user
>   puts "user exist"
> else
>   puts "user don't exist"
> end
user dont exist
=> nil
```
またuserのパスワードが``foobar``の場合
``authenticateメソッド``を使うことでパスワードと一致してるか検証可能

```terminal
> user = User.first
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at:, updated_at:, password_digest: FILTERED]>

> if user.authenticate("foobar")
>   puts "Password is correct"
> else
>   puts "Password is wrong"
> end
Password is correct
=> nil

> if user.authenticate("")
>   puts "Password is correct"
> else
>   puts "Password is wrong"
> end
Password is wrong
=> nil
```
paranoia only_deletedメソッドのクセ

## 何が言いたいか
paranoiaが用意している`only_deleted`メソッドは便利そうに見えてクセがあるなと感じました。

## paranoia？
https://github.com/rubysherpas/paranoia
論理削除でおなじみのgem。
`acts_as_paranoid`とモデルに書くだけで、物理ではなく論理削除してくれるようになる。
（destroy!とかするとdeleted_atに値が入る）

## 事象
下記のようなテーブルがあるとします。
**Userモデル**

| id | name | age | deleted_at |
| --- | --- | --- | --- |
| 1 | けんじ | 5 | 2021-01-01 11:38:30
| 2 | たろう | 6 | null |
| 3 | じろう | 5 | null |

## 今回登場するメソッド
### with_deleted
論理削除されたレコードも取得できる
便利そう！

```ruby
User.all
# => ID: 2, 3を取得できる
User.with_deleted
# => ID: 1, 2, 3を取得できる
```
### only_deleted
論理削除されたレコードのみ取得できる
これも便利そう！

```ruby
users = User.with_deleted
# => ID: 1, 2, 3のレコードを取得できる

users.only_deleted
# => ID: 1のみ取得できる
```

## 何がクセ？
### 5歳児のレコードをusersに代入
```ruby
users = User.where(age: 5)
p users
# => <ActiveRecord::Relation [#<User id: 3, name: "じろう", age: 5, deleted_at: nil>]>
```
### それにonly_deletedしてみる
```ruby
p users.only_deleted
# => <ActiveRecord::Relation [#<User id: 1, name: "けんじ", age: 5, deleted_at: 2021-01-01 11:38:30>]>
```
id: 1のけんじくんのレコードがとれている・・・。
usersに論理削除されたレコードは無いので、てっきり何も返ってこないものと思いました。
`where.not(deleted_at: nil)`した時とは挙動が異なるようですね。

## ソースを見に行く
https://github.com/rubysherpas/paranoia/blob/032a2ad4df8e623b6a276edd22305ef3b63b5b91/lib/paranoia.rb#L34-L45

```ruby
    def only_deleted
      if paranoia_sentinel_value.nil?
        return with_deleted.where.not(paranoia_column => paranoia_sentinel_value)
      end
      # if paranoia_sentinel_value is not null, then it is possible that
      # some deleted rows will hold a null value in the paranoia column
      # these will not match != sentinel value because "NULL != value" is
      # NULL under the sql standard
      # Scoping with the table_name is mandatory to avoid ambiguous errors when joining tables.
      scoped_quoted_paranoia_column = "#{self.table_name}.#{connection.quote_column_name(paranoia_column)}"
      with_deleted.where("#{scoped_quoted_paranoia_column} IS NULL OR #{scoped_quoted_paranoia_column} != ?", paranoia_sentinel_value)
    end
    alias_method :deleted, :only_deleted
```
なんか最初に`with_deleted`している。。
なるほど、`only_deleted`とは、

```ruby
users = users.with_deleted
# => ID: 1, 3を取得
users.where.not(deleted_at: nil)
# => ID: 1を取得
```
をしているというわけですね。

## あとがき
単純に論理削除されたレコードのみ取得するときは`where.not(deleted_at: nil)`するのもありだと思いました。
「便利ー！」と思って`only_deleted`を使うと、場合によっては意図しない論理削除されたレコードを拾ってくる可能性がありそうだなと。
（ActiveRecordを取得するスコープが意図したものしか取得しない保証があるならOKだと思います。）

あと`deleted`というエイリアスがあったの初めて知りました。
HTMLとJavaScriptだけで複数の画像ファイルのアップロードとプレビュー

#はじめに
HTMLとJavaScriptを用いて複数画像のアップロードとプレビューを行うWebサイトを作成するにあたって，Web検索したところあまり記事がヒットしなかったため自作したプログラムを公開しようと考えました．JQueryなどは使わず，素のJavaScriptで作成しました．
JavaScriptについての知識が浅いため，スマートでない部分もあるかと思います．

#仕様
1. HTMLとJavaScriptのみで実装する． 
1. 画像を複数枚同時に投稿できる．
1. 投稿した画像は横並びにプレビュー表示される
1. 削除ボタンを押すとプレビューから削除される

```:フォルダ構成
．
├─index.html
├─js/
　　└─main.js
├─css/
　　└─style.css
```

#HTMLで雛形を作る

まずは，HTMLで雛形を作っていきます．
ファイルアップロードのためのフォームと，空のdivタグを置いておきます．

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <title>画像アップロード</title>
    <link rel="stylesheet" href="./css/style.css">
</head>

<body>
    <h1>画像アップロード</h1>
    <form>
        <input type="file" accept="image/*" multiple=" multiple" onchange="loadImage(this);">
    </form>
    <div id="imgPreviewField">
    </div>
    <br>
    <script type="text/javascript" src="./js/main.js">
    </script>
</body>

</html>
```

#JavaScriptを書いていく
JavaScriptで動きの部分を書いていきます．
`key`は，アップロードされた画像に付与する一意のIDを管理します．
画像をアップロードする際は，`<figure></figure>`で画像本体と削除ボタンを囲んだものを`<div></div>`内に追記していきます．
`inputタグ`内に`name属性`として画像固有のIDを保持して置くことで，個別に削除ができるようにしています．
削除ボタンが押されると，`getElementById(img-xxx)`の形で対象要素を取得し，`remove()`を行います．

```javascript:./js/main.js
let key = 0;
function loadImage(obj) {
    for (i = 0; i < obj.files.length; i++) {
        var fileReader = new FileReader();
        fileReader.onload = (function (e) {
            var field = document.getElementById("imgPreviewField");
            var figure = document.createElement("figure");
            var rmBtn = document.createElement("input");
            var img = new Image();
            img.src = e.target.result;
            rmBtn.type = "button";
            rmBtn.name = key;
            rmBtn.value = "削除";
            rmBtn.onclick = (function () {
                var element = document.getElementById("img-" + String(rmBtn.name)).remove();
            });
            figure.setAttribute("id", "img-" + key);
            figure.appendChild(img);
            figure.appendChild(rmBtn)
            field.appendChild(figure);
            key++;
        });
        fileReader.readAsDataURL(obj.files[i]);
    }
}
```

#CSSで画像を横並びにする
`figureタグ`に`display:inline-block;`を設定することで画像を横並びに表示します．
お好みで見た目を整えたら完成です．

```css:./css/style.css
div figure{
    display: inline-block;
}
body{
    padding-top: 4px;
    border: 1px solid #ddd;
    border-radius: 3px;
    text-align: center;
}

```

#おわりに
同じようなことをやっている方はいたのですが，RubyやJQueryを使用していたり，JavaScript内にHTMLを直書きしていたりといった感じが多かったので，思い切って初投稿してみました．改善点などあれば，是非ご指導ください．

#参考にしたサイト
* [JavaScriptでFileReaderを使った複数画像のプレビュー例](https://blog.ver001.com/javascript-image-preview-multiple)
Ubuntuにフォントをインストール


どこからフォントをインストールするかで若干手順が異なります． 

# Google Fonts のフォントをインストール

1. [GoogleFont](https://fonts.google.com/)から好きなフォントをダウンロード  
  (今回はPT_Monoをダウンロードしました)
2. ダウンロードしたファイルを解凍し，決められたフォルダに配置

       ```sh
       $ cd path/to/downloaded_font_directory
       $ unzip PT_Mono.zip -d PT_Mono
       $ cp PT_Mono/*.ttf ~/.fonts/
       ```

3. 再起動



# macのフォントをインストール

1. [Appleのサイト](https://developer.apple.com/fonts/)からフォントをダウンロード  
(今回はSF-Monoをダウンロードしました)
2. ダウンロードしたファイルを解凍し，決められたフォルダに配置

       ```sh
       $ cd path/to/downloaded_font_directory
       $ 7z x SF-Mono.dmg
       $ cd SFMonoFonts/
       $ 7z x SF\ Mono\ Fonts.pkg
       $ 7z x Payload\~
       $ mkdir ~/.fonts        # If there is no directory
       $ cp Library/Fonts/* ~/.fonts
       ```

3. 再起動



`7z`がなければ

```sh
$ sudo apt install p7zip-full
```

# 参考
[How to Install New Fonts in Ubuntu and Other Linux Distributions
](https://itsfoss.com/install-fonts-ubuntu/)
[Install Mac OSX fonts on Linux easily.](https://securitronlinux.com/debian-testing/install-mac-osx-fonts-on-linux-easily/)
docker コマンド　[自分用]

### docker コマンド

```

docker pull <image>
# イメージをホストに入れる

docker run -it <image> <command>
# imageからコンテナをたててcommandを実行 bashコマンドなど
# hostからimageを探して、なければdocker-hubから持ってくる

docker ps -a
# コンテナ一覧

docker images
# ホストにあるimageの一覧

docker restart
# コンテナをupにする

docker exec -it <container> bash
# bash起動

docker commit
# コンテナをimageにする

docker rmi <image>
# イメージ削除

docker rm <container>
# container削除

docker system prune

# nonname image 全削除

```

docker run のオプション

```
docker run -it <image>
-i: input可能
-t: 表示を綺麗にする

docker run --name <name> <image>
--name: 名前をつける

docker run -d <image>
-d: detached modeで起動　バックグラウンドで動かす

docker run --rm <image>
--rm: foreground modeで起動　コンテナをexit後に削除

```

docker build のオプション

```

# リポジトリ名をつける
docker build -t <name> <path>
```
docker instructions [自分用]

## docker instructionsについて


### FROM

基本となるimageを指定

```
FROM alpine:latest
```

### RUN

レイヤを作りコマンドを走らせる
キャッシュできる


```
RUN apt-get update 
RUN apt-get install -y curl
```

###CMD

build後に実行したいコマンドを記述
レイヤは作らないのでキャッシュにはならない

```
CMD ["<コマンド>", "<コマンド引数>"]
CMD ["/bin/bash"]
```

### ENTRYPOINT

デフォルトコマンドを指定できるが、docker run で上書きできない
またCMDがデフォルト引数になる


### ADD
圧縮ファイル(.tar)をimageに組み込む際によく使われる
iamge内ではファイルは解凍される

```
ADD alpine-minirootfs-20201218-x86_64.tar.gz /
```

### COPY

COPYに指定したファイルをdocekr imageに組み込んで
docekr-container内を利用できる。

```
COPY <file名> <path>

```
### WORKDIR
作業ディレクトリの指定
以降のRUNは指定したディレクトリで実行される

```
WORKDIR /sample_folder
```
(覚書) クリーンアーキテクチャ 第2部 構成要素から始めよ：プログラミングパラダイム

構成は各章毎に分けて、要約・独自の解釈・具体的なコード等を挟み、なるべく腑に落ちやすい形を目指す。
独自の解釈を挟む際は冒頭に "ダブルコーテーションをつける。

"第二章は歴史のお勉強ですね

# 第2部 構成要素から始めよ：プログラミングパラダイム

ソフトウェアアーキテクチャはコードから始まる。
1938年, Alan Turingがコンピュータプログラミングの基礎を築いた。
1945年まで、彼は実際のコンピュータで、実際のプログラムを書いていた。彼の使用していた言語はバイナリだ。

それから様々な革命が起きた。

- 言語の革命
    - 1940年代後半にアセンブラが登場
        - プログラムをバイナリに翻訳する負担を無くした。
    - 1951年にGrace Hopperがコンパイラを考案
        - プログラムを英語で記述できるようにした。
    - その後、COBOL、PL/I、SNOBOL、C、Pascal、C++、Javaなど絶え間なく新しい言語が生み出されている。
- プログラミングパラダイムの革命
    - パラダイムとは、プログラミングの方法のことで、どのプログラミング構造を使うべきか、いつ使うべきかを教えてくれる。
    - 現在まで、大きく3つのパラダイムが存在している。どれもお互いに似ているところがない。


## 第3章 パラダイムの概要

### 構造化プログラミング

> 構造化プログラミングは、直接的な制御の移行に規律を課すものである。

最初に導入されたパラダイムは1968年にEdsger Wybe Dijkstraが発見した「構造化プログラミング」である。

Dijkstraは制限のないジャンプを if/then/else、do/while/until に置換えた。

### オブジェクト指向プログラミング

> オブジェクト指向プログラミングは、間接的な制御の移行に規律を課すものである。

次に導入されたパラダイムは、構造化プログラミングの2年前の1966年に Ole Johan Dahl と Kristen Nygaard が発見したオブジェクト指向プログラミングである。

この2人は、ALGOL言語の関数呼び出しのスタックフレームをヒープに移動できること、これにより、関数から戻ってきたあとでも関数で宣言したローカル変数が存在し続けられることに気づいた。

- この関数は今日のクラスのコンストラクタになり、ローカル変数はインスタンス変数になった。
- そしてネストした関数はメソッドになった。
- 規律のある関数ポインタの使用により、ポリモーフィズムの発見に繋がった。

"[クロージャー](https://en.wikipedia.org/wiki/Closure_(computer_programming))との関係も凄く近い気がする。
1960年代に開発された概念のよう。ここの歴史的な繋がりはもっと深堀りたい。


### 関数型プログラミング

> 関数型プログラミングは、代入に規律を課すものである。

3つのパラダイムの中では最も早く発明された。

Alonzo Church の業績で、Alan Turing が挑んでいた数学的問題を追求しながら、1936年にラムダ計算を発明した。
ラムダ計算の基本的な概念は不変性である。
このことにより、関数型言語には代入文がないことを意味する。
実際には、変数の値を変更する手段が用意された言語も多いが、非常に厳しく制限されている。

### 考えるべきこと

意図的に3つのパラダイムのパターンを紹介した。
これらのパラダイムは、プログラマから能力を削除している。
何をすべきかを伝えるよりも、何をすべきでないかを伝えている。

1958年から1968年の10年間に発見された3つのパラダイム以降、新しいパラダイムは追加されていない。

### まとめ

パラダイムの歴史的な教訓は、アーキテクチャの全てに関係している。

- アーキテクチャの境界を超えるための仕組みとして、ポリモーフィズムを使う。
- データの配置やアクセスに規律を課すために、関数型プログラミングを使う。
- モジュールのアルゴリズムの基礎として、構造化プログラミングを使う。

これらの3つが、アーキテクチャの3つの大きな関心事「コンポーネントの分離」「データ管理」「機能」に対応している。

## 第4章 構造化プログラミング

coming soon.
Symbol from NEM のブロック生成を観察する

Symbol from NEM のコミュニティによるテストが実施されます。
ぜひ、このイベントのタイミングでブロックチェーンのロールバックとファイナライズをリアルに体感しましょう。とくにNEMでの決済を検討している方は、どのタイミングで送金が確定されるのかを知ることはとても大切なことですので、頭で理解するだけではなくブロックの生まれて、そして一部が消えて、永遠に残り続ける様子を一度は観察しておきましょう。

まず、接続するノードを選択します。
https://symbolnodes.org/nodes/

私が設置しているHTTPS対応ノードは以下になります。
https://node.xembook.net

F12キーを押してコンソールを開いて以下のスクリプトを入力していきます。

##### ライブラリの埋め込み
```js
NODE = window.origin;

(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.0.js';
document.getElementsByTagName('head')[0].appendChild(script);

```
アクセスするノードの指定とbrowserify化したsymbol-sdkを表示したページに埋め込みます。

##### 事前準備
```js
nem = require("/node_modules/symbol-sdk");
op  = require("/node_modules/rxjs/operators");
repo = new nem.RepositoryFactoryHttp(NODE);
nsRepo = repo.createNamespaceRepository();
blockRepo = repo.createBlockRepository();

wsEndpoint = NODE.replace('http', 'ws') + "/ws";
listener = new nem.Listener(wsEndpoint,nsRepo,WebSocket);

(async() =>{
epochAdjustment = await repo.getEpochAdjustment().toPromise();
})();

```
必要なクラスを生成しておきます。

##### Blockのリスニング
```js
latest_block = 0;
last_finalized_block = 0;

listener.open().then(() => {
    setInterval(function(){
        listener.newBlock()
    }, 30000);
    
    listener.newBlock()
    .pipe(
      op.mergeMap(x=>blockRepo.getBlockByHeight(x.height))
    )
    .subscribe(x=>{
      console.log("------------------");
      if(latest_block >= x.height.compact()){
          console.log("■■■　roll back!!　■■■");
      }
      console.log("prevHash:" + x.previousBlockHash);
      console.log("timestamp:" + new Date(Number(x.timestamp.toString()) + epochAdjustment * 1000));
      console.log(x.height.compact() + ":("+ x.totalTransactionsCount  +"txs):"+ x.hash);
      latest_block = x.height.compact();
      
    });
    
    listener.finalizedBlock()
    .subscribe(x=>{
        diff_max = latest_block - last_finalized_block; 
        diff_min = latest_block - x.height.compact();
        if(last_finalized_block != 0){
          console.log("================");
          console.log("FinalizedBlock:" + x.height.compact() + ":" + diff_min.toString() +"<" + diff_max.toString() + ":" + x.hash);
        }
        last_finalized_block = x.height.compact();
    })    
});

```

リスナークラスを利用してBlock情報を取得します。


リスナーを実行すると以下のようにコンソール出力されていきます。

![スクリーンショット 2021-01-26 1.30.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/48b372fa-10e2-f994-19f9-66494c520e2b.png)

prevHashが前のブロックのハッシュ値と一致しているのがわかります。
ロールバックが発生すると以下のように表示されます。

![スクリーンショット 2021-01-26 1.36.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/eff7d705-ab11-2ba6-a209-2f36b622cf82.png)

ブロック高：49695 で 898txsのブロックがロールバックされて894txsのブロックが次のブロックに引き継がれていくのがわかります。

ファイナライズが発生すると以下のような表示になります。
![スクリーンショット 2021-01-26 1.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/77cf9885-4a6a-e12e-cd4b-fabf35fc8671.png)

49680のブロックがファイナライズされ、最短で25個、最長で29個前に生成されたブロックが確定されたことを意味します。
AWSとは。簡単に。

## AWSとは
AWS(Amazon Web Services)は、Amazon社が提供するクラウドサービスです。クラウドサービスとしては最大規模で１００以上のサービスが存在します。

### 特徴
・サービスがとにかく豊富！
・リソースを必要なときに必要な分だけ調達できる為、とても柔軟です。
・使った分だけ支払う従量課金を採用している。


###インフラを構築することできる
まずインフラとは何でしょうか？
・インフラとはサーバーやネットワークのことで、Infrastructure(基盤)と言います。
　　　　　　　　　　　↓
サーバーとは、クライアントに対してサービスを提供する。例えば、Webサーバーだったり、データベースサーバー。そのクライアントとサーバーのデータの送受信がネットワークと言います。

###クラウドとは？
クラウドコンピューティングと言いまして、ネットワークと使ってコンピューターリソースを利用する形態のこと。形態にも種類があって、また後日調べて記事書きます（＾＿＾；）

まとめると、AWSはサーバー、ネットワークなど様々なサービスを提供するクラウドサービスということ。

インフラができるようになると、自身でインフラ構築してサービスをリリースできます。

###インフラを構築する場合
サーバーを設置して、OSやそれぞれ必要なソフトウェアをインストールして設定する。
ネットワークの構成としましては、設置したサーバーをネットワークに接続する。そのネットワークで使用するIPアドレスの範囲を決めて設定でき、IPアドレスに割り当てる。

###IPアドレス
IPアドレスとは、コンピュータやサーバーに設定されたインターネット上の住所のことを指します。
インターネット上においてIPアドレスは世界中でたった1つです。この住所を指定することで、特定のコンピュータやサーバーと通信することができるようになります。

# 終わりに

すごく簡単にAWSについて話しました。基礎から勉強して、また記事書きたいと思います。
ConoHa VPSでターミナル使った時につまづいたところ

<p>Qiita初めての投稿です。暫定でつまづいたところを備忘録も兼ねて書いていきます。
<p>ConoHa VPSの初心者向け講座　ConoHa教室
https://support.conoha.jp/vps/?btn_id=v-hellovps-w-02-vpsGlonavi_school#school
ではSSHクライアントソフトに「Teraterm」を使って説明が続くのですが、Macの場合はターミナルにSSHクライアントソフトが最初から入っているので、それを使いたいと考えました。
<h2>一般ユーザーでログインができない


root権限でログイン。一般ユーザーを作成したところまでは良かったんですが、そのユーザーでloginしようとしてもなかなか入れません。

```
ssh root@(IPアドレス)
Password:(一般ユーザー名)
Permission denied, please try again.

```
or

```
su -
Password:(一般ユーザーで作成したパスワード)
su: Sorry
```


これを２００回ほど繰り返しました。何故なのか... ...

root権限のログイン方法で試していたのでこれがいけなかった。su -はログイン後に入力する物だと気づくのに、だいぶ時間を取られました。


正解は

```
ssh （一般ユーザー名)@(IPアドレス)
Password:(一般ユーザーで作成したパスワード)
```
これで一般ユーザーとしてVPSにログインする事ができました。

<h2>サーバーを再構築した後にターミナルで入れない

Conohaはサーバー構築時にオプションで色々アプリケーションを入れてくれる。gitlabに興味が出たのでインストールしてたら、面倒臭くなり、そしたら上の機能を知ったので、再構築することにしました。

しかし、再構築後にターミナルでログインを試みたところ、

```
WARNING: POSSIBLE DNS SPOOFING DETECTED! 
```
どうやら以前に作ったサーバーの設定がターミナル側に残っているようなので、これを削除する必要があります。
vim使って

```
~/.ssh/known_hosts
```
の該当箇所を消してしまうと言う方法か、もっと簡単にrmを使って削除してしまう方法があります。そうすると、また新規のサーバーをターミナルでログインできるようになります。

<h2>未解決の問題


次につまづいたのは、root権限から直接ログインを禁止する方法です。
手順はroot権限でログインをして、Permitrootloginを「Yes」から「No」に変えて保存しただけ... ...

一般ユーザーでログインできない時に、「root権限で入れないし、一般ユーザーでも入れないから詰みか」と匙を投げそうになりましたが、その時ダメもとでroot権限のままログインを試みましたところ、何故かできてしまいまして、それはまだ解決に至ってないのです。(2021/1/26現在)
PokéAPIで取得できる値の紹介（きのみ編）

こんばんは、佐藤です。
ポケモンだいすきエンジニアです。
第2回目の投稿となりました。
~~（記事のフォーマットは前回の焼き増しです）~~

[公式ドキュメント](https://pokeapi.co/docs/v2)を参考にPokéAPIを利用して取得できる値の紹介をしたいと思います。
今回は「きのみ」編となります。（ポケモンに関する用語を多少知っていないと意味がわからないかもしれません）

# PokéAPIとは（ざっくり）
莫大なポケモンの情報を取得することができるRESTful-APIです。
https://pokeapi.co/

# 値の取得方法
情報を取得するだけであれば非常に簡単です。
情報が知りたいきのみに合わせて以下のURLを実行すれば、
そのきのみに関連する情報がJSON形式で表示されたページにアクセスできます。

```URL
https://pokeapi.co/api/v2/berry/{id or name}/
```

idとnameはそれぞれ以下のように対応しています。

<details><summary>対応表（数が多いので折りたたみ）</summary>
<div>

| id | name | タイプ名 |
|:-:|:-:|:-:|
|1|cheri|クラボのみ|
|2|chesto|カゴのみ|
|3|pecha|モモンのみ|
|4|rawst|チーゴのみ|
|5|aspear|ナナシのみ|
|6|leppa|ヒメリのみ|
|7|oran|オレンのみ|
|8|persim|キーのみ|
|9|lum|ラムのみ|
|10|sitrus|オボンのみ|
|11|figy|フィラのみ|
|12|wiki|ウイのみ|
|13|mago|マゴのみ|
|14|aguav|バンジのみ|
|15|iapapa|イアのみ|
|16|razz|ズリのみ|
|17|bluk|ブリーのみ|
|18|nanab|ナナのみ|
|19|wepear|セシナのみ|
|20|pinap|パイルのみ|
|21|pomeg|ザロクのみ|
|22|kelpsy|ネコブのみ|
|23|qualot|タポルのみ|
|24|hondew|ロメのみ|
|25|grepa|ウブのみ|
|26|tamato|マトマのみ|
|27|cornn|モコシのみ|
|28|magost|ゴスのみ|
|29|rabuta|ラブタのみ|
|30|nomel|ノメルのみ|
|31|spelon|ノワキのみ|
|32|pamtre|シーヤのみ|
|33|watmel|カイスのみ|
|34|durin|ドリのみ|
|35|belue|ベリブのみ|
|36|occa|オッカのみ|
|37|passho|イトケのみ|
|38|wacan|ソクノのみ|
|39|rindo|リンドのみ|
|40|yache|ヤチェのみ|
|41|chople|ヨプのみ|
|42|kebia|ビアーのみ|
|43|shuca|シュカのみ|
|44|coba|バコウのみ|
|45|payapa|ウタンのみ|
|46|tanga|タンガのみ|
|47|charti|ヨロギのみ|
|48|kasib|カシブのみ|
|49|haban|ハバンのみ|
|50|colbur|ナモのみ|
|51|babiri|リリバのみ|
|52|chilan|ホズのみ|
|53|liechi|チイラのみ|
|54|ganlon|リュガのみ|
|55|salac|カムラのみ|
|56|petaya|ヤタピのみ|
|57|apicot|ズアのみ|
|58|lansat|サンのみ|
|59|starf|スターのみ|
|60|enigma|ナゾのみ|
|61|micle|ミクルのみ|
|62|custap|イバンのみ|
|63|jaboca|ジャポのみ|
|64|dragon|レンブのみ|

</div>
</details>
たとえば、イトケのみの情報が知りたい場合は以下のどちらかのリンクからアクセスすることができます。
https://pokeapi.co/api/v2/berry/37/
https://pokeapi.co/api/v2/berry/passho/



# 取得できる値
[マトマのみ](https://pokeapi.co/api/v2/berry/26)を例に取得できる値を見てみます。
<font color="red"><b>【注意】理由はわかりませんが、執筆時点では基本的に第4世代までの情報で停止しているようです。</b></font>

## id
PokéAPIにおける識別子
`"id":26`

## name
PokéAPIにおける名称
`"name":"tamato"`

## growth_time
きのみを植えた木が1段階成長するのにかかる時間（単位：時間）
`"growth_time":8`

## max_harvest
第4世代における1本の木から収穫できる最大個数
`"max_harvest":5, `

## natural_gift_power
わざ「しぜんのめぐみ」の威力<font color="red">（注：第5世代までの威力）</font>
`"natural_gift_power":70`

## size
大きさ（単位：mm）
`"size":200`

## smoothness
なめらかさ（ポロックやポフィンに影響する）
`"smoothness":30`

## soil_dryness
きのみを植えた土が乾く速度
`"soil_dryness":8`

## firmness
かたさ
`"firmness":{"name":"soft","url":"https://pokeapi.co/api/v2/berry-firmness/2/"}`

## flavors
きのみの味
`"flavors":[{"flavor":{"name":"spicy","url":"https://pokeapi.co/api/v2/berry-flavor/1/"},"potency":20},...}]`

### potency
味の濃さ 
`"potency":20`

### flavor
味の種類
`"flavor":{"name":"spicy","url":"https://pokeapi.co/api/v2/berry-flavor/1/"}`

## item
道具固有の参照情報
`"item":{"name":"tamato-berry","url":"https://pokeapi.co/api/v2/item/151/"}`

## natural_gift_type
わざ「しぜんのめぐみ」のタイプ
`"natural_gift_type":{"name":"psychic","url":"https://pokeapi.co/api/v2/type/14/"}`

# あとがき
第6世代以降に登場したきのみの情報は提供されていませんが、PokéAPIを使う際の参考になれば幸いです。

PokéAPIのエンドポイントに「きのみのかたさ」「きのみの味」もあるようなので、近いうちにまとめたいと思います。
本当は「ポケモン編」とか書きたいんですが、まとめなきゃいけない情報が多すぎて重たい腰が上がらない状態です。

今後もPokéAPIやポケモンの話やその他技術について書いていきたいと思います。
Emacs で環境変数を引き継ごう

Emacs上のlspで`python-language-server`を使おうとしたら、こんなエラーが‘lsp::pyls‘バッファに出てpylsの起動に失敗してしまいました。

```
Traceback (most recent call last):
  File "/home/pluser/.local/bin/pyls", line 6, in <module>
    from pyls.__main__ import main
ModuleNotFoundError: No module named 'pyls'
```

私の環境では、Pythonのインストールパスを非標準なものへと変更しており、Pythonライブラリの検索パスをPYTHONUSERBASE環境変数でシェルに別途設定しています。
Emacs上のlspクライアントはEmacsの環境変数をそのまま引き継いでクライアントとの通信を行うので、何らかの理由（シェルではなくデスクトップ環境から起動した、など）で普段とは異なる環境変数でEmacsが起動されてしまうと、今回のようなケースではPYTHONUSERBASEなどの環境変数が設定されておらず、LSPの起動や実行に支障をきたしてしまいます。

LSPのプロセスはEmacsの環境変数を引き継ぐので、手っ取り早く対処するには、Emacsを適切な環境変数で起動してあげるとよいです。シェルの環境変数がきちんとしている場合には、デスクトップエントリなどを編集して、 `/bin/bash -c 'emacs'` としてEmacsを起動するようにすると良いでしょう。

または、Emacsがプロセス起動する時の環境変数である`process-environment`変数を調整すると良いでしょう。`(setenv "PYTHONUSERBASE" "/path/to/python")` などとすると任意の環境変数を設定できます。

## 参考文献
- [process - Set environment variables for spawned subprocesses - Emacs Stack Exchange](https://emacs.stackexchange.com/questions/41738/set-environment-variables-for-spawned-subprocesses)
- [[pyls] pyls fails to start with No module named pyls · Issue #13493 · syl20bnr/spacemacs](https://github.com/syl20bnr/spacemacs/issues/13493)
- [環境変数の設定 | Emacs JP](https://emacs-jp.github.io/tips/environment-variable)
Latex description 環境でラベルを「太文字にしない」

### Latex の description 環境について
description環境について[ここ](http://www.yamamo10.jp/yamamoto/comp/latex/make_doc/item/item.php#DESCRIPTION)で説明されています。簡単に言うと、見出し（ラベル）付きで箇条書きの文章が書けるものです。
例：

```latex
\begin{description}
  \item[SDN:]\mbox{}\\
      ・OpenFlow Controller : Ryu（version 4.34）\\
      ・OpenFlow Switch     :	Open vSwitch (version 2.10.1）（以降，OVSと表記する）\\
      ・Southbound API      : OpenFlow Protocol (version 1.3)\\
      ・Northbound API      :  RESTful API
  \item[IDS:]\mbox{}\\
      ・Snort (version 2.9.17)
  \item[syslog:]\mbox{}\\
      ・rsyslog (version 8.1901.0)
  \item[SNMP Trap通知：]\mbox{}\\
      ・SnortSnmpPlugin ( 対応Snort version: 2.9.3.1)
\end{description}
```
その結果がこんなふうになります：
<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521653/c1d32910-6ed2-7c9b-16cf-c60980b55c09.png">


### ラベルの先頭に```\rm```をつける
ラベルの先頭に```\rm```をつけることで「太文字にしない」ことが可能らしいです。

```latex
\begin{description}
  \item[\rm SDN:]\mbox{}\\
      ・OpenFlow Controller : Ryu（version 4.34）\\
      ・OpenFlow Switch     :	Open vSwitch (version 2.10.1）（以降，OVSと表記する）\\
      ・Southbound API      : OpenFlow Protocol (version 1.3)\\
      ・Northbound API      :  RESTful API
  \item[\rm IDS:]\mbox{}\\
      ・Snort (version 2.9.17)
  \item[\rm syslog:]\mbox{}\\
      ・rsyslog (version 8.1901.0)
  \item[\rm SNMP Trap通知：]\mbox{}\\
      ・SnortSnmpPlugin ( 対応Snort version: 2.9.3.1)
\end{description}
```

その結果：
<img width="550" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521653/6ce92cf5-d7c3-ac7c-2cca-e857a6733af9.png">
MatplotlibのFuncAnimationのコールバック関数が初期値で2回実行される

# `matplotlib.animation.FuncAnimation`の不思議な挙動

(コードサンプルは @yubais 様の[こちら](https://qiita.com/yubais/items/c95ba9ff1b23dd33fde2)の記事中にある`funcanimation.py`を参考にしました.)

例えば以下のようなコードを考えます.

```python3:funcanimation.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

def update(i):
    plt.cla()                      # 現在描写されているグラフを消去
    rand = np.random.randn(100)    # 100個の乱数を生成
    plt.plot(rand)                 # グラフを生成
    print(f"i={i}")                # 現在のiの値をターミナルに表示

ani = animation.FuncAnimation(fig, update, interval=100)
plt.show()
```

コードの解説が必要な場合は以下をクリックしてください.

<details>
 <summary>コード解説</summary>
 <div>

  1. 描画領域を生成しfigとする
  1. アニメーションを1フレーム進めるごとに呼ばれ, 実際に描画を行うコールバック関数`update`を定義. `i`は`update`が呼ばれるたびにインクリメントされながら内部で渡されるカウンタ.
  1. アニメーションを生成する対称の描画領域に`fig`, コールバック関数に`update`を設定し, 100msごとにフレームを進めるよう設定してアニメーションをスタート
 </div>
</details>

さて, 上記のコードを実行してターミナルを眺めると

```
i=0
i=0
i=1
i=2
i=3
(以下略)
```

となり, `update`が**i=0で2回呼ばれている**ことが分かります. 今回私はi=0のときだけ処理を分けたいと思っていたためこれが問題となり, 公式ドキュメントを調べてみました.

# 調査結果と解決法

[Matplotlib Documentation 3.3.3](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.animation.FuncAnimation.html)によると, `matplotlib.animation.FuncAnimation`には`init_func`という引数が存在し, これは

> A function used to draw a clear frame. If not given, the results of drawing from the first item in the frames sequence will be used. This function will be called once before the first frame.
> (拙訳) 初期フレームを描くための関数です. もし明示的に与えられない場合, 1枚目のフレームが初期フレームを描くために使われます. この関数は1枚目のフレームが描画される前に1度だけ呼ばれます.

とあります. つまり`init_func`を与えない場合, コールバック関数がi=0のもとで初期フレームを描くために1回, 実際にアニメーションフレームを描き始めたときに1回と計2回呼ばれるため, 初期フレームが2回描画されるのは正常な動作だということです.

したがって, 今回の私のようにコールバック関数をi=0で一度しか呼んでほしくない場合には

```python3:funcanimation.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def init():
    pass  # 何もしない

fig = plt.figure()

def update(i):
    plt.cla()                      # 現在描写されているグラフを消去
    rand = np.random.randn(100)    # 100個の乱数を生成
    plt.plot(rand)                 # グラフを生成
    print(f"i={i}")                # 現在のiの値をターミナルに表示

ani = animation.FuncAnimation(fig, update, init_func=init, interval=100)
plt.show()
```

とすればよさそうです.

一見するとinit()がなぜ定義されているのか分かりにくいような気がしますが, とりあえずこれで解決できたのでよしとします.
依存性逆転をDependency Injectionでやる

# A子さんがBくんに依存している状態

```ts
class B {
    love() {
        return "愛してるよ(2番目になw)"
    }
}


class A {
    b = new B()
    console.log(b.love() + "って言ってくれた！好き！")
}
```

A子さん「Bくんがいないとダメなの...」

# DI(Dependency Injection)することでA子さんを「IBを継承した男なら誰でもいい」状態にする

```ts
interface IB {
    love(): string
}

class HonestB implements IB {
    love(){
        return "愛してるよ(誰よりも)"
    }
}

class A {
    constructor(b: IB){
        this.b = b
    }
    console.log(b.love() + "って言ってくれた！好き！")
}

const b = new HonestB()
const a = new A(b)
```

A子さん「HonestBくんに乗り換える！」

class Aの中でnew B()してたときはBに依存していたが
class AにIBの継承者をコンストラクタインジェクションできるようになった結果
new Aの引数に指定したIBの継承者を誰でも彼氏にできるようになった
A子さん「Bくんの代わりなんていくらでもいるのよ」

Bくんの代わりを用意できるため、Bくんが実装されていなくても代わりにdummyBくんを用意することでA子さんの実装を進められる: `new A(dummyB)`
同じ要領でBくんに依存しない単体テストもかける
Vue+Vuetifyで共通のボタンコンポーネントを作成する

ボタンのデザインを統一したり、連打防止の処理をいれたり、ボタンを押したときの共通の処理のためにボタンをコンポーネントにして使ってみる


```vue:ボタンコンポーネント（例）
<template>
  <v-btn  
    @click="commonClick"
    :color="color"
    :text="text"
  >
    <slot></slot>
  </v-btn>
</template>

<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator';
import {PropType} from "vue";

@Component
export default class ButtonComponent extends Vue{

  @Prop({ type: Function as PropType<() => Promise<unknown>>, required: true })
  onClick!: Function;
  @Prop({ type: String})
  color!: string;
  @Prop({ type: Boolean, default: false })
  text!: boolean;

  public async commonClick() {
    // 共通でしたい処理があれば記載
    await this.onClick();
  }
}
</script>

```

使い方

```vue

<ButtonComponent
  text
  color="success"
  :on-click="clickEvent()">
  ボタン
</ButtonComponent>
```

v-btnに一つコンポーネントかぶせるだけだけど同じ処理何回も書かなくてすみそう、textと同じようにv-btnにあるやつは全部指定できる
https://vuetifyjs.com/ja/api/v-btn/

全然関係ないけどqiitaのコード挿入した時のシンタックスハイライトよくできてるなぁ
MacOS Catalina環境でのPython3インストール・アップデート手順メモ

MacOSのターミナルでpythonコマンドを実行するとデフォルトでインストールされている古いpythonが呼び出される。
最新のPythonを利用したい場合のインストール、アップデート手順を示す。

# パッケージからのインストール
## 手順1 Pythonのインストール
[Python公式](https://www.python.org/downloads/mac-osx/)からインストールするpythonのパッケージをダウンロードし、インストールする。
パッケージからインストールした場合のインストール先パスは`/Library/Frameworks/Python.framework/Version/<バージョン>/bin`となる。

## 手順2 .zshrcの編集
MacOS Catalinaからデフォルトのログインシェルが`bash`から`zsh`に変更されたため、`.zshrc`にpython3のパスを追加する。

```zsh
# vi等のエディタで.zshrcを開き、編集する
$ vi ~/.zshrc
```

```zsh:~/.zshrc
# PYTHON_HOMEにインストールしたpythonのパスを指定する
export PYTHON_HOME="/Library/Frameworks/Python.framework/Version/3.9/bin"
export PATH="$PYTHON_HOME:$PATH"

# pythonコマンドでpython3が起動するにようにaliasを設定
alias python='python3'
alias pip='pip3'
```

`zshrc`設定後、ターミナルを再起動しpythonを起動させた際に、インストールされたバージョンが呼び出されていればOK。

```zsh
$ python
Python 3.9.1 (v3.9.1:1e5d33e9b9, Dec  7  2020,  12:10:52)
[Clang 6.0 (clang-600.0.57)] on drawin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

また、古いPythonをアンインストールする場合は、Macのアプリケーションを開くと、`Python 3.X`というフォルダが存在するため、それをドラッグ&ドロップでゴミ箱に捨てるだけでOK。