OmniAICreator/Qiita-1.07M huggingface dataset:
送信ボタン/登録ボタンを押した後、ローディングアイコンを表示させる(二重送信防止)



## シンプルな方法
(2022/5/11追記しました)

Railsアプリでデフォルトで活用されているrails-ujsの機能を使えば、より簡単に二重送信防止が実現できたので、追記します。
ただし、くるくる回るアイコンや、オリジナルのアイコンを表示させたい場合は、この方法では実現できません。

```ruby
<%= f.submit "送信", data: { disable_with: "送信中..." } %>
```

<img width="100" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/31b7bd70-9d99-4333-05b2-afcd513a8ceb.jpeg">

送信をクリックすると、表示がこのように変わり押せなくなる↓
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/c8eeefce-9bb8-09c9-66e8-431224d2802c.jpeg">

(追記終わり)

## 概要
Railsアプリを例として、ローディングアイコンのgifファイルとJSを使って実装します。
実装するのは、「送信ボタンをクリック後、送信ボタンを非表示にし、代わりにローディングアイコンを表示させる」というシンプルなものです。

## 事前準備
事前準備として、ローディングアイコンのgifファイルを用意し、`loading.gif`という名前でアプリ内に保存し使えるようにしておきます。
「ローディングアイコン　ダウンロード」等でググればフリーのものが見つかるでしょう。

## 実装

このような一般的なフォームがあるとします。

```erb
<%= form_with url: "パス" do |form| %>
  <%= f.button '登録', class: 'btn' %>
<% end %>
```

div要素を以下のように追記します。

```erb
<%= form_with url: "パス" do |form| %>
  <%= f.button '登録', class: 'loading_btn' %>
  <div class="loading">
    <%= image_tag 'loading.gif' %>
  </div>
<% end %>
```

追加したdiv要素はデフォルトでは非表示にしておきます。

```css
.loading {
  display: none;
}
```

下記のようなJSを適用させます。

```js
$(function() {
  $('form').on('submit', function() {
    $('.loading_btn').hide();
    $('.loading').show();
  });
});
```

以上で完了です。
必要なら、CSSで適当にレイアウトを整えてください。

### おまけ：link_toの場合

フォームの中のsubmitボタンではなく、link_toで作ったボタンにもローディングアイコンを表示させたい場合、
以下のようにすることで可能です。

#### パターン1
thisを使っているので、繰り返し処理内でも使いやすい

```erb
<%= link_to "更新", なんたらupdate_path , method: :post, class: 'btn btn-success　loading_btn' %>
<div class="loading">
  <%= image_tag 'loading.gif' %>
</div>

```

```js
$(".loading_btn").click(function(){
  $(this).hide()
  $(this).next("div").show();
  });
```

#### パターン2
htmlにonclick属性を付与している

```erb
<%= link_to "更新", なんたらupdate_path , method: :post, class: 'btn btn-success　loading_btn', onclick: "clickLoadingBtn()" %>
<div class="loading">
  <%= image_tag 'loading.gif' %>
</div>

```

```js
function clickLoadingBtn() {
  $('.loading_btn').hide();
  $('.loading').show();
}
```
python3 配列を数値に変換して計算する (記録）

####2つの整数の組がn個与えられるので、各組の計算結果を足し合わせたものを出力してください。
各組の計算結果は次の値です。
・2つの整数の組を足し合わせたもの
・ただし、2つの整数が同じ値だった場合は、掛け合わせたもの

```
time = int(input())
result = 0

for i in range(time):
    std_in = input()
    array = std_in.split()

    if array[0] == array[1]:
        result += int(array[0]) * int(array[1])
    else:
        result += int(array[0]) + int(array[1])

print(result)
```
入力例1
5
2 1
3 6
4 2
4 4
4 70

出力例1
108
python3 配列条件付き　抽出方法（簡易版）

#### 指定した配列（リスト）を定義し、それらの要素のうち5以上の数をすべて足し合わせた値を出力してください。

```
l = [4, 0, 5, -1, 3, 10, 6, -8]
l_plus = [i for i in l if i >= 5]
        
print(sum(l_plus))
```
<hr>
 
#### 改行区切りで整数がn個入力されるので、n個の整数のうち、5以上のものをすべて足し合わせた値を出力してください。

```
n = int(input())

a = [0]*n

for i in range(n):
    a[i] = int(input())


a_list = [i for i in a if i >= 5]

print(sum(a_list))
```
【python】IBM watson speech-to-text サンプル動かすときのエラー「Handshake status 403 Forbidden」の原因

音声ストリーミング文字起こしアプリのサンプルを動かす中で
躓いたところがあったので共有の意味も込めて投稿します。
<ul>
【環境】
<li>mac big sur 11.2.3
<li>venv python3
</ul>

【参考資料】
youtube: https://www.youtube.com/watch?v=YCyuZM454_I
Github（IBM） : https://github.com/IBM/watson-streaming-stt

<h3>【躓いたこと】</h3>
実行時、

```
Handshake status 403 Forbidden
```

というエラーが発生し、動作しない。

<h3>【原因】</h3>
speech to textセービス作成時のロケーション設定の問題。

<h3>【解決方法】</h3>
サービス作成時に
ロケーションを「東京（ja-tok）」にせず「ワシントンDC（us-east）」にする。

![スクリーンショット 2021-09-07 10.50.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633803/f193add3-aa40-9ad1-67f7-e1311a8dabf1.png)

それに伴い、
speech.cfg では「region」を

```python:speech.cfg
apikey = <your API key>
# Modify region based on where you provisioned your stt instance
region = us-east
```
とする。
<hr>
日本語を認識させるには、
transcribe.py 175行目　のモデルを変更すればOK

```python:transcribe.py
def get_url():
    config = configparser.RawConfigParser()
    config.read('speech.cfg')
    # See
    # https://console.bluemix.net/docs/services/speech-to-text/websockets.html#websockets
    # for details on which endpoints are for each region.
    region = config.get('auth', 'region')
    host = REGION_MAP[region]
    return ("wss://{}/speech-to-text/api/v1/recognize"
           "?model=ja-JP_BroadbandModel").format(host)
```

```python:transcribe.py
           "?model=ja-JP_BroadbandModel").format(host)
```
　　　　　　　　　　　　　　　　　　↑ここ


他言語のモデルは、
https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-models
ここで確認できる。

<hr>
<h2>【サンプルアプリの動かし方（簡易説明）】</h2>
上記参考資料記載のyoutubeまたは、IBMのGithubの通りに進めていけば簡単に動かすことができますが、流れを簡単に記載します。

●IBMアカウントを作成し、
　上記記載のロケーションに注意してサービスを作成する
（https://www.ibm.com/jp-ja/cloud/watson-speech-to-text　）

●git cloneする
（https://github.com/IBM/watson-streaming-stt　）

```
git clone https://github.com/IBM/watson-streaming-stt.git
```

●必要なものをインストールする(pyaudioも必要)

```
pip install -r requirements.txt
```

●プロジェクトをお好きなエディターで開き、
　「speech.cfg.example」 ファイルを編集する

①API key/ region を入力する
　＊上記参照

②ファイル名を変更
「speech.cfg.example」→「speech.cfg」
　
●音声モデルを変更する
＊上記参照

●ターミナルからコマンドを実行

```
python transcribe.py -t 20
```
* 最後の「２０」は、プログラムを実行する秒数

マイクに話しかけてみて、ターミナルに話した文字が現れたらOK！！
<hr>

単純な内容なのに、かなりの時間を使ってしまいました…
自分もこれから、リファレンス読んで色々試していこうと思います。
駆け出しの投稿ですので、お気づきの点ありましたらコメントのほどよろしくお願い致します！
スラブモデルの作り方

# はじめに
結晶表面のシミュレーションを行う際、表面を模したクラスター、あるいは周期スラブ（薄膜）を用いるのが一般的です。特に金属表面を取り扱う際には金属的性質を模しやすいことから周期スラブを用いることが一般的になっています。有料のソフトを探し出すとキリがありませんが（）、ここではスラブモデルの構造と第一原理計算に必要な入力ファイルの作成方法を幾つか簡単に紹介します。

## マニュアル作成

### 古典的な方法（1）
格子定数を決定した後、表面ユニットセルとスラブ厚から原子座標を手で計算します。初歩的な結晶学の知識が必要になりますが、勉強にはなります。Ashcroft & Merminなどを読めば良いでしょう。求めた格子ベクトル（周期系DFTコードの場合）と座標を入力ファイルに自分で書き込みます。単位に注意しましょう。

### 古典的な方法（2）
自分で求めた座標を元にプログラムを書いてプログラムのフォーマットに合わせてスラブの格子ベクトルと座標を生成する。

## プログラムの利用

例えば以下に示すプログラムを利用してスラブの座標を得ることができます。

### VESTA
以下のチュートリアルが参考になります。
* [Creating a surface slab model using VESTA](https://ma.issp.u-tokyo.ac.jp/app-post/1668)
* [Building slab geometries for catalysis with VESTA](http://hjkgrp.mit.edu/content/building-slab-geometries-catalysis-vesta)

### Burai
[Burai](https://nisihara.wixsite.com/burai)はQuantum-ESPRESSOのためのGUIで、無償で利用が可能です。スラブモデルだけではなくスーパーセルの作成機能もあります。

:::note warn
macOS Sonoma（Apple M3）で最新のJavaを利用すると起動すらしませんでした。
:::


### CatKit Slab Generator
[CatKit Slab Generator](https://www.catalysis-hub.org/catKitDemo)
SUNCATで開発されているウェブインターフェース。原子であれば吸着系の構造も作成してくれるようです。

### ASE
[Atomic simulation environment (ASE)](https://wiki.fysik.dtu.dk/ase/)を利用してスラブモデルを作成することが可能です。[Bulding things/Surfaces](https://wiki.fysik.dtu.dk/ase/ase/build/surface.html)や[例](https://wiki.fysik.dtu.dk/ase/gettingstarted/surface.html?highlight=slab)を参考にすると良いでしょう。

MateriAppsページにある[ASEを用いた表面構造の作成](https://ma.issp.u-tokyo.ac.jp/app-post/5843)も参考になります。

### pymatgen
[Materials Project Workshop](https://workshop.materialsproject.org)の[Working with Surfaces and Interfaces](https://workshop.materialsproject.org/lessons/03_heterointerfaces/Main%20Lesson/)が参考になります。

### Winmostar
[Winmostar](https://winmostar.com/en/)はWindows上で動作する有料のソフトウェアです。リーズナブルな価格で高機能です。私はメインでMacを使っているのであまり詳しくはないですが。

### slabgen

私が書いたスラブモデル作成用fortranプログラム。単純な構造の単原子固体の表面に対応。必要に応じて計算できる表面を追加中。プログラムはgitlabより以下のコマンドを実行することによりダウンロード可能です。

```
git clone https://gitlab.com/ikutaro/slabgen.git
```

プログラムをビルドするためにはソースディレクトリに移動

```
cd slabgen/src
```

``makefile``のコンパイラを編集します。以下はgfortranの例です。

```
FC=gfortran
FFLAGS=-O2
LD=gfortran
LDFLAGS=
```
その後``make``を実行します。

```
make
```
slagenコマンド群へのコマンドサーチパスを設定した後に``slabgen/example``以下の``README.md``を読んでプログラムを使ってみましょう。使い方は[リンク](http://www-cp.prec.eng.osaka-u.ac.jp/puki_state/index.php?計算コードの使い方%2FSTATE%2Fslabgen)も参照して下さい。計算可能な表面は``slabgen/README.md``を参照して下さい。
Kotlin で半角カナ判定する

単純だけどすぐに解決できなかったのでメモ。

要はunicodeの値でrange判定かければいい。

こんなかんじ。

```kotlin
// 入力文字
val str = "あいうえおABCｱｲｳｴｵ"

// 半角なら1, 全角なら2でカウントする(スペース埋め処理等）
var count= 0

// 全角半角判定
for (c in str.toCharArray()) {
    count+= when {
        c.toString().toByteArray().size <= 1 -> 1 // 半角文字なら＋１
        c in '\uff61'..'\uff9f' -> 1 // 半角カナ文字なら＋１
        else -> 2 // 全角文字なら＋２
    }
}
```
Swift で Floyd-Warshall Algorithm (ワーシャル・フロイド法）使ってAPSP：All Pair Shortest Path（全点対最短経路問題）



備忘のメモ

## NOTE

-  実装：２次元配列のDP


## コード

```swift
// init
let INF = 1_000_000
var dp = [[Int]](repeating: [Int](repeating: INF, count: N), count: N) // set inf
for i in 0..<N { dp[i][i] = 0 } // zero reset
for (from, to, cost) in list { dp[from][to] = cost } // set initial val

// floyd-warshall
for k in 0..<N {
    for i in 0..<N {
        for j in 0..<N {
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])
        }
    }
}
```
OAuth2.0とは

##OAuth2.0とは
OAuth2.0は身近なアプリ等で多く使用されています。
例えばアプリ内で、インスタグラムに投稿したり、クレジット決済をしたい場合等など、他のサービスの機能を使いたいときが多々あると思います。その際に、ユーザの情報等を安全に扱う仕組みの1つにOAuth2.0があります。他にも様々な仕組みはありますが、OAuth2.0が使用されているサービスは結構多く、QiitaやGitHub、FaceBookやSpotifyなどもOAuth2.0を採用しています。

##例
説明だけだとイメージが湧きにくいので、身近なFacebookログインを備えたアプリを例に挙げてみます。

FaceBookログインがあるアプリ: 「XYZ」
ログインするユーザー: 「ABC」

XYZ : Facebookさん！！ABCさんの情報をアプリで使ってもいいでしょうか！
Facebook : あなたにABCさんの情報を使っていい許可はあるのですか？XYZさんには教えられません。

Facebookからすれば、よくわからない怪しいアプリ「XYZ」にユーザーの情報等を使わせろと言われても、応じないのが普通ですよね。これを安全に裏付けを行なっているのがOAuth2.0の仕組みです。

##仕組み
以上では概要について説明しましたが、OAuth2.0がどのような仕組みで動いているのかを図を交えながら説明していきます！

![14601DC7-CFBB-4D73-A5C7-618275D50F95.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1170864/bd3ab496-3756-9fc1-187b-a5fae04b6509.jpeg)


ユーザー : 
①ログインなどのアクションを行う

アプリ :
②ユーザのアクションを受け取り、Facebook（連携したいサービス）に連携APIを送る。

Facebook:
③アプリさん！あなたに認可コードを渡すから、ユーザーにそれを持って連携代行確認web（窓口的な）に来るように伝えてね！

アプリ:
④もらった認可コード渡すから、窓口行ってきてね！（あ、リダイレクトurlも渡すからアプリを開くときはここから開いてね）

ユーザー(ブラウザ):
⑤Facebookさん、これがもらってきた認可コードです！アクセストークン下さい！

Facebook:
⑥認可コードあってます！アクセストークンあげます

ユーザー(ブラウザ):
⑦リダイレクトURLからアプリを開いてアクセストークンを渡そう！

アプリ:
⑧アクセストークン受け取りました！これで色々操作できるぞ！

##終わりに
QiitaAPIとかGitHubAPIを触ったら結構勉強になりました！ぜひ参考にしてみてください！
-dオプションの意味。Dockerコンテナを立ち上げるときのdetachedモードとは？


# 前提
-dオプションをなんとなくつけていたので、調べました。忘れないように記録しておきます。
まず前提として、Dockerはクライアント/サーバアプリケーションです。クライアント上でコンテナを作成するコマンドが叩かれると、クライアントがサーバにリクエストを行い、コンテナ作成はサーバ上で実行されます。
# -dをつけるとdetachedモードでコンテナを起動
detachedモードだと、バックグラウンドでコンテナを起動します。つまり、クライアントがリクエストをしている間に、クライアントは終了します。detachedモードでコンテナを起動すると、そのまま他のコマンドを実行することが出来ます。つまり、起動した後も普通のターミナルとして使うことが出来ます。

# -dをつけないとforegroundモードでコンテナを起動
逆は、フォアグラウンドでコンテナを起動します。先程と異なり、クライアントは終了しません。foregroundモードで起動すると、実行中のプロセスに対してコマンドをインタラクティブに入力することが出来ます。


間違いがありましたら、コメントでご指摘いただけると有り難いです。 
# 参考
https://stackoverflow.com/questions/34029680/docker-detached-mode#comment110725353_34029977
本番環境にてGmailを送信する【Rails】

#本日の内容
今回の記事のですが、本番環境(EC2)にてGmailを送る実装になります。
`開発環境でも参考になると思います！(記述する場所を変えるぐらいなので)`

#環境・前提
ruby 2.6.5
本番環境EC2

#◇Gmailメール実装
こちらでは、本番環境にてgmailからユーザーにメールを送っていきます。

###流れ
①Gmailアカウント／アプリパスワード取得
②コードに記述

###Gmailアカウント／アプリパスワード取得
gmailのアカウントのアプリパスワードが必要です。(通常のログインパスワードだとエラーが出ます)
今回は、gmailアカウントの２段階認証をオンにして、アプリパスワードを取得ます。

**① 送信用に利用するgmailのアカウントで [ログイン](https://myaccount.google.com/?utm_source=OGB&tab=mk&utm_medium=act&gar=1)**
**② [セキュリティ]設定**
　画面左のメニューから[セキュリティ]を選択し、セキュリティの設定画面を開きます。
![gmail1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1822683/07d585a4-1521-3e0e-7a04-dbd4d4921236.png)
**③ 2段階認証を有効化**
　[Googleへのログイン]にある[２段階認証プロセス]を選択し、画面に沿って設定を完了させてください。
　※既に有効な場合は、手順をスキップしてください
![agmail2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1822683/689b774f-7b85-c54a-646b-f47672f49161.png)
**④　アプリで利用するためのパスワードを取得します。**
　[Googleへのログイン]にある[アプリパスワード]を選択し、パスワードを発行してください。
![agmail3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1822683/f73fea2f-61eb-c1d1-2808-43cb2dc4a293.png)
`※上記の後に出てくる、アプリパスワードを生成するアプリとデバイスを選択してください、のアプリ選択は「その他」で大丈夫です。`

**⑤　パスワード取得完了**
　発行完了すると、１６桁の番号が払い出されます。
　この番号をこの後コードに記述します。
![agmail4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1822683/3d50e663-d8e6-2ac5-c1da-5ac7bd0a16ab.png)


###コードに記述
`config/environments/product.rb`に下記の記述を行えば完了です！
開発環境の場合は、`config/environments/development.rb`に記述すればOKです

```ruby:config/environments/product.rb
  config.action_mailer.default_url_options = { host: "Elastic IP アドレス" } #ECの本番アドレス
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => 'smtp.gmail.com',
    :port => '587',
    :domain => 'smtp.gmail.com',
    :authentication => 'plain',
    :user_name => '自身のGmail',
    :password => 'アプリパスワード'#先程発行した16桁のパスワードを記述
  }
```

以上になります。
数理計画（定式化③）

制約条件の定式化で参考になった手法を記載します。

#2値
説明変数に２値（０：なし、１：あり）を使用ケースがありますが、その際に使用するテクニック

##選択
```
説明変数
　 x[j] (j：1～n)
　 x[j] ∈{0,1}

どちらか一方だけ必ず
   x[j1] + x[j2]  = 1

少なくとも一方
   x[j1] + x[j2]  ≧ 1

一方を優先
   x[j1] ≧ x[j2]

応用が利きそうです。
```
##条件分岐
```
説明変数
　 y[j] (j：1～n)
　 0≦y[j]≦R
　 x[j] (j：1～n)
　 x[j] ∈{0,1}

   if y[j] == 0
     価値 = 0
   else
     価値 = 100

   x[j] = 0 →　価値なし
   x[j] = 1 →　価値あり

   価値 = 100 ×　x[j]
   y[j] ≦ R × x[j]　　　：価値がない場合、y[j] = 0
　 0≦y[j]≦R
```
##制約条件の緩和
```
説明変数
　 y[j] (j：1～n)
　 0≦y[j]≦R

　 A[j] ×　y[j]　≦　C[j]
　 B[j] ×　y[j]　≦　C[j]

上記の制約条件があり片方だけ満足すればいい場合
　 x[A]　Aの制約が有効・無効
　 X[B]　Bの制約が有効・無効
　 x[A][B] ∈{0,1}　　0：無効　1：有効
   
   X[A] + X[B] = 1
　 A[j] ×　y[j]　≦　C[j] × Big-M(1 - x[A]) 
　 B[j] ×　y[j]　≦　C[j] × Big-M(1 - x[B]) 
   
Big-M 制約にならない大きな数字
```
[Xcode]古いXcodeで最新iOSの端末にアプリをインストール

#解決したい事：
最新iOS端末を持っていますが、xcodeは古いバージョンで開発し続けて、開発中のアプリをインストールできない。
XcodeのバージョンをあげようとしてもまたMacのOSバージョンも上げなければならない。

#その時の対策：
#### 1) 以下のリンクにて、最新版のiOSに該当するZipファイルをダウンロードする

https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport

#### 2) Xcodeの下記デイレクトり下に、上記リンクから落としたzipファイルを解凍しておく

> Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

#### 3) 最新版の実機で古いxcodeを開いてアプリをビルド・インストールしてみると、無事にインストールできた！
【CSS】フレックスボックス (flexbox) の使い方

# はじめに
フレックスボックスの学習備忘録です。

## 学習方法
[FLEXBOX FROGGY](https://flexboxfroggy.com/#ja)は、ゲーム形式にフレックスボックスを楽しく学べます。
FLEXBOX FROGGYを最後まで行うと下記のスタイルがわかるようになります。

```css:Q24
#pond {
  display: flex;
  flex-direction: column-reverse;
  flex-wrap: wrap-reverse;
  justify-content: center;
  align-content: space-between;
}
```

https://flexboxfroggy.com/#ja

## フレックスボックスのまとめ

### ```justify-content```: 横方向に移動する

    * flex-start: アイテムはコンテナーの左側に並びます
    * flex-end: アイテムはコンテナーの右側に並びます
    * center: アイテムはコンテナーの中央に並びます
    * space-between: アイテムはその間に等しい間隔を空けて表示されます
    * space-around: アイテムはその周囲に等しい間隔を空けて表示されます
    * space-around: 周辺に等しいスペースを空ける
    * space-between: 間に対して均等にスペースを空ける
     
```css:justify-contentの例
#pond {
  display: flex;
  justify-content: flex-end;
}
```

### ```align-items``` : 縦方向に移動する
    * flex-start: アイテムはコンテナーの上部に並びます。
    * flex-end: アイテムはコンテナーの下部に並びます。
    * center: アイテムはコンテナーの垂直方向中央に並びます。
    * baseline: アイテムはコンテナーのベースラインに表示されます。
    * stretch: アイテムはコンテナーの大きさに合うよう広がります。

```css:align-itemsの例
#pond {
  display: flex;
  justify-content: center;
  align-items:center;
}
```

###```flex-direction``` : 軸の方向を変える

* row: アイテムは文章と同じ方向に配置されます。
* row-reverse: アイテムは文章と逆の方向に配置されます。
* column: アイテムは上から下に向かって配置されます。
* column-reverse: アイテムは下から上に向かって配置されます。


###```order``` : アイテムの順序を指定する
* アイテムはデフォルトでは0の値を取ります。
* １以上は右へ移動します。
* 左に置きたい場合は-1以下を指定します。

```css:orderの例
#pond {
  display: flex;
}

.yellow {
order: 1
}
```

###```align-self``` :　個別のアイテムへ設定できるプロパティー 

```css:align-selfの例
#pond {
  display: flex;
  align-items: flex-start;
}

.yellow {
align-self:flex-end
}
```


### ```flex-wrap```: アイテムを強制的に１行にまとめるか、改行させるか制御する

* nowrap: 全てのアイテムは、ひとつの行にフィットします。
* wrap: アイテムは他の行へ折り返します。
* wrap-reverse: アイテムは逆順になって他の行へ折り返します

```css:flex-wrapの例
#pond {
  display: flex;
  flex-wrap: wrap;
}
```

* flex-directionとflex-wrapの二つのプロパティーはよく一緒に使われるため、これらを統合するショートハンドプロパティーflex-flowが作られました。
* このショートハンドプロパティーは空白文字で分割した二つのプロパティーの値を受け付けます。

```css:flex-directionとflex-wrapを２つを省略できるよ
#pond {
  display: flex;
  flex-flow: column wrap
}
```

###```align-content```: 複数の行が他の行とどう距離を取り広がるのかを指定する

* flex-start: 行はコンテナーの上側に詰められます。
* flex-end: 行はコンテナーの下側に詰められます。
* center: 行はコンテナーの中央に詰められます。
* space-between: 行はその間に等しい間隔を空けて表示されます。
* space-around: 行はその周囲に等しい間隔を空けて表示されます。
* stretch: 行はコンテナーに合うよう引き延ばされます。

```css:align-contentの例
#pond {
  display: flex;
  flex-wrap: wrap;
  align-content:flex-start;
}
```
【GCP】GoogleMapsPlatformのDynamic Mapsってなんや？ってなったので整理する

こちらの動画だとわかりやすいかと思いました。
GoogleのGoogleMapsPlatformチームが公開している、GoogleMapsPlatformの概要の公式動画です。
1:53-4:45あたりがDynamic Maps に関する部分になってます。
https://www.youtube.com/watch?v=kA679ERgBV4&t=68s

こちらの動画な感じで操作すると、「インタラクティブでカスタマイズ可能な地図」を表示できます。

※補足１
GoogleMapsPlatformは地図でいろんなことができますというサービスですが、
GoogleMapsPlatformの大きな機能として3つのMAP、Place、Routeというものに分けています。
Dynamic MapsはMAPの中に入ってます。
↓
こちらのサイトで「MAP」→「Dynamic Maps」という感じで分類されてます。
https://www.zenrin-datacom.net/business/gmapsapi/function/

こんな感じ
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/0f2c10a8-b052-df37-3d97-34150fa0c71e.png)
※汚くてすみません。。。

さらに、「Dynamic Maps」の中で複数のAPIが分類されていますが、
このAPI群のいくつかを使うと「動的に地図を表示、カスタマイズする」ことができますよとなります。
なので、冒頭の動画に合った感じで、いろいろ地図の表示を変えられますとなって、
以下のサイトにあるような「独自のコンテンツや画像を使ってマップをカスタマイズできる」ことになります。
https://www.zenrin-datacom.net/business/gmapsapi/function/

※補足２
Dynamic MapsはＳＫＵ単位です。
https://developers.google.com/maps/billing/gmp-billing?hl=en
https://www.zenrin-datacom.net/business/gmapsapi/function/
https://oxynotes.com/?p=12048
AWS EC2にSSL/TLSを追加する(https化)

AWS EC2インスタンスWEBサーバーを[ムームードメイン](https://muumuu-domain.com/)などで取得した独自ドメインでHTTPS化を有効にする手順について


##ムームードメインの操作
取得したいドメインを検索＞カートに追加
###ドメイン設定
WHOIS公開情報：チェック
ネームサーバー(DNS)：ムームーDNS
ドメインの利用方法：選択しない
ムームーメール：チェックしない


##ACMの操作
*AWS Certificate Managerのコンソール画面＞証明書のリクエスト
*パブリック証明書のリクエストを選択して、証明書のリクエストをクリック
*取得したドメインを入力し、次へ
*DNSの検証を選択して、次へ
*任意のタグをして、確認
*確定とリクエスト
*検証状態のステータスが「検証保留中」になっていることを確認する
*ドメイン名左の▼をクリックして、CNAMEレコードの名前欄と値欄を控える

##ムームードメインの操作
*カスタムドメインの操作
*コントロールパネルからムームーDNSをクリック
*取得したドメインの　利用する　をクリック
*DNS設定をする
*カスタム設定　をクリック
*設定２にCNAMEを追加する
※1「控えたCNAME名前欄の".ドメイン名."より前」をサブドメインに入力する
※2「控えたCNAME値欄」を内容に入力する


##AWS Load Balancerを作成
EC2のコンソール＞ロードバランサー＞ロードバランサーの作成＞Application Load Balancerの作成　をクリック
###ロードバランサーの設定
名前：任意の名前
スキーム：インターネット向け
リスナーのロードバランサーのプロトコル：HTTPS
AZ：対象のインスタンスが配置されているAZVPCとAZを選択

###セキュリティ設定の構成
証明書タイプ：ACMから証明書を選択する
証明書の名前：今回作成した証明書
セキュリティポリシー：任意のポリシーを選択

###セキュリティグループの設定
セキュリティグループ名：任意の名前
タイプ：HTTPS
ソース:0.0.0.0/0

###ルーティングの設定
ターゲットグループの名前：任意の名前
ヘルスチェックの名前：/index.html（や/index.php）

###ターゲットの登録
対象のインスタンスを追加


##対象インスタンスのセキュリティグループを編集
対象のインスタンス＞セキュリティタブ＞セキュリティグループ＞インバウンドルールの編集
タイプ：HTTP
ソース:今回作成したロードバランサーのセキュリティグループ


##参考
*[チュートリアル: Amazon Linux 2 に SSL/TLS を設定する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html)
【Laravel】Xdebugを導入する（mac × MAMP）

##VSCodeの拡張機能のインストール
PHP Debugをインストールする。
（VSCoedeの拡張機能のところで、felixfbecker.php-debugと検索）

##Xdebugのインストールと設定
macのMAMPにはXebugがデフォルトでインストールされれている。

###Xdebugがインストールされているか確認する方法
適当なファイル（例：phpinfo.php）を作成し、以下のように記述する。

```phpinfo.php
<?php
phpinfo();
?>
```
このページをブラウザで開き、Xdebugの記述があればインストールされている。
Xdebugについての記述が無い場合は、インストールを行う。

###Xdebugのインストール方法（Xdebug3の場合）
1. Xdebug Wizardを開く。
https://xdebug.org/wizard

2. 先ほどのブラウザに表示されたphpinfoを全てコピーし、Xdebug Wizardのテキスト欄に貼り付ける。

3. 「Analyse my phpinfo() output」をクリック。

4. InstructionsのところにダウンロードするべきXdebugが表示されるので、リンクをクリックしてダウンロードする。

5. Instructionの「2. Move the downloaded file to ~~~~」のパスをコピーし、エクスプローラーを開いて貼り付け、このパスまで移動する。ここに、4.でダウンロードしたファイルをドラッグ&ドロップする。

6. Instructionの「3. Edit ~~~~」のパスを辿り、php.iniを開く。「add the line」以下の「zend_extension = 」をphp.iniの一番下に追記する。(xdebug.mode=debugにしておく)

7. サーバーを再起動し、phpinfoを開いてXdebugの記述があるか確認する。


###インストール済みの場合の設定方法
1. phpinfoの「Configuration File （php.ini） Pathのconfの前までをコピー。Finderでこのパスまで移動する。/lib/php/extensions/no-debug~~/xdebug.so この「xdebug.so」が対象のファイルなので、このファイルまでのフルパスをコピーする。

2. phpinfoの「Configuration File （php.ini） Pathのconf/php.iniに、[Xdebug]の設定を追記する。

```
//Xdebug ver3の場合

[XDebug]
xdebug.mode=debug,develop,trace
xdebug.start_with_request = yes
zend_extension = C:\MAMP\bin\php\php7.4.1\ext\php_xdebug-3.0.0-7.4-vc15.dll

※zend_extensionはXdebug Wizardでコピーした値


//Xdebug ver2、またはMacの場合

[XDebug]
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_port = 9010　　　　
zend_extension = C:\MAMP\bin\php\php7.4.1\ext\php_xdebug-2.0.0-7.4-vc15.dll

※Windowsの場合:zend_extensionはXdebug Wizardでコピーした値
※Macの場合:xdebug.soまでのパス
```

3.サーバーを再起動して、設定を反映させる。

##VSCodeの設定
1. デバッグの設定（サイドバーの虫のアイコン）より、「launch.json ファイルを作成します。」をクリック。「PHP」を選択する。

2. .vscode/launch.jsonが作成されるので、以下の通り編集する。これより下は不要なので削除する。

```.vscode/launch.json.php
{
  // IntelliSense を使用して利用可能な属性を学べます。
  // 既存の属性の説明をホバーして表示します。
  // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9010,
　　　　　　　　　　　　　　　　　　　　//php.iniのポートと同じに。
      "stopOnEntry": true
    },
  ]
}
```
###PHPのワーニングを画面表示する
※ワーニングエラーも、開発環境では確認できる方がよいので。

1. php.iniを開き、「display_errors」と検索する。
2. 「display_errors = On」に変更する。
3. サーバーを再起動して、設定を反映させる。
MATLABでDJIのtelloを動かそう。1

#初めに
matlabでtelloというドローンを動かそうとおもいます。
大学で情報系を専攻している人はmatlabを使用していると思います。
**MATLAB**
https://jp.mathworks.com/products/matlab.html
**tello**
![71-npJDLgmL._SL1500_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493403/47fd8d03-653a-1cac-5a23-2597370532e5.jpeg)

#MATLABでどう動かすか
まずはMATLABにあるパッケージを自分のMATLABにダウンロードします。
**Ryze Tello Drone Support from MATLAB**
https://jp.mathworks.com/matlabcentral/fileexchange/74434?download=true
このパッケージを自分のパソコンにダウンロードした後に実行しmatlabで動かします。
そして、自分のパソコンとtelloを接続します。telloに電源を入れ、telloから出るwifiを経由してtelloを動かします。
![connect_to_tello_wifi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493403/ecd99996-05a3-e7f9-7d41-57b883584f82.png)
そしたらコマンドを打ち込んでtelloを動かしていきます。

#コマンドの例
まずはtelloのオブジェクトを作っていきます。
```r = ryze();```
**離陸**
```takeoff(r);```
**着陸**
```land(r)```
**移動**
```move(r,[カメラがついている方向　右方向　重力の方向])```
![ryze_drone_with_axes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1493403/440ce66c-dcd8-79f9-8ace-c4b6c96d90c0.jpeg)

最後にオブジェクトのｒを消しましょう。
clear r;
このコマンドをmatlabのエディターに書きtelloにwifiを経由してつなぎ実行ボタンを押すとドローンが動きます。
#次に記事でより高度に飛ばすためのコマンドを書いていきます。
[MATLABでDJIのtelloを動かそう。2](https://qiita.com/RyeWiskey/items/6a566776e44015a01a51)

#写真の引用
>https://viva-drone.com/tello-toydrone-rize-dji/
>https://jp.mathworks.com/help/supportpkg/ryzeio/ug/connect-to-ryze-drone-over-wifi.html
>https://jp.mathworks.com/help/supportpkg/ryzeio/ref/move.html
間違いがありましたら指摘ください。
python3 mapとlambdaとは？

# mapとlambda
mapとはイテレータの要素を加工するためのもの

```
def triple(n):
  return n * 3

print(list(map(triple,[1, 2, 3])))

a = [10, 20, 30]
```
mapでリスト（イテレータ）を呼ぶとジェネレータになる。そのため結果をリストに変換する必要がある。

```
print(list(map(triple,a)))
```
###lambdaは上記の計算（triple）関数を書かなくても一行で実行できるものをいう。

```
print(list(map(lambda n: n*3, a)))
```
shellスクリプトで複数のpdfの最初のページにハンコを押す

# shellスクリプトで複数のpdfの最初のページにハンコを押す

## 概要
複数のPDFの最初のページにハンコを押して行き最後に一つのファイルにまとめる。

## 前提条件
- MAC
- homebrew が入っている

## 事前準備

ghostscript(PDF対応のため)とimagemagick(画像操作アプリ)をインストールしておく。

```sh
brew install ghostscript
brew install imagemagick
```


## フォルダ構造

```

./
./hanko.png < ハンコpngファイル
./pdfin/  < PDFたちを置く場所
./pdfout/pdfin/ < 出来上がったpdfが入る場所
./pdfout/omatome.pdf　< おまとめPDF
./work/ < 作業スペース

```
## 使い方
- ダウンロードした請求書PDF（結合前）たちを入手する
- どこかに作業フォルダを作ってそこに cd する
- 「pdfin」ディレクトリを作る
- hanko.pngを「./」におく
- ./pdfin に請求書PDFたちを置く
- 下にあるShellScriptをコピペする。（+enter)
- ./pdfout/pdfin/ にハンコが押されたファイルができる
- いつものように結合する


## カスタマイズ
- +400+750　の部分を変えれば画像が重なる場所が変わる
- hanko.pngを変えれば画像が変わる

## ShellScript
コピペする

```sh
echo
echo "PDFにハンコを押します"
mkdir ./work

rm -rf ./pdfout/pdfin
mkdir ./pdfout/pdfin
for FILE in ./pdfin/* ; do
echo "$FILE の処理をしています"
rm -rf ./work
mkdir ./work

convert -define png:color-type=6 -density 300 "${FILE}" ./work/page.png
FIRSTFILE=$(ls ./work/page*.png|head -n1)
composite -density 300 -gravity northwest -geometry +400+750 -compose over ./hanko.png "$FIRSTFILE" "$FIRSTFILE"

convert -define png:color-type=6 ./work/page*.png ./pdfout/"${FILE}"
done
echo "PDFを一つにまとめています"
convert -density 300 ./pdfout/pdfin/* ./pdfout/omatome.pdf
echo "./pdfout/omatome.pdf"
```
Openshift環境でCLI、Git リポジトリーを使用して、アプリを作成する(Git からS2I へのBuild & Deploy方法)



##参考：CLI を使用したアプリケーションの作成
https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.4/html/applications/creating-applications-using-cli

##注意localじゃなくてgitからS2I Build & Deploy
localでうまく起動できるかはまず確認しないと！！！


##セットアップ

IBM CloudとIKSクラスタの操作に必要なCLIツールのセットアップ

```
$ curl -sL https://ibm.biz/idt-installer | bash 
```
oc cliのinstall

```
$ brew install openshift-cli
```

projectを作成

```
$ oc new-project test
```

secretの作成

```
$ oc create secret generic github-token --from-literal=username=<githubのユーザーネーム> --from-literal=password=<githubのパスワード> --type=kubernetes.io/basic-auth
secret/github-token created
```

作成したsecretの確認

```
$ oc get secret
```

(optional)secretを削除したい場合

```
$ oc delete secret
```


ビルドイメージのプッシュおよびプルにシークレットを使用するには、シークレットは Pod 内でマウント可能である必要があります

```
$ oc secrets link builder github-token
```


プライベートリモートリポジトリー内のソースコードに基づいて新規アプリケーションを作成
3分ぐらいかかった

```
$ oc new-app <https://github.ibm.com/XXXXXX/XXXX.git> -e PORT=8080 --source-secret github-token
...
Run 'oc status' to view your app.

```

デプロイ進捗を確認

```
$ oc get bc
NAME          TYPE     FROM   LATEST
api-gateway   Source   Git    1


$ oc project
Using project "wu" on server "https://c100-e.jp-tok.containers.cloud.ibm.com:31036".


$ oc status


$ oc get pods
NAME                           READY   STATUS             RESTARTS   AGE
api-gateway-1-build            0/1     Completed          0          7m1s
api-gateway-222222-5555   0/1     CrashLoopBackOff   5          5m30s


$ oc logs -f api-gateway-222222-5555


$ oc logs -f api-gateway-1-build  
Caching blobs under "/var/cache/blobs".
Getting image source signatures
...
Writing manifest to image destination
Storing signatures
Generating dockerfile with builder image image-registry.openshift-image-registry.svc:5000/openshift 
...
STEP 3: ENV OPENSHIFT_BUILD_NAME="api-gateway-1"   
STEP 4: USER root
STEP 5: COPY upload/src /tmp/src
STEP 6: RUN chown -R 1001:0 /tmp/src
STEP 7: USER 1001
STEP 8: RUN /usr/libexec/s2i/assemble
---> Installing application source ...
---> Installing all dependencies
audited 904 packages in 6.81s
...
Push successful
```

無事にデプロイ後、外部公開(同サービスに外部からアクセスさせたい場合を想定します。)

```
$ oc status


$ oc get route
No resources found in XX namespace.
->routeがない状態


$ oc get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
api-gateway   ClusterIP   111.11.1.111   <none>        8080/TCP   6m59s


#ルートとして公開する
$ oc expose service api-gateway
route.route.openshift.io/api-gateway exposed


#routeが新規生成される
$ oc get route
 NAME          HOST/PORT                                                                                                        PATH   SERVICES      PORT       TERMINATION   WILDCARD
api-gateway    XXXXXX         api-gateway   8080-tcp                 None



$ oc start build XXXXX

```
python3 イテレータとジェネレータとは？

###イテレータとは、
連続するデータを操作するオブジェクト（リスト・集合・タプル）

```
scores = [10, 20, 30, 40]
it = iter(scores)
print(next(it))
print(next(it))
print(next(it))
print("hello")
print(next(it))
```
上と同じ意味

```
for score in scores:
  print(score)
```
##ジェネレータ
リストから変換するのではなくて 0 からイテレータを作ることもできます。0から連続するデータを操作するオブジェクト作ることをジェネレータという。
無限ループを while True:
次の要素を引っ張ってくる yield i * 2 という命令 ジェネレータの重要なポイント
yieldをnextと連動させて取ってくることができる。
イテレータを作るこうした関数をジェネレータと呼ぶ

```
def get_infinite():
  i = 0
  while True:
    yield i * 2
    i += 1

g = get_infinite()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
for x in g:
  print(x)


def point():
  i = 0
  while i < 10:
    yield i +2
    i += 2

no1 = point()
print(next(no1))
print(next(no1))
print(next(no1))
print(next(no1))

for g in no1:
  print(g)
```
M5Stack Core2: base64 エンコード

```text:base64_test/base64_test.ino
// ---------------------------------------------------------------
/*
	base64_test.ino

						Sep/07/2021

	for M5Stack Core2
*/
// ---------------------------------------------------------------
#include <M5Core2.h>
#include <base64.h>

// ---------------------------------------------------------------
void setup()
{
	M5.begin();
	M5.Lcd.setBrightness(32);
	delay(1000);

	M5.Lcd.println("*** start ***");
	Serial.println("*** start ***");
	Serial.println("*** Base64 example ***");
	
	char Buf[50];

	String str_array[] = {"A","AB","ABC","ABCD","ABCDE","ABCDEF","ABCDEFG",
		"ABCDEFGH"};

	int llx = 8;
	Serial.println ("llx = " + String(llx));
	delay(1000);

	 for (int itt=0; itt < llx; itt++)
		{
		str_array[itt].toCharArray(Buf, 50);	
		String str_encoded = encode_proc(Buf);
		Serial.println(str_encoded);

		delay(500);
		}

	delay(500);
	Serial.println("*** setup *** end ***");
}

// ---------------------------------------------------------------

String encode_proc(char* input)
{
	int inputLen = strlen(input);
	Serial.print("inputLen = " + String(inputLen) +"\t");
	Serial.println(input);

	String encoded = base64::encode(input);

	return encoded;
}

// ---------------------------------------------------------------
void loop()
{
	Serial.println("*** loop ***");
	delay (2000); 
}

// ---------------------------------------------------------------
```

実行結果

```text
$ cu -s 115200 -l /dev/ttyACM0
Connected.
*** start ***
*** Base64 example ***
llx = 8
inputLen = 1	A
QQ==
inputLen = 2	AB
QUI=
inputLen = 3	ABC
QUJD
inputLen = 4	ABCD
QUJDRA==
inputLen = 5	ABCDE
QUJDREU=
inputLen = 6	ABCDEF
QUJDREVG
inputLen = 7	ABCDEFG
QUJDREVGRw==
inputLen = 8	ABCDEFGH
QUJDREVGR0g=
*** setup *** end ***
*** loop ***
```
【Python3】Python3エンジニア認定データ分析試験受験記

昨日、一般社団法人Pythonエンジニア育成推進協会が提供しているPython3エンジニア認定データ分析試験を受験した。

https://www.pythonic-exam.com/exam/analyist

結果は、1000点満点中900点(合格最低点:700点)で合格した。

#0.筆者のスペック
Python経験は1年半ほど
2020年7月 Python3エンジニア認定基礎試験合格
機械学習はほぼ初

#1.勉強に使用した教材と費用
A.『Pythonによるあたらしいデータ分析の教科書』(以後公式教材と呼ぶ)

https://www.amazon.co.jp/dp/4798158348/

B.模試(DIVE INTO CODE)

https://diver.diveintocode.jp/dive_into_exam/2

C.難しい模試(プライムストラテジー)

https://study.prime-strategy.co.jp/

費用
受験費:11000円(学割が効くと5500円)
公式教材:Amazonで2728円※
※以下サイトの通りに受験宣言をするとキャンペーンで無料でテキストをもらえるそうです。(2021年11月まで)

https://www.pythonic-exam.com/archives/news/555camp 



#2.勉強した期間
 試験受験すると決めた1か月前から公式教材を電車の中で読み、わからない単語や用法を調べOneNoteに記した。
試験2週間前に教材を読み終えたので、プライムストラテジーよりも簡単と言われていたDIVE INTO CODEから提供されている模試を解き始めた。
最初は47.5%とかなり低かったが、わからない単語や用法を調べ公式教材のコードを実行しつつ、複数回受験していくうちに合格点を安定して取れるようになった。
 試験一週間前からは、プライムストラテジーの方の模試を受験した。
DIVE INTO CODEの模試で合格点を取れていたので、合格点行くだろうと甘く考えていたが、結果は52.5点/100点となった。
この模試でもDIVE INTO CODEの時と同様に、複数回受験していくうちに、合格点を安定して取れるようになった。


#3.受けてみて
機械学習の分野が苦手だったため、機械学習の分野(特に、教師あり学習と教師なし学習の違い等)を理解するのに苦労した。


#4.感想
公式教材がすごくわかりにくかった。
難易度は模試レベルだった。
Couchbase Server Java SDKによるアプリケーション開発へのロードマップ

##  はじめに

Couchbase　Server Java SDKによるアプリケーション開発に関する記事を、カテゴリー別に整理しています。

## 機能解説

### 分散トランザクション

[Couchbase Server Java SDK解説：分散トランザクションプログラミング入門](https://qiita.com/yoshiyuki_kono/items/4efb2f1f5a03051e28c5)

[Couchbase Server Java SDK解説：分散トランザクション〜キーバリュー操作API（解説と利用例）](https://qiita.com/yoshiyuki_kono/items/26b1045b7a756ef8e9e8)

[Couchbase Server Java SDK解説：分散トランザクション〜N1QLクエリ](https://qiita.com/yoshiyuki_kono/items/86b30b1e13b050045df9)

[Couchbase Server Java SDK解説：分散トランザクションの内部メカニズム](https://qiita.com/yoshiyuki_kono/items/2d428b16b224b8c01239)

[Couchbase Server Java SDK解説：分散トランザクションの内部メカニズム〜クリーンアップ詳細（設定と監視）](https://qiita.com/yoshiyuki_kono/items/cc6788a2d31b0a0e9141)

[Couchbase Server Java SDK解説：分散トランザクション〜エラー処理を理解する](https://qiita.com/yoshiyuki_kono/items/d7eb2b9553d858c7cb93)

[Couchbase Server Java SDK解説：分散トランザクション〜トランザクションライフサイクル](https://qiita.com/yoshiyuki_kono/items/ff1f532094024cc4549a)

[Couchbase Server Java SDK解説：分散トランザクション〜ログとトレース](https://qiita.com/yoshiyuki_kono/items/5e8363557b6f5a0dc576)

[Couchbase Server N1QL解説：ロールバック](https://qiita.com/yoshiyuki_kono/items/59709e035462737954cd)

### セキュリティ

[Couchbase Server Java SDK解説: フィールドレベルの暗号化](https://qiita.com/yoshiyuki_kono/items/0e811d29bd69818c283f)

### 非同期プログラミング

[Couchbase ServerリアクティブAPI解説(JAVA)](https://qiita.com/yoshiyuki_kono/items/2663ef8c23fb54d3a74c)

## チュートリアル

[Spring Boot + Spring Data: JSONデータベースCouchbaseを使ってJavaオブジェクトをそのまま保存する](https://qiita.com/yoshiyuki_kono/items/da214312b3ace0de24b1)

[リアクティブプログラミングをNoSQLで「体験」してみる（Couchbase Reactive APIに触れる)](https://qiita.com/yoshiyuki_kono/items/7c191ca0e2d15bc7eaf6)

## アドバンスド機能解説

[CouchbaseにおけるHA/DR対応 (Java SDK注解)](https://qiita.com/yoshiyuki_kono/items/489b494e046bc4d93d32)

## Swagger連携

https://qiita.com/yoshiyuki_kono/items/5cd50ef832ae5cf22773

## 関連情報

https://docs.couchbase.com/java-sdk/current/hello-world/overview.html
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type...が出た時に解決した方法

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type { ... } ... が出てちょっとハマったので共有します

## 環境
mac 11.5.2(Big Sur)

vue 2.6.14
typescript 4.3.2
eslint 6.8.0
@vue/eslint-config-typescript 7.0.0


## 問題
自前で作ったCMSの編集処理でpostするデータが入った連想配列をFormDataに詰め直す際に`Object.keys()`で連想配列をループしながらvalueを取り出したかったが、当該エラー発生

```typescript:Typescript
interface Article {
  id: number | null;
  title: string;
  description: string;
  eyecatch: string;
  headline: string;
  paragraph: string;
  links: number[];
}

const postData = reactive<Article>({
  id: null,
  title: "",
  description: "",
  eyecatch: "",
  headline: "",
  paragraph: "",
  links: [],
});

const formData = new FormData();
Object.keys(postData).forEach((key) => {
  formData.append(key, postData[key]);  // postData[key]でTS7053エラー発生
});
```

## 原因
上記`postData[key]`が暗黙的にanyを含んでいるとのこと。ん〜どゆこと？Articleにnullとか配列が入ってるから？？上記コードの場合`postData['title']`などArticleのkeyになっている文字列を直接指定すればエラーは起きない。ということはkeyが指定した文字列でないからか。。ちょっとナニイッテルカワカラナイヨ。Object.keysで回すときってkeyは指定された文字列ちゃうの？？

## 解決
`key as keyof Article`でエラーがなくなりました。他の方の記事を参考にさせていただきました。

```typescript
Object.keys(postData).forEach((key) => {
  formData.append(key, postData[key as keyof Article]);
});
```

## まとめ

ちょっと腑に落ちないエラーはルールから除外してもいいんだけど、それだとtypescript使ってる旨味がないからちゃんと解決していかなきゃいけないけど、このパターンはtypescript側で吸収できるんじゃね？と思ったり思わなかったり。


## 参考にしたページ
助かりました。ありがとうございます。

https://qiita.com/Nossa/items/e01d0bce67b760c0bcb9

https://qiita.com/tktcorporation/items/051bb03bb4d72930d8e9
【ES6】変数宣言const・let・var のまとめ

# これは何？
ES6記法で書く機会が増え、`const`, `let`, `var`の使い分けがよくわかっていないため、どのようなな違いがあるかまとめてみました

# 結論
基本的には`const`を使う。
forループの処理などのように再代入が必要なケースのみ`let`を使用する。
`var`は、挙動が把握しづらく、バグの温床になる可能性があるため使わない。


# 用語
それぞれの特徴を理解する際に、出てくる用語のまとめ
- 再代入 = 一度宣言した変数を更新すること
- 再宣言 = 一度宣言した変数を、同じ変数名を使って再び宣言し直すこと
- ブロックスコープ = ブロック{}ごとに囲まれた範囲のこと
- 関数スコープ = 関数のブロック{}ごとに作られる範囲のこと

# それぞれの特徴

## const
- **再代入不可**

- **再宣言不可**

- **ブロックスコープを持つ**
ブロックスコープ外からのアクセスを制限。つまり、ブロックスコープ外から参照ができない。

- **関数スコープを持つ**
関数スコープ外からのアクセスを制限。つまり、関数スコープ外から参照ができない。

## let
- **再代入可能**

- **再宣言不可能**

- **ブロックスコープを持つ**
ブロックスコープ外からのアクセスを制限。つまり、ブロックスコープ外から参照ができない。

- **関数スコープを持つ**
関数スコープ外からのアクセスを制限。つまり、関数スコープ外から参照ができない。

## var
- **再代入可能**

- **再宣言可能**

- **ブロックスコープを持たない**
ブロックスコープ外からのアクセスを許可する。つまり、ブロックスコープ外から参照ができる。

- **関数スコープを持つ**
関数スコープ外からのアクセスを制限。つまり、関数スコープ外から参照ができない。

# 再現
## 再代入
``` js
const constValue = 'Hello!!';
let letValue = 'Hello!!';
var varValue = 'Hello!!';

// 再代入
constValue = 'Goodby!!';
letValue = 'Goodby!!';
varValue = 'Goodby!!';

console.log(constValue);
console.log(letValue);
console.log(varValue);

// エラー内容
Uncaught TypeError: Assignment to constant variable.
Goodby!!
Goodby!!
```

`const`のみ再代入しようとするとエラーが吐かれる。

## 再宣言
``` js
const constValue = 'Hello!!';
let letValue = 'Hello!!';
var varValue = 'Hello!!';

// 再宣言
const constValue = 'Goodby!!';
let letValue = 'Goodby!!';
var varValue = 'Goodby!!';

console.log(constValue);
console.log(letValue);
console.log(varValue);

// エラー内容
Uncaught SyntaxError: Identifier 'constValue' has already been declared
Uncaught SyntaxError: Identifier 'letValue' has already been declared"
Goodby!!
```
`const`と`let`は再宣言しようとするとエラーが吐かれる。

## ブロックスコープ
``` js
const isTest = true;

if(isTest) {
  const constValue = 'Hello!!';
  let letValue = 'Hello!!';
  var varValue = 'Hello!!';
}

console.log(constValue);
console.log(letValue);
console.log(varValue);

// 出力
Uncaught ReferenceError: constValue is not defined
Uncaught ReferenceError: letValue is not defined
"Hello!!"
```

`const`と`let`は、if文などのブロックスコープ外から参照できない

## 関数スコープ
``` js
const setValuables = (text) => {
  const constValue = text;
  let letValue = text;
  var varValue = text;
}

setValuables('Hello!!');

console.log(constValue);
console.log(letValue);
console.log(varValue);

// 出力
Uncaught ReferenceError: constValue is not defined
Uncaught ReferenceError: letValue is not defined
Uncaught ReferenceError: varValue is not defined
```

`const`、`let`と`var`全て、関数ブロック外から参照できない

# const, letの方が優れている
`var`だと宣言したブロック以外にも影響をあたえてしまうため、意図しないところで値が変わってしまう。`const`, `let`だと宣言したブロック以内に影響が収まるため、意図しないところで値が変わってしまうことを防ぐことができます。

# constは定数のように見えて、定数ではない

`const`は再代入はできないが、`オブジェクト型（Array, Objectなど）`の中身を変更することができるようです。

例えば、配列に配列を再代入するとエラーになるが、配列の中身の一部を変更する時はエラーにらずに変更することができます。

そのため、`const`は定数のように見えて、定数ではないと言えます。

# まとめ
まとめて見て感じたことは、制限の少ない`var`を使うのではなく、制限の多い`const`、`let`
を使う方が良さそうです。
また、基本的には変数はconstで定義してあげて、for文などの処理で、変数を数え上げたりする場合は`let`を使用するという使い分けで良さそうです。
VS Code 1.60 の新機能 - ペア括弧の色付け機能

https://code.visualstudio.com/updates/v1_60#_high-performance-bracket-pair-colorization

括弧のペアを見分けやすくする色付け機能が追加された。
設定 `editor.bracketPairColorization.enabled` を `true` に変更すると有効になる。
（追記：この設定はv1.67以降では[デフォルトで有効になる](https://code.visualstudio.com/updates/v1_67#_bracket-pair-colorization-enabled-by-default)ようになった）

javascriptの例

| デフォルトの状態 | 設定ONの状態 |
|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/82c045c1-6e82-7b8f-49c8-d3b7ffa7b620.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/dac2e450-24f8-64af-2038-7b0aa5cbc52c.png)|

今までは拡張機能によって実現されていたがデフォルトで実現できるようになった。
php version 違いでエラーになる

 Fatal error: Uncaught Error: Call to undefined function mysql_connect() 　

![スクリーンショット 2021-09-07 8.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645197/c89d8564-0a4a-fed0-0c0f-b24c7df10d54.png)

バージョンが違うと出る
ネットで検索すると
バージョンによって書き方が変わると書いてあった

php version 7に書き換えるには、

$conn = mysql_connect($sv,$user,$pass) or die("接続エラー");

空

$conn = mysqli_connect($sv,$user,$pass) or die("接続エラー");


mysql_connect ------> mysqli_connect というふうにiをmysqlの


後につけることで解決することができる


そうすればエディタで表示されているエラーを解消することができる。
Godotで効果音の再生終了を待つ

## 動作環境

- Windows 10 Pro 21H1
- Godot V3.3.3

## 概要

Godotで

1. ボタンを押す
1. 効果音の再生
1. シーンの切り替え

という動作をさせたいとき、シーンの切り替えが早すぎて効果音がほとんど再生されない場合があります。

どうやって再生終了を待つか、という問題の対処方法です。

## yieldを使う

ループで待とう、とか効果音の長さを測っておいてタイマーを設定しよう、などというアイデアが思いつきますが、どちらもタイミングは不安定でメンテナンス性に欠けます。

対処はとても簡単`yield`を使えば解決します。

```
$AudioStreamButton.play()
yield($AudioStreamButton, "finished")
get_tree().change_scene("res://SceneTitle.tscn")
```

オーディオストリームの`finished`シグナルに対し`yield`を仕掛けるだけ。

たったこれだけで効果音の再生を待ってからシーンが切り替わります。
【Unity】シングルトンを使わずにシーン間でデータを共有したい

RPGゲームを開発中のUnity初心者です。シーン間のデータ共有の方法について検索をかけると「DontDestroyOnLoad」や「シングルトン」が多く結果に上がってきますが、正直あまり使いたくないのが本音です。

ます「シングルトン」はあまり多用したくないですよね･･･。
アイテムの所持状態やキャラステータス等シーン間で共有したいデータはたくさんあるのですが、その数のシングルトンを用意するのはオブジェクト指向に反していると感じます。「static」も同じです。

「DontDestroyOnLoad」に関しては個人的な感想なのですが、寿命が長いオブジェクトってどうなのっていう(;´･ω･)
シーンを切り替えても切り替えてもヒエラルキーに「DontDestroyOnLoad」が残り続けるのがなんか気持ち悪くて嫌なんです･･･。

ということでシーン切替時にデータを受け渡す方法を探したら神サイト様がありました！
#SceneManager.sceneLoaded
https://note.com/suzukijohnp/n/n050aa20a12f1

こういう神サイト様の存在は本当にありがたいです😌
要はシーン切替時に呼び出すイベントの中で、シーン切替後のスクリプトを呼び出すことが可能だとのことです。その時にデータを渡せますね、便利です。
nginxのリバースプロキシとNuxt.jsのリダイレクトでハマった話

# 状況
Dockerでnginxとnode環境(Nuxt.js)を構築して、リバースプロキシを介してNuxtアプリにアクセスすることを試みた。

```yml:dokcer-compose.yml
version: '3.9'
services:
  proxy:
    image: nginx:1.21.0
    volumes:
      - ./proxy/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - '80:80'

  web:
    build:
      context: ./web
      dockerfile: Dockerfile
    command: yarn dev
    volumes:
      - ./web:/app
    tty: true
    environment:
      PORT: 3000
      HOST: 0.0.0.0
    ports:
      - '3000:3000'

```

```conf:nginx.conf
events {}
http {
  server {
    listen 80;
    server_name localhost;

    location / {
      proxy_pass http://host.docker.internal:3000/;
    }
  }
}
```

この設定で、http://localhost/ へアクセスすると、リバースプロキシを介してNuxtアプリにアクセスできる。
しかし、途中で`location`を`/`から`/app/`に変更して、http://localhost/app/ の形でアクセスできるようにしたくなった。

```conf:nginx.conf
events {}
http {
  server {
    listen 80;
    server_name localhost;

    location /app/ { # ここを変更
      proxy_pass http://host.docker.internal:3000/;
    }
  }
}
```

`nginx.conf`を書き換えて、http://localhost/app/ にアクセスしたところ、こんなエラーが発生した。

> [error] 25#25: *1 open() "/etc/nginx/html/_nuxt/runtime.js" failed (2: No such file or directory)

ブラウザにはLoading Circleが表示されているので、Nuxtアプリ自体にはアクセスできているようだが、読み込めていないファイルがあるらしい。

エラー表記から`_nuxt/runtime.js`の参照先がおかしいことがわかる。
本来であれば、`localhost:3000`にホストされている`_nuxt/runtime.js`を参照したいところが、`localhost`にホストされている`_nuxt/runtime.js`を見に行ってしまっている。

# 解決までの道のり
まず、NuxtのbaseURLを`/`から`/app/`に変更した。

```javascript:nuxt.config.js
export default {
  // これを追記
  router: {
    base: '/app/'
  }
}
```

こうすることで、`localhost`ではなく、`localhost/app`にホストされている`_nuxt/runtime.js`を参照することになり、リバースプロキシによって`localhost/app`から`localhost:3000`へ飛ばされるので、結果的に`localhost:3000`にホストされている`_nuxt/runtime.js`を見に行くことになる。

よし、解決！

と思ったが、別の問題が発生した。
リダイレクトが無限に繰り返されるようになってしまった。
メカニズムとしてはこんな感じ。

1. `localhost/app`にアクセス
2. リバースプロキシが`localhost:3000`に読み替え
3. NuxtのbaseURLは`/app/`なので、`localhost:3000`から`localhost:3000/app`にリダイレクト
4. 結果的にURLは`localhost/app`になる
5. 1へ戻る

baseURLを書き換えたときにリバースプロキシの設定も書き換える必要があった。

```conf:nginx.conf
events {}
http {
  server {
    listen 80;
    server_name localhost;

    location /app/ {
      proxy_pass http://host.docker.internal:3000/app/; # ここを変更
    }
  }
}
```

http://localhost/app にアクセスすると、ちゃんとサイトが表示されました。
今度こそ解決！！ ٩(ˊωˋ*)و

# 別解
`proxy_pass`を設定するときには、trailing slash(後ろに付けるスラッシュ)に気をつける必要がある。
詳しくはこちら↓の解説記事を参照。
https://www.xmisao.com/2014/05/09/nginx-proxy-pass.html

trailing slashを付けずに`proxy_pass`を設定すると、飛び先のURLには、`location`の文字列も付与されるようになる。
これを利用して、最後の`nginx.conf`の書き換えを以下のようにしてもOK

```conf:nginx.conf
events {}
http {
  server {
    listen 80;
    server_name localhost;

    location /app/ {
      # proxy_pass http://host.docker.internal:3000/app/;
      proxy_pass http://host.docker.internal:3000; # これでもOK
    }
  }
}
```
【RSpec】KeyError: Factory not registered:を解決した方法


#対象者

* RSpecテストを実施した際にKeyError: Factory not registered:というエラーが出ている方


#目的

* 上記エラーを解消して、テストを正常に作動させる

#実際の手順と実例
###1.結論（解決策）

aliasを用いて、「spec/factories/user.rb」内のuserに「,aliases: [:follower,:followed] 」と追加して解決


###2.エラー内容と前提

フォロー機能のテスト実行時に出たエラーが下記の通り

![スクリーンショット 2021-09-06 14.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/c4081f24-fc70-1ecd-d57a-671d9a0d2f00.png)

Factoryに"followed"が登録されていないと予想

下記

```model/relationship.rb
class Relationship < ApplicationRecord
  # followerがフォローした人、followedがフォローされた人
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end
```

```model/user.rb
class User < ApplicationRecord
  has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
  has_many :followers, through: :reverse_of_relationships, source: :follower
  has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
  has_many :followings, through: :relationships, source: :followed
end
```

```spec/factories/relationships.rb
FactoryBot.define do
  factory :relationship do
    association :followed
    association :follower
  end
end
```

```spec/factories/users.rb
FactoryBot.define do
  factory :user do
    name { Faker::Lorem.characters(number: 4) }
    nickname { Faker::Lorem.characters(number: 4) }
    email { Faker::Internet.email }
    introduction { Faker::Lorem.characters(number: 20) }
    password { 'password' }
    password_confirmation { 'password' }
  end
end
```

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

RSpec.describe Relationship, type: :model do
   let!(:relationship) { FactoryBot.create(:relationship) }

  describe "モデルのテスト" do
    it "有効なRelationshipの場合は保存されるか" do
      expect(build(:relationship)).to be_valid
    end
  end
end
```

###3.エラー原因

Relationship.rbで
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
と記述しているように,アソシエーションに別名をつけている場合はFactoryの方にも別名を付ける必要があります。

なので、users.rbを上記の内容を追加します。

````spec/factories/users.rb
FactoryBot.define do
  factory :user, aliases: [:follower,:followed] do
:               　　#上記を追加
(中略)
:
end
````

aliasとは既存のメソッドに対して別名をつけることができるRubyメソッドのひとつです。

[Rubyのaliasとalias_methodでメソッドに別名を付ける方法【初心者向け】](https://techacademy.jp/magazine/18697)


これで解決しました！
setodaNote CTF Passcode Writeup Using Ghidra

setodaNote CTF Rev問題の３問目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/e746a73e-fa66-7827-ec1e-6607fdcac04d.png)

まずは strings から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/fec822ca-6856-1352-3507-6531b2aab45f.png)
Invalid passcode. Too short.発見
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/18e8ac01-c14a-81f2-6abc-a5782d892668.png)
関数は，FUN_00101185

```c:FUN_00101185(抜粋)
          iVar1 = strcmp((char *)&local_108,"20150109");
          if (iVar1 == 0) {
            puts("The passcode has been verified.\n");
            printf("Flag is : flag{%s}",&local_108);
          }
```

flagは，flag{20150109}
setodaNote CTF ELF Writeup Using Ghidra

setodaNote CTF Rev問題の２問目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/f111bd34-ed48-5baf-59be-1a74c3396e52.png)

stringsを確認したらダメだったので，functionから。
putsが気になったので，putsから追いかけてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/05d0b1a1-7dc8-6d44-473b-11c9cdbd3d3d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/df2cb452-cc8d-4ab8-a02f-4f44a137c80d.png)
putsのcall元は？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/c542fefe-ea07-1f57-5798-412204faad1b.png)
putsのcall元は，FUN_00101135

```c:FUN_00101135
undefined8 FUN_00101135(void)
{
  undefined8 local_28;
  undefined8 local_20;
  undefined local_18;
  int local_c;
  
  local_28 = 0x465d5a534f49444e;
  local_20 = 0x55494a4143494577;
  local_18 = 0;
  local_c = 0;
  while (local_c < 0x10) {
    *(byte *)((long)&local_28 + (long)local_c) = *(byte *)((long)&local_28 + (long)local_c) ^ 0x28;
    local_c = local_c + 1;
  }
  puts((char *)&local_28);
  return 0;
}
```

stack strings を 0x28 で xor してる
ビンゴみたい
Ghidra scriptでフラグを復元してみる

```python:test_ELF.py
#
# solver for WaniCTF Reversing complex
#
def qword_parse(value):
    #return([(value & 0xff00000000000000) / 0x100000000000000,(value & 0x00ff000000000000) / 0x1000000000000,(value & 0x0000ff0000000000) / 0x10000000000,(value & 0x000000ff00000000) / 0x100000000,(value & 0x00000000ff000000) / 0x1000000,(value & 0x0000000000ff0000) / 0x10000,(value & 0x000000000000ff00) / 0x100,(value & 0x00000000000000ff) / 0x1])
    return([(value & 0x00000000000000ff) / 0x1,(value & 0x000000000000ff00) / 0x100,(value & 0x0000000000ff0000) / 0x10000,(value & 0x00000000ff000000) / 0x1000000,(value & 0x000000ff00000000) / 0x100000000,(value & 0x0000ff0000000000) / 0x10000000000,(value & 0x00ff000000000000) / 0x1000000000000,(value & 0xff00000000000000) / 0x100000000000000])

def dword_parse(value):
    #return([(value & 0xff000000) / 0x1000000,(value & 0x00ff0000) / 0x10000,(value & 0x0000ff00) / 0x100,(value & 0x000000ff) / 0x1])
    return([(value & 0x000000ff) / 0x1,(value & 0x0000ff00) / 0x100,(value & 0x00ff0000) / 0x10000,(value & 0xff000000) / 0x1000000])

def word_parse(value):
    #return([(value & 0xff00) / 0x100,(value & 0x00ff) / 0x1])
    return([(value & 0x00ff) / 0x1,(value & 0xff00) / 0x100])

local_28=[]

addr = toAddr(0x0010113d)
inst = getInstructionAt(addr)
local_28.extend(qword_parse(inst.getOpObjects(1)[0].getValue()))

addr = toAddr(0x00101147)
inst = getInstructionAt(addr)
local_28.extend(qword_parse(inst.getOpObjects(1)[0].getValue()))

print(local_28)
print(''.join(map(chr,local_28)))

ans = []

i = 0
while i < 0x10:
    ans.append(local_28[i] ^ 0x28)
    i = i + 1

print(ans)
print(''.join(map(chr,ans)))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/6c7f5177-98cd-64fe-4c8d-87993b1af28b.png)
ビンゴ！
method（メソッド）について

・復習＋学習始めたての方に


method（メソッド）とは？

プログラミングにおける処理をまとめたもののこと

定義の仕方

```rb
def say_hello
  puts "Hello" 　メソッドの定義の部分
end

say_hello　　　　メソッドの実行
```

実行結果　Hello と出ます！

初投稿なので、簡単なのを簡単にまとめてみました。
これからどんどん分かりやすく楽しみめるような投稿していきます！
[Visual Studio Code]ブラケット（括弧）のペアを色分けする

# 概要
Visual Studio CodeではこれまでもBracket Pair Colorizer等、拡張機能で括弧の色分けが出来ていました。
2021年8月アップデートのVisual Studio Code ver1.60から自身の機能としてこの機能が実装されました。

# 本文
設定画面の検索窓に

```cs
editor.bracketPairColorization
```
と入力します。

![スクリーンショット (715).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5dd6fd7b-6274-721d-c1cf-009f583a6ed5.png)

チェックを入れるだけで完了です。

# 補足
Bracket Pair Colorizerを使うよりもパフォーマンスの向上が見込めるそうです:grinning: