OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript:超初級編】ボタン操作で画像を表示する/切り替える

##このプロジェクトを作った目的
とあるプロジェクトの雛形を実験してみたかった
投稿者は未経験からIT業界にはいったので、最初はつまづいたな〜という思いから一応記事にしておきます。
##前提条件
webデザイナーではないのでclassの命名規則とかは見逃してください。
あとコードの綺麗さとかはすみませんが汚いです！！！！涙
##何をつくるか
シンプルに以下3つの要件を設定。3つ以下の細かいことは無視。
・スマホ用の解像度（横505px,縦766px）
・画像の下にボタンを複数配置する（8個）
・ボタンをクリックすると画面に表示されている写真が変わる
##完成イメージ
githubですコードをダウンロードすればそのままgetできるはずです。
https://github.com/i-am-ethan/pushBtn_changePics
![スクリーンショット 2021-02-16 20.31.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/f08ae8b3-114b-5a0f-1b1e-7abfc69642f3.png)

##スタート！！

###(1)いらすとやで画像を調達
今回は、８種類の動物の画像をゲットする
https://www.irasutoya.com/search/label/%E5%8B%95%E7%89%A9
ボタンは自分でpowerpointで作りました。
githubで公開したので勝手にdownloadしてください。

###(2)プロジェクトファイルを作る
てきとうな名前でディレクトリをつくって、いつものように三種の神器を作成。
・index.html
・style.css
・main.js
ファイルの構造はこんな感じです
![スクリーンショット 2021-02-16 21.02.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/13c32de3-1ea2-3ca3-8521-2a975f5ac274.png)

###(4)index.html
とりあえず、画像1枚とその下にボタンが並ぶようなスタイルを記述します。
まじで見にくいですがすみません。

```html:index.html
<body>
  <div class="wrap">
    <div class="main">
      <div class="pics">
        //画像を配置
        <img class="pic" id="pics" onclick="" src="img/arupaka.png" alt="">
      </div>
      <div class="btns">
　　　　　//ボタンたちを配置
        <img class="btn" id="btn1" src="btn/1.png" height="50px" width="50px">
        <img class="btn" id="btn2" src="btn/2.png"  height="50px" width="50px">
        <img class="btn" id="btn3" src="btn/3.png"  height="50px" width="50px">
        <img class="btn" id="btn4" src="btn/4.png" height="50px" width="50px">
        <img class="btn" id="btn5" src="btn/5.png"  height="50px" width="50px">
        <img class="btn" id="btn6" src="btn/6.png"  height="50px" width="50px">
        <img class="btn" id="btn7" src="btn/7.png"  height="50px" width="50px">
        <img class="btn" id="btn8" src="btn/8.png"  height="50px" width="50px">
      </div>
    </div>
  </div>
  //jsの読み込みです
  <script src="main.js"></script>
</body>
```

###(5)style.css
cssは好きなようにやってください

###(6)main.js
jsファイル内のメソッドです。
こちらのidとsrcを変えてあげれば、他のボタンのクリックされた処理もできるとおもいます！

```javascript:main.js
//"btn1"というIDを取得して、クリックしたらfunctionを実行する
document.getElementById("btn1").onclick = function(){
    //"pics"というIDを取得して、そのsrcを"img/arupaka.png"に変更する
    document.getElementById("pics").src="img/arupaka.png";
  }
```

###(7)アロー関数バージョン
```javascript:main.js
//"btn1"というIDを取得して、クリックしたらfunctionを実行する
document.getElementById("btn1").onclick = () => {
    //"pics"というIDを取得して、そのsrcを"img/arupaka.png"に変更する
    document.getElementById("pics").src="img/arupaka.png";
  }
```

###(8)コードを短縮したい時
```javascript:main.js
const pushBtn = (btn,src) => {
  document.getElementById(btn).onclick = function(){
    document.getElementById("pics").src=src;
  }
}
pushBtn("btn3","img/hituzi.png")
pushBtn("btn4","img/kaba.png")
pushBtn("btn5","img/tori.png")
pushBtn("btn6","img/uma.png")
pushBtn("btn7","img/usi.png")
pushBtn("btn8","img/yagi.png")
```

以上！！
B - Orthogonality, A - Three-letter acronym, C - Monsters Battle Royale

2021/2/15
くじかつ精進内容

##[B - Orthogonality](https://atcoder.jp/contests/abc188/tasks/abc188_b)

O(N)
問題の内容は、A[i]＊B[i]の合計は０か判定してください。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
const long long INF = 1LL << 60;
 
int main() {
    int n;
    cin >> n;
 
    vector<ll> a(n), b(n);
    rep(i, n) cin >> a[i];
    rep(i, n) cin >> b[i];
 
    ll res = 0;
    rep(i, n){
        res += a[i] * b[i];
    }
    if(res == 0) cout << "Yes" << endl;
    else cout << "No" << endl;
 
    return 0;
}
```

##[A - Three-letter acronym](https://atcoder.jp/contests/abc059/tasks/abc059_a)

o(1)
問題は、先頭の文字列を大文字に変換し繋ぎ合わせて出力せよ。
pythonの大文字への変換メソッドは「upper」です。

```python:python
S1, S2, S3 = list(map(str, input().split()))
print(S1.upper()[0] + S2.upper()[0] + S3.upper()[0])
```

##[C - Monsters Battle Royale](https://atcoder.jp/contests/abc118/tasks/abc118_c)

O(N)
最大公約数を求める問題です。

```python:python
import math
from functools import reduce
 
N = int(input())
A = list(map(int, input().split()))
 
res = reduce(math.gcd, A)
print(res)
```
gem bcryptの使い方

##gem bcryptとは？
パスワードをハッシュ化するための関数を提供してくれるgemです。
Gemfileに既にコメントアウトされてあるので、コメントアウトを外しbundleします。

#ハッシュ関数とは？
適当な値を中に放り込むと適当な値を返してくれる関数のこと。
 bcryptで生成されたハッシュ値は60文字で出力されます。

文字列　→　ハッシュ関数生成　→　カラム保存
という流れになります。


/model

```
 def password=(raw_password)
    if raw_password.kind_of?(String)
      self.hashed_password = BCrypt::Password.create(raw_password)
    elsif raw_password.nil?
      self.hashed_password = nil
    end
  end

```

引数をとり、kind_ofメソッドで文字列かどうかの判定を入れています。stringクラスであればtrueが返ります。

BCrypt::Password.createでインスタンスを生成し、カラムであるhashed_passwordに代入しています。




参考：https://hiyo-ac.hatenablog.com/entry/2019/01/27/160644
&emsp; &emsp; &ensp; &ensp; https://wa3.i-3-i.info/word11948.html
jestで特定のファイル(ファイルごと)でtestする環境を変えたい場合

JavaScriptのテスティングフレームワークとして有名なjestですが、使っていると以下のようなエラーが起きることがあります。

```console
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
    Consider using the "node" test environment.
```

jestではテストの実行するときの環境が、デフォルトで`jsdom`になるのですが、テストファイルによっては上記のようなエラーに出くわします。

そこで、`ファイルごとに環境を変えられたらいいのに`と思って調べていたところ、[公式ドキュメント](https://jestjs.io/docs/ja/configuration#testenvironment-string)に載っていました。

以下がその方法です。

```test.ts
/**
 * @jest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div');
  expect(element).not.toBeNull();
});
```

ファイルの上部(多分どこでも大丈夫だと思いますが)に`@jest-environment jsdom`や`@jest-environment node`を追加することで、そのファイルのみ別の環境でテストできます!!
デザインど素人がそれっぽいフォームを作るときのポイント

#概要
フォームの初期デザインって（当たり前ですが）ダサいですよね。
しかし、どうすればそれっぽくなるのかイチイチ悩んでしまって時間がかかってしまったので、デザイン素人が一瞬で**それっぽくする**フォームの作成をまとめたいと思います。

#ポイント
##①input要素の横幅は全て統一
![スクリーンショット 2021-02-16 14.00.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/4f934f32-b1e8-fd35-d1ce-617ef87b4cda.png)

>input{
    width:90%;
}

複数あるフォームの部品は横幅を揃えることでそれっぽくなります。

##②枠線はいい感じに
input要素の初期値は下記のようになってます。

```改善前.css
input{
    border-width: 2px;
    border-style: inset;
    border-color: -internal-light-dark(rgb(118, 118, 118), rgb(133, 133, 133));
}
```

太さは1pxの方がスタイリッシュになりますし、色もダサいし、個人的にinsetじゃなくてsolidのほうがかっこいいです。

```改善後.css
input{
    border: 1px solid #CFCABF;
}
```
色はハッキリした色は使わない方が**それっぽい**です。

##③入力欄の選択時の枠線をいい感じに
デフォルトの選択時の枠線配は以下のようになっています。
![スクリーンショット 2021-02-16 14.14.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/16e5598b-a051-7a2b-c270-84c9af99ace2.png)

（ださい。。。）

input:focusでstyle変更できます。

```.css
input:focus{
  border: 1px solid #ff9900;
}
```

##④textareaの右下のやつを消す
![スクリーンショット 2021-02-16 14.21.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/0149ed90-55f3-565d-5f1f-34d92c969d12.png)

この右下にあるのもダサいので、消しておきます。

```.css
textarea{
    resize: none;
}
```

##⑤画像選択も消す
![スクリーンショット 2021-02-16 14.25.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/ee60ef30-ef80-b41c-b4be-e23550a3a96e.png)
 input fileもダサいので変更します。

これは初期値を弄るよりも、これ自体をdisplay:none;にして別でボタンを作った方が手っ取り早いです。

```.html
<label class="form-label image-label" for="image">
    <input id="image" type="file" name="image"
        accept="image/png, image/jpeg" style="display:none;" v-on:change="onFileChange">
    <div>アイコンを変更する</div>
</label>   
```

```.css
label div{
    display: inline-block;
    border: 1px solid;
    border-radius: 5px;
    padding: 2%;
    margin: 0;
    cursor: pointer;
}
```

#まとめ
デザイナーから見たら何言ってんだコイツって思われるのかもしれませんが、これでそれっぽいフォームを作ることができました。
【解決】This program needs access to the screen. Please run with a Framework build of python, and only when you are logged in on the main display of your Mac.

#環境
macOS Big Sur
python 3.7.5(pyenvの不具合でpyenv installではインストールできないやつ)

#エラー文
```
This program needs access to the screen. Please run with a Framework build of python, and only when you are logged in on the main display of your Mac.
```

#やろうとしてたこと
pyenvでインストールしたpythonで、wxpythonを動かそうとしてた。
一回諦めてtkinterに挑戦してみたけど、動かなかった。
wxpythonはtkinterをベースにしてるっぽいので、結局tkinterが動かなかったんだと思う



#原因
wxpythonを使うのには、Framework buildのpythonがが必要になるらしい。
pyenv installで、入れたものはFramework build ではないので、上記エラーが出る。


#さらにめんどくさいこと
pyenvとmacの相性が悪いのか、pyenvだと3系のpythonがうまく入らないので、下記のコマンドで入れてた。ややこし

```
CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" pyenv install --patch 3.7.5 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)
```

#エラー対応とframeworkbuildのpythonのインストール両方解決するコマンド
```
CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" pyenv install --patch 3.7.5 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)
```
鹿島アントラーズと横浜F・マリノスで二項検定

# はじめに

「Rによるやさしい統計学」で統計学を学んでいるが、例題だけやっていてもおもしろくないので、Jリーグの歴史でいまだJ2降格を経験していない名門2チームのどちらが強いのかを二項検定してみる。データは[Soccer D.B.](https://soccer-db.net/team/headtohead.php?te=1004)を使う。これまでの両チームの戦績は、全78戦で鹿島39勝、横浜26勝、13引分（2021年2月16日現在）。手順は本に従って進める。

# 問題設定

統計的仮説検定によって、確認する。

## (1)帰無仮説と対立仮説の設定

帰無仮説H0：　鹿島アントラーズと横浜F・マリノスの強さは等しい
対立仮説H1：　鹿島アントラーズは横浜F・マリノスよりも強い

対立仮説より、この検定は片側検定となる。なお、「強い」とは勝つ確率が相手チームよりも高いことを、「強さが等しい」とは勝つ確率が相手チームと等しい（つまり0.5）ことを意味するとする。

## 検定統計量の選択

検定統計量は鹿島アントラーズの勝利数となる。

# (3)有意水準αの決定

有意水準は5%とする。

# (4)検定統計量の実現値を求める

検定統計量の実現値は、鹿島アントラーズの勝利数39勝となる。

# (5)帰無仮説の棄却 or 採択の決定

まず帰無仮説のもとでの検定統計量の分布（帰無分布）を dbinom関数 を用いて求める。この関数は、ある事象の成功確率がpであるとき、n回の試行でx回成功する確率を dbinom(x, n, p) で求めることができる。今回は引分のケースは除いた全65戦で鹿島39勝、横浜26勝とし、帰無仮説で「強さは等しい」としているため成功確率を0.5として、65戦して39勝する確率を求めると以下のようになる。

```r:dbinom.R
dbinom(39, 65, 0.5)
# [1] 0.02717543
```

これからわかるように、強さが等しい2チームが65回対戦して、39勝する確率は __約2.7%__ となることがわかる。勝利数の取りうる範囲は0勝から65勝まであるので、以下のコードでそれぞれの勝利数となる確率を求め、帰無分布を図示すると以下のようになる。

```r:winRate.R
nwin <- 0:65
plot(nwin, dbinom(nwin, 65, 0.5), type="h")
```

![kimu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/5b1f2dd1-918c-ceef-5520-fabf8c5bfc09.png)

pbinom関数 を使うと勝利数がx以下である確率（下側確率）を求められる。使い方は dbinom関数 と同じ。オプションで lower.tail=FALSE で上側確率を求められる。（以下で勝利数を38としているのは、38勝以下である確率を引いたものが39勝以上となる確率であるため。）

```r:pbinom.R
round(pbinom(38, 65, 0.5, lower.tail=FALSE), digit=4)
# [1] 0.068
1 - round(pbinom(38, 65, 0.5), digit=4)
# [1] 0.068
```

この結果より、39勝以上する確率は 0.068 となり、この確率は有意水準 0.05 よりも大きいので、帰無仮説は採択される。つまり、__「鹿島アントラーズと横浜F・マリノスの強さは等しい」__となる。ちなみに40勝以上する確率は 0.0408 となるため、この場合は帰無仮説が棄却され、「鹿島アントラーズは横浜F・マリノスよりも強い」と言える。あと1勝していれば5%水準で有意であると言えたみたいだが、とはいえこの戦績を見ると今回の検定結果は「第2種の誤り」なのではと思ったり思わなかったり・・・。
M5Stackで会議室の使用状況をモニタリングしよう②（マグネットスイッチ＋人感センサー編）


#概要
[前回](https://qiita.com/keicafeblack/items/9280ac3a39a14c96b00e)は会議室の利用状況をWeb上で把握できる仕組みを
　M5Stack＋マグネットスイッチ→ThingSpeak
を使って構築しました。

しかし”会議後にドアを開けておく”事を忘れる場合があるため、人感センサーを使用して会議室内の人の有無をチェックできる機能を追加しました。
![人感センサー付き.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/b0ab39e8-10f9-3b8a-63b3-c1ca7ea42d29.jpeg)
![TS.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/f1a77232-98de-e386-78c1-03a1b1c58011.jpeg)

なお、今回もUIFlowを使用して、1行もコードを書かずに構築しています。

#使用したもの
・M5Stack（Basic）
・マグネットスイッチ
　→ダイソーの「ドアが開くと点灯するライト」の部品を流用
　　→[参考：ラズパイで100均のドア開閉センサー検知](https://jellyware.jp/kurage/raspi/daiso_sensorlight.html)
・追加：[秋月電子：焦電型赤外線センサーモジュール（焦電人感センサ）](https://akizukidenshi.com/catalog/g/gM-14064/)
	

#接続方法
①マグネットスイッチ
　→21ピン
　→GND
②人感センサー
　センサー→M5Stack
　GND→GND
　VCC→5V
　OUT→5ピン

#コード
最後に人を感知してから
・何秒経過したか→画面表示
・何分経過したか→ThingSpeakに通知
を出力しています（あまり大きな数値を出しても意味がないので、最大3分まで対応しています）


![C1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/951d9d0f-9d83-5698-496e-d8a06cc7d070.jpeg)
![C2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/5005a68f-2f67-ea3b-b372-8de2640cbe4b.jpeg)


```ruby:M5Door2.py
from m5stack import *
from m5ui import *
from uiflow import *
import time
import machine
import urequests

setScreenColor(0x222222)


CNT = None
isOpen = None
isMan = None


DoorStatus = M5TextBox(88, 44, "DoorStatus", lcd.FONT_DejaVu24, 0xFFFFFF, rotate=0)

from numbers import Number




setScreenColor(0x000000)
DoorStatus.setText('Started')
wait(5)
pin0 = machine.Pin(21, mode=machine.Pin.IN, pull=machine.Pin.PULL_UP)
pin1 = machine.Pin(5, mode=machine.Pin.IN, pull=machine.Pin.PULL_UP)
CNT = 1
while True:
  isOpen = pin0.value()
  isMan = pin1.value()
  if isOpen == 0:
    setScreenColor(0xff0000)
    lcd.print('Close', 0, 0, 0x000000)
  else:
    setScreenColor(0x009900)
    lcd.print('Open', 0, 0, 0x000000)
  if isMan == 0:
    if CNT >= 180:
      CNT = 180
  else:
    CNT = 1
  lcd.print(((str('Last Man Found(s):') + str(CNT))), 0, 30, 0x000000)
  if 0 == 0:
    try:
      req = urequests.request(method='GET', url=(str(((str('https://api.thingspeak.com/update?api_key=★ここにAPIKeyを入れます★&field1=') + str(isOpen)))) + str(((str(' &field2=') + str((CNT / 60)))))), headers={})
      lcd.print('Posted', 50, 120, 0x000000)
    except:
      lcd.print('NG', 50, 120, 0x000000)
  wait(5)
  CNT = (CNT if isinstance(CNT, Number) else 0) + 5
  wait_ms(2)


```

#苦労したところ
１．ThingSpeakに２つの数値の送る書き方が分からなかった
>・・・&field1=') + str(isOpen)))) + str(((str(' &field2=') + str((CNT / 60)))

という書き方で送ることができました。

２．人感センサーに反応されないようにするのが大変だった
近くにいるとどうしても反応してしまうため、センサーを皮の筆入れで包むことで遮断した
Qiita Daily Survey memo 2021.02.16

# Qiita Daily Survey memo 2021.02.16
Qiita の記事を可能な限り毎日読むために、読んだmemoを公開することでモチベーションを維持しようという試み。
昨日は1位だったフラクタル構造の記事をどうしよう…と悩んでいたら、書き損ねてしまいました…。

## [Python と Playwright でブラウザを自動操作させるコードを自動生成したよ](https://qiita.com/mainy/items/3a9de19f440991f67f34)
mainy さんの記事。
ブラウザの自動操作の記事ですが、コードの自動生成とテスト・エビデンス取得の効率化のところがヤバい（語彙力）。
納得の 227 LGTM と Daily 1位。
がっつりしたフロントエンドの開発・テストは業務経験がありませんが、同様の作業で苦しんでいる方は非常に多いのではと感じます。
コードの自動生成では、そもそも0から（テンプレートとかはもちろんあると思いますが）書くのに比べて、大きく手間が減ると思いました。
また、自動生成の修正で作業がそろえば、コードも似たようなものになるはずなので、複数人で作業した時の揺れを最小限に抑えられると感じました。
また、キャプチャの取得、および動画を撮れるのもものすごい…。
これは絶対に触ってみたいと思った技術です。


## [究極に便利な検索サイトを作った【Ultimate search】](https://qiita.com/Tanukizzan/items/ffc2e11d8c7cb6f11e27)
Tanukizzan さんの記事。
高校生の方が作成された、様々な検索に対応した検索サイト。
最近の高校生本当にSUGOI…
記事も大変丁寧に書かれていて読みやすいです。
何よりも、「作りきって」「公開して」「解説の記事を書く」ができていることがすごい。
見習わなければ…と思いました…。

余談ですが、VRで知り合った方が、知識も技術も相当高かったので年上かと思っていたら高校生だった、なんてこともありました。


## [【2021年版】サーバーサイドエンジニアがVue.jsでモダンフロントエンド開発を始めるまで](https://qiita.com/yuki_0920/items/af003c0899cb83d99c14)
yuki0920 さんの記事。
Vue.js 周りの知識（Javascript,Vue.js,CSS,webpack,StoryBook,Railsとの連携)を体系的に学習され、その流れと時間を書いてくださっている記事です。
自分は React にトライして簡単なサイトを作ったところで止まってしまっているので、体系的な整理や振り返りが必要だなと思いました…。
また、所要時間書いてくださっているのが非常にありがたく、どれくらいの心構えで向かっていけばいいのかがわかり、チャレンジしやすいなと感じました。（20時間と書かれていても、20時間頑張るぞー！となるのと、ページを開いて「うわ…」となるのでは、精神的な負荷が全然違うと思います）
また、自分はCSSのところが弱いので、貼られていたリンクの[CSS の構成要素](https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks)を読んでおこうと思いました。


## [【個人開発】爆速でClubhouseのアイコンを作れるサービスを作ったので振り返る](https://qiita.com/retoruto_carry/items/337081d188a718e6c746)
れとるときゃりー(retoruto_carry)さんの記事。すき。もっと伸びて。
非常にキャッチ―な画像から始まり、スケッチや作業の流れがまとめられている記事です。
ちょっと触ってみるか…と思ったら、1分くらいでできてしまった…SUGOI

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410015/6278b64b-16f5-8d36-3251-8b200dee5ec3.png)

自分は古き良きウォーターフォールや設計書設計書した開発も、それはそれでよいと思いますが、、、
この記事で紹介されているような スケッチ -> 実装してみる -> 追加・修正 -> まとめる の流れが好きなので、読んでいて「うんうん！うんうん！！」となる記事でした。
4日で作ったとありますが、ものすごい…。
エネルギーをいただきました…頑張る！！


## [【AI×音声】文字起こし要約サービスを作って「緊急事態宣言」を3行にまとめてみた。](https://qiita.com/naogify/items/21391c1305f6946f6176)
オオハシ ナオキ(naogify) さんの記事。
文字起こしに加えて要約までしてくれるサービスを作った…という記事。
記事内では緊急事態宣言を3行にまとめると…？ということをしてくれていて「制度が甘い…」と振り返られていますが、要約の提案が出てくるだけですんごいと思いました。
自分は朝起きた時に、頭の中をボイスメモでdupmして空っぽにしてから考え事をするようにしていますが（3日坊主、n日ぶりm回目）、それらが簡単な要約付きで List されてくれたら、すごい助かるかも…！と思いました。

リンク先からサイトを利用させていただきましたが、chrome が悪いのかネットワークが悪いのか、自分の環境からでは文字起こしが反応せず…といった感じでした。

## つれづれ感想
勉強して、まー分かったで終わらせず、何か作って形にして公開する…まで頑張れる人すごいなーと思います…。
めちゃエネルギーをいただいたので、自分もスケッチから初めて何かしてみる…！
EventBridgeのターゲットに異なるアカウントのEventBridgeを指定する

# 構成

![EventBridge_AccountCross.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/d2aa0852-b933-7b47-87ad-a18029b2a448.png)

# 受信側EventBridgeの事前準備

　EventBridgeのターゲットに異なるアカウントのEventBridgeを指定する際、受信側のEventBridgeイベントバスARNを指定する必要があります。
　受信側EventBridgeのイベントバスARNをメモするために受信側アカウントにサインインします。

![スクリーンショット 2021-02-16 18.59.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/cfc17a81-32cc-d2ef-0d60-7b41bcaaf5d6.png)

　次に、送信側アカウントからのイベントを受信できるようにするためのアクセス許可を行います。

![スクリーンショット 2021-02-16 19.24.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/fc16f13b-055e-03f0-db95-15d8ff86d6a8.png)

# 送信側EventBridgeの設定

　送信側アカウントにサインインし、EventBridgeルールを作成します。

![スクリーンショット 2021-02-16 19.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/ecbe7f5f-0cf3-e486-3b4d-8e7ac923c526.png)

　失敗しました。

![スクリーンショット 2021-02-16 19.06.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/495085a4-0ba7-4eff-ec4c-32dd8c96833d.png)

　異なるリージョンのターゲット追加は許可されていないようです。
　同じリージョン間で作成します。
　今度は作成できました。

![スクリーンショット 2021-02-16 19.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/8ca38b9f-0e8e-b5a9-2d09-6d3fd5e82b35.png)

　ついでに自動作成されたIAMロールの内容を確認します。
　受信側アカウントのイベントバスにイベント送信を許可するIAMポリシーがアタッチされていました。

```json:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "events:PutEvents"
            ],
            "Resource": [
                "arn:aws:events:us-east-1:${受信側アカウントID}:event-bus/default"
            ]
        }
    ]
}
```

　これで受信側EventBridgeで受信できるようになっているはずです。

# 受信側EventBridgeの設定

　送信側EventBridgeからのイベントに一致するためのルールを作成します。

![スクリーンショット 2021-02-16 19.40.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/ebffed00-c2f2-26e8-7b9c-a450ba1734d6.png)

　送信側EventBridgeからイベントの受信に成功したようで、ターゲットに指定したSNSからメールが届きました。
　イベントの内容はJSON形式にすると以下のようになりました。

```json:
{
    "version":"0",
    "id":"724ffb86-a0db-06ef-5cef-1c1b407cfcb4",
    "detail-type":"Scheduled Event",
    "source":"aws.events",
    "account":"${送信側EventBridgeのアカウントID}",
    "time":"2021-02-16T10:38:38Z",
    "region":"us-east-1",
    "resources":["arn:aws:events:us-east-1:${送信側EventBridgeのアカウントID}:rule/test-cross-account"],
    "detail":{}
}
```

# 料金

　EventBridgeでクロスアカウントで送信した場合、送信アカウントに料金が請求されます。
　無料ではないようです。
　百万件の公開済みイベントごとに1ドルでした（2021.2.16現在）。
　https://aws.amazon.com/jp/eventbridge/pricing/
Typescript の HTMLElement型一覧

# HTMLElementの型宣言に悩んだときに見直す表

DOMを扱う場合、型宣言に困りませんか？
まだIDEの機能を十分に使いこなせておらず、どうしても型宣言に悩む場合があります。

一覧化していればある程度予測がつくと思うので
同じような方がいればぜひ参考にしてください。


```
HTMLAppletElement
HTMLBRElement
HTMLBaseElement
HTMLButtonElement
HTMLCanvasElement
HTMLDListElement
HTMLDataElement
HTMLDataListElement
HTMLDetailsElement
HTMLDialogElement
HTMLDirectoryElement
HTMLDivElement
HTMLEmbedElement
HTMLFieldSetElement
HTMLFontElement
HTMLFormElement
HTMLFrameElement
HTMLHRElement
HTMLHeadElement
HTMLHeadingElement
HTMLHtmlElement
HTMLIFrameElement
HTMLImageElement
HTMLInputElement
HTMLLIElement
HTMLLabelElement
HTMLLegendElement
HTMLMapElement
HTMLMarqueeElement
HTMLMediaElement
HTMLMenuElement
HTMLMetaElement
HTMLMeterElement
HTMLModElement
HTMLOListElement
HTMLObjectElement
HTMLOptGroupElement
HTMLOptionElement
HTMLOutputElement
HTMLParagraphElement
HTMLParamElement
HTMLPictureElement
HTMLPreElement
HTMLProgressElement
HTMLQuoteElement
HTMLScriptElement
HTMLSelectElement
HTMLSlotElement
HTMLSourceElement
HTMLSpanElement
HTMLTableCaptionElement
HTMLTableCellElement
HTMLTableColElement
HTMLTableElement
HTMLTableRowElement
HTMLTableSectionElement
HTMLTemplateElement
HTMLTextAreaElement
HTMLTimeElement
HTMLTitleElement
HTMLTrackElement
HTMLUListElement
HTMLUnknownElement
```

## ちなみに
`extends HTMLElement`している箇所を一覧化してみたのですが、
よくよく調べると公式にも記載がありました。

どのタグがどの型に紐づいてるかは下記参照すれば、きっとわかると思います
（筆者未確認☆）

[Typescript公式](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.htmlelement.html)
【Python】Djangoでプロジェクトを作成する

## 前提
Anacondaはインストールしておく。

## 手順
```
$ pip install django
```
これでDjangoをインストールする。

```
$ django-admin startproject myproject
```
そのあと、このコマンドでmyprojectというプロジェクトを作成することができる.

```
$ls
```
これでディレクトリ内を確認。

```
manage.py	myproject
```
このようなファイルが出来上がっている。

そのあと、下のコマンドを実行する。

```
$ python manage.py runserver
```
![スクリーンショット 2021-02-16 19.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628093/cbad73b5-e75e-5e8f-4680-516a2abc83ad.png)

できた。
Ruby on Jetsでターミナルにログを出力する方法

## ターミナルにLoggerを出力する方法

loggerが記載されている箇所を変更する。

```ruby:config/application.rb
# config.logger = Jets::Logger.new($strerr)
config.logger = Jets::Logger.new($stdout)
```

loggerを出力する際はRuby on Railsのように、例えばlogger.debug ('hi')という記載をするのでは無く、Jets.logger.debug ('hi')のようにJetsを明言します。
これを記載しなければ、エラーが起こります。

```ruby:posts_controller.rb
# GET /posts
  def index
    Jets.logger.debug ('log')
    p ('log')
    @posts = Post.all
    Jets.logger.debug (@posts.to_a)
  end
```

以下のようにログが出力されます。

```
app_1  | I, [2020-11-20T02:44:43.363645 #60]  INFO -- : Started GET "/posts" for 172.18.0.1 at 2020-11-20 02:44:43 +0000
app_1  | I, [2020-11-20T02:44:43.363994 #60]  INFO -- : Processing PostsController#index
app_1  | I, [2020-11-20T02:44:43.364474 #60]  INFO -- :   Event: { 省略 }
app_1  | I, [2020-11-20T02:44:43.364651 #60]  INFO -- :   Parameters: {}
app_1  | D, [2020-11-20T02:44:43.364999 #60] DEBUG -- : log
app_1  | "log"
app_1  | D, [2020-11-20T02:44:43.381540 #60] DEBUG -- : [#<Post id: 2, title: "create", created_at: "2020-11-20 01:39:31", updated_at: "2020-11-20 01:39:31">, #<Post id: 3, title: "test", created_at: "2020-11-20 01:43:45", updated_at: "2020-11-20 01:43:45">, #<Post id: 4, title: "post", created_at: "2020-11-20 01:43:53", updated_at: "2020-11-20 01:43:53">, #<Post id: 5, title: "new", created_at: "2020-11-20 02:31:57", updated_at: "2020-11-20 02:31:57">]
```

changelogを確認すると、1.5.2のリリースよりLoggerが利用できるようになったようです。

### 参考サイト
https://github.com/boltops-tools/jets/blob/master/CHANGELOG.md#152
Vue.jsとGoogle Books APIを使って本の検索機能を実装する

Vue.jsとGoogle Books APIを使って簡単に本の検索機能が実装できたのでメモを残しておきます。

#コード内容

```html
    <form id="search-form">
        <input class="form-text" type="text" id="isbn" placeholder="ISBNコードを入力" v-model="isbn">
        <button type="button" v-on:click="search()">検索</button>
    </form>
    <div id="result"></div>
```

![検索フォーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110285/3b5d7d60-90c4-a3e2-4485-845c782f0685.png)

に対して、

```javascript

new Vue({
    el:'#search-form',
    data: {
        isbn: '',
    },
    methods: {
        search() {
            const code = document.getElementById('isbn').value;

            fetch(`https://www.googleapis.com/books/v1/volumes?q=isbn:${code}`)
                .then(response => {
                    return response.json();
                }).then(data => {
                    const bookTitle = data.items[0].volumeInfo.title;
                    $('#result').append(bookTitle);
                }).catch(function(error) {
                    $('#result').append(error);
                });
        }
    }
});
```

と設定することで
![検索結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110285/563230a9-74a7-8974-d0a2-62c4a90d3fc1.png)

検索機能が実装されました。

#何が起きているのか

まず

```javascript
const code = document.getElementById('isbn').value;
```
の部分で、検索フォームに入力されたISBNコードを取得しています。


```javascript
 fetch(`https://www.googleapis.com/books/v1/volumes?q=isbn:${code}`)
                .then(response => {
                    return response.json();
                }).then(data => {
                    const bookTitle = data.items[0].volumeInfo.title;
                    $('#result').append(bookTitle);
                }).catch(function(error) {
                    $('#result').append(error);
                });
```
上記の部分でやっていることは,

①Fetch APIでPromiseを受け取る
②Promiseが成功すればresolveを失敗すればrejectを呼び出します。(詳しくはわかっておらずすみません、、、）
③resolveならthen,rejectならcatchの処理が行われる
④（resolveだった場合の処理）ここで受け取ったレスポンスの中からJSONを抽出
⑤JSONをdataと定義し、JSONを辿っていきtitleを取得！

といった流れになっています。

#終わりに
自分で書いていて理解が足りていない部分が、よくわかりました（特にPromise)
間違っている点などあれば、ご指摘いただけると幸いです。
【JavaScript】windowオブジェクトとは

#プログラミング勉強日記
2021年2月16日

#windowオブジェクトとは
　画面上に表示されているすべてのオブジェクトの親となるオブジェクトで、JavaScriptのオブジェクト階層の最上位に位置する。ウィンドウに関する情報の取得や、ウィンドウを設定・操作する。

　以下のようにアラートダイヤログを出すこともできる。

```js
window.alert('HelloWorld');
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/b3daf21e-43bf-71ac-7f4d-c8adac8d9149.png)

##`window.`の省略
　`<script>`と`</script>`の間では省略できる。

```html
  <script type="text/javascript">
	window.alert('HelloWorld');
  </script>
```


#windowオブジェクトの種類

| コレクション | 説明 |
|:--:|:--:|
| frames[] | ウィンドウ内の全フレームを取得 |

| プロパティ | 説明 |
|:--:|:--:|
| closed | ウィンドウが閉じられているか調べる |
| defaultStatus | ブラウザのステータスバーに表示するデフォルトメッセージを設定・取得 |
| document | ドキュメントの出力、ドキュメント情報の取得・設定 |
| history | 履歴の移動（戻る・進む）、履歴数の取得 |
| length | ウィンドウ内のフレーム数を取得 |
| location | URL情報の取得 |
| name | ウィンドウ名の取得・設定 |
| opner | 自分自身を開いた親ウィンドウを示す |
| parent | 親ウィンドウ |
| screen | スクリーンサイズの取得・設定 |
| self | ウィンドウ自身を指す |
| status | ブラウザのステータスバーに表示するメッセージを設定・取得 |
| top | トップ |

| メソッド | 説明 |
|:--:|:--:|
| alert() | アラート表示 |
| blur() | フォーカスを外す |
| close() | ウィンドウを閉じる |
| confirm() | 確認ダイアログ表示 |
| clearInterval() | タイマー解除 |
| clearTimeout() | タイマー解除 |
| createPopup() | ポップアップウィンドウ生成 |
| focus() | フォーカスを当てる |
| moveBy()／moveTo() | ウィンドウ位置移動 |
| open() | ウィンドウを開く |
| print() | ウィンドウを印刷する |
| prompt() | 入力ダイアログ表示 |
| resizeTo()／resizeBy() | ウィンドウサイズ変更 |
| scrollBy() | 相対位置にスクロールする |
| scroll() | 指定位置にスクロールする |
| scrollTo() | 指定位置にスクロールする |
| setTimeout() | タイマー設定（指定秒数後に処理を実行） |
| setInterval() | タイマー設定（定期的に処理を実行） |


#参考文献
[windowオブジェクト一覧](https://phpjavascriptroom.com/?t=js&p=window)
[JavaScriptのWindowオブジェクト](http://itref.fc2web.com/javascript/window.html#PROPERTY)
【JavaScript】event.targetとevent.currentTargetの違い

JavaScriptのevent.targetとevent.currentTargetの違いについての記事です。

イベントが発生したときにコールバック関数に渡されてくる`eventオブジェクト`にはイベントに関する情報が格納されている。イベントの発生源となる要素を取得する際、この２つの違いで戸惑ったのでまとめます。

##結論
event.currentTarget : イベントハンドラを登録した要素
event.target : イベントが発生した要素

##実例
[ポートフォリオ](https://portfolio-f4b3a.web.app/)の内容を例とする。
（GitHubは[こちら](https://github.com/watanabedaigo/Portfolio)をクリック）
<img width="500px" alt="代替テキスト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031318/952ba8a3-78b6-0af6-a377-567189035565.png">
ヘッダーに４つのアイコンがあり、アイコンをクリックすると該当する位置までスクロールするようになっている。
HTMLファイルは以下の通り。

```html:index.html
<header class="d-flex justify-content-center align-items-center w-100 header">
    <span class="mr-4 about-icon" v-on:click="scroll"><i class="fas fa-user-alt"></i></span>
    <span class="mr-4 ml-4 skills-icon" v-on:click="scroll"><i class="fas fa-pen"></i></span>
    <span class="mr-4 ml-4 works-icon" v-on:click="scroll"><i class="fas fa-file-code"></i></span>
    <span class="ml-4 contact-icon" v-on:click="scroll"><i class="fas fa-envelope"></i></span>
</header>
```

jsファイルは以下の通り。

```javascript:main.js
const header = new Vue({
    el:'header',
    methods:{
        scroll:function(event){
            switch(event.currentTarget){
                case $('.about-icon')[0]:
                    const about = $('#about').offset().top;
                    $("html, body").animate({ scrollTop: about - 20 }, 200);
                    break;
                case $('.skills-icon')[0]:
                    const skills = $('#skills').offset().top;
                    $("html, body").animate({ scrollTop: skills - 20}, 200);
                    break;
                case $('.works-icon')[0]:
                    const works = $('#works').offset().top;
                    $("html, body").animate({ scrollTop: works - 20 }, 200);
                    break;
                case $('.contact-icon')[0]:
                    const contact = $('#contact').offset().top;
                    $("html, body").animate({ scrollTop: contact - 20 }, 200);
                    break;    
            }
        }
    }
})
```
event.currentTargetでは`span要素`を取得することができ、event.targetではFontAwesomeの`i要素`が取得される。

場合分けをするにあたり、`span要素`を取得できた方が都合が良かったため、今回はevent.currentTargetを用いている。
Linux標準教科書　第4章まとめ

# はじめに
こちらの続きです。
[第1章](https://qiita.com/sasao3/items/730a579f2710660195eb)
[第2.3章](https://qiita.com/sasao3/items/1dca5a44ce9898b178b1)

# 正規表現とパイプ
正規表現はLinuxの様々な処理で使われることが多いため、理解しておくべきとのこと。


## 標準入出力
Linuxプログラムには、「1つの入り口と、2つの出口」がある。
それぞれ、標準入力と標準出力・標準エラー出力である。

![スクリーンショット 2021-02-17 11.46.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/f26f05f8-7a2d-0b04-9472-8e7b130dcba0.png)


標準入力は、プログラムに入ってくるデータのことを示す。標準入力先は一般的にはキーボード。

標準出力は、プログラムの実行結果を書き出す先を示す。あくまでも書き出す先なので実行結果のことではない。
→そのため、***何かコマンドを実行した結果が画面上に表示されることを、「標準出力に出力された」という。***
標準エラー出力は、エラーメッセージを書き出す先のことを示す。
上記二つの出力は、一般的にはプログラムを実行した端末のディスプレイになっている。

## リダイレクト
リダイレクトは、出力の向かう先を変更すること。
Linuxでは、`リダイレクト「>」`を用いて標準出力や標準エラー出力の向かう先を変更することができる。
リダイレクトを用いることで、出力をファイルに書き込むこともできる。

### 出力のリダイレクト
以下はリダイレクトの実行例である。

```
ls > ls-output 
```

上記コマンドを実行すると、ls（参照）の結果が、ls-outputというファイルに記載される。
ls-outputファイルがない場合は、新しく作成される。ls-outputファイルがすでにある場合は、前のls-outputファイルの中身が削除され、新しく作成される。

上書きせず、追記したい場合は、`アペンド「>>」`を使う。

### catコマンドによるファイル作成
catコマンドとリダイレクトを組み合わせることで、自由な内容のファイルを作成できる。
実行例

```
$ cat > cat-output
Hello
This is cat redirect
```

catコマンドとリダイレクトを用いることで、自由にファイルに記載できる。また、入力を終わらせる場合は、`Ctrl + D`で終了できる。
Linuxでは、`Ctrl + D`で入力の終了をする。

## 標準エラー出力
コンピュータを操作していると、様々なエラーが起きることがある。エラーは画面とログに出力される。
エラーメッセージは通常標準出力されるが、リダイレクトを用いて任意のファイルにファイル出力をすることもできる。

```
例）ls -l aiueo 2> ls-l-output 
```

aiueoというディレクトリがない場合、「ディレクトリがないです」という旨のエラ〜メッセージがls-l-outputファイルに出力される。

この「2」というのは標準エラー出力を示している。「1」と指定すると、標準出力になる。
***エラーメッセージを出力したいなら「2」を指定し、プログラムの実行結果を出力したいなら「1」を指定すればよい。***

## パイプ
標準入力からデータを入れることにより、特別な処理ができる。
コマンドとコマンドをパイプ「|」でつなげる（前コマンドの出口と後コマンドの入り口をパイプでつなげる）ことで、コマンド間でデータの受け渡しができる。

そのため、前のコマンドの出力結果を後ろのコマンドの標準入力に渡すことができる。

```
ls -l /user/bin | less
```

`ls -l /user/bin`だけだと、表示されるものが多く全てを表示することはできないが、パイプを用いて`less`とつなげることで、`ls -l /user/bin`の標準出力を`less`の標準入力にできる。

## grepコマンド
grepコマンドは、ファイルの中からデータを検索することができる。
また、先ほどのパイプと一緒に使うことで、標準出力の結果から検索することができる。

書式：`grep [オプション] 検索条件 [指定ファイル]`

検索する上で、ワイルドカードなどを用いることもできるが、検索条件として正規表現が用いられる。

オプション

| オプション | 詳細 | 
|:-----------:|:------------|
| -e       | 文字列を検索パターンとして扱う        |
| -i     |  検索パターンと入力ファイルの双方で、英大文字と小文字の区別を行わない     |
| -v       |  検索パターンとマッチしなかった行を選択する       |

### 正規表現
正規表現で使われる記号と意味

| 記号 | 意味 | 
|:-----------:|:------------|
| ^       | 行頭を表す        |
| $     |  行末を表す     |
| .       |  任意の一字を意味する       |
| *       |  直前文字の0回以上の繰り返しを意味する       |
| [...]       |  ..の中の任意の一字を意味する       |
| [^...]       |  ..の文字が含まれないことを意味する       |
| ¥       |  正規表現の記号をエスケープする       |

使用例
^test　→　testから始まるものを検索
test$　→　testで終わるものを検索
te.t　→　teとtの間に任意の一文字が入っているものを検索
[ab]test　→　aもしくはbに続くもの（atestやbtest）を検索
[^ab]test　→　aもしくはbで始まらないもの（ctest,etestなど）を検索

パイプやオプションを組み合わせると、このようなこともできる

```
grep abc /etc/* | grep -v tcp
```
こちらのコマンドは、/etcディレクトリにある、abcという文字列を含み、tcpという文字を含まないファイルを検索している。

# まとめ
今回は第4章についてまとめました。
ここの章くらいから、普段あまり使ったことのないコマンドがでてきたので、いろいろ触ってみようと思います。
CloudFirestoreのarrayを使ってみる

CloudFirestoreのarrayを使用している記事があまり見つからなかったので、備忘録的に残しておく。

**記載すること**
CloudFirestoreのフィールドのarray型の使い方（今回は追加）

**記載しないこと**
Firebaseのプロジェクトの作り方


下の写真のように`favorite_dog`という配列を作り、その中に、好きな犬の名前を入れていくコードを作る。

![スクリーンショット 2021-02-16 18.46.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998564/a347af97-13f7-2abc-9505-fd1a9cdb2edb.png)

*main.dart*

```dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';


Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Firebaseテスト',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyFirestorePage(),
    );
  }
}

class MyFirestorePage extends StatefulWidget {
  @override
  _MyFirestorePageState createState() => _MyFirestorePageState();
}

class _MyFirestorePageState extends State<MyFirestorePage> {
//配列に追加する関数を作る。
  appendArray() {
    DocumentReference ref = FirebaseFirestore.instance
        .collection('male')
        .doc('h1V6VPae89iMno78IiSP');
    ref.update(
      {
        "favorite_dog": FieldValue.arrayUnion(['犬の名前']),
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: Text('登録'),
              onPressed: () {
                appendArray();
              },
            ),
          ],
        ),
      ),
      // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
```
```dart
ref.update(
      {
        "favorite_dog": FieldValue.arrayUnion(['犬の名前']),
      },
    )
```
updateはmap形式で書きます。

試しに犬の名前を「hachi」とし、`flutter run`し、登録ボタンを押すと、
![スクリーンショット 2021-02-16 18.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998564/941663b2-e3c1-c95f-9aeb-d663f10f8e69.png)


無事に配列の[1]にhachiが格納されました。
なお、配列にすでにある要素については重複して追加はされません。

※参考
https://firebase.google.com/docs/firestore/manage-data/add-data#java_10
【NetCommons3】MacにNetCommons3をインストールしてみた

# MacにNetCommns3をインストールしてみた
私事でNetCommons3を触ることになりまして、いきなり本番環境を触るのが怖かったので手元のMacにインストールしてみました。1年前にもインストールした事があるのですが、そのときはCentOSでほとんど苦労しませんでした。今回はインストールだけで8時間くらい苦戦したので備忘として投稿させていただきます。

## 環境
- PHP 7.2.34
- cakephp 2.10　※2系でないとnc3動きません
- mysql 8.0.23
- NetCommons3.3.3
- mac：Catalina10.15.7、MacBook Pro

## 参考にさせて頂いたページ・資料
- [Macに最初から入っているPHPではintlモジュールが有効化されていないくて少し詰まった話]
(https://qiita.com/nntsugu/items/cd68a614a0ad55513843)
- [MySQLのソケットエラー](https://pentan.info/php/socket_error.html)

- [【MySQL】PHPで接続できないとき SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client](https://motomotosukiyaki.com/mysql-from-php-server-requested-authentication-method-unknown-to-the-client/)

## 手順
- phpのintlモジュールを有効化 ※↑参考ページを参照
- https://github.com/cakephp/cakephp からcakephp2*をzipダウンロードして展開、アクセス確認
- NetCommonsをzipダウンロードして展開、index.php修正、アクセス確認
- apacheでphpとrewriteを有効化
- mysqlでテーブルとユーザを作成、ユーザの認証方式変更
- php.iniの修正 ※デフォルトではソケット通信NG
- NetCommonsのインストール、画面表示に従ってポチポチ

## コンフィグファイル等の抜粋
<details><summary>NetCommons3の直下、index.php　※CAKE_CORE_INCLUDE_PATHを修正</summary><div>

```
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
	//define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
        define('CAKE_CORE_INCLUDE_PATH', ROOT . DS .'vendors'. DS .'cakephp'. DS .'cakephp'. DS . 'lib');
}
```
</div></details>


<details><summary>apacheのhttpd.conf修正</summary><div>

```
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
LoadModule php7_module libexec/apache2/libphp7.so
DocumentRoot "/***/***/www/" #nc3のzip展開後に名前をwwwに変更、ドキュメントルート変更
AllowOverride All #リライトが動かないとnc3で404エラー(not found)が発生
```
</div></details>

<details><summary>my.cnfを修正</summary><div>

```
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
sql_mode=NO_ENGINE_SUBSTITUTION
#pdo_mysql.default_socket=/tmp/mysql.sock　※不要？

[client]
socket=/tmp/mysql.sock
```
</div></details>

<details><summary>php.iniを修正</summary><div>

```
extension=pdo_mysql ;有効化
[Pdo_mysql]
; Default socket name for local MySQL connects.  If empty, uses the built-in
; MySQL defaults.
pdo_mysql.default_socket=/tmp/mysql.sock ;パスを指定
```
</div></details>

## おわりに
投稿するつもりもなく、苦戦したので自分用に記事化しました。記憶を辿りながら書いておりますので間違いがありましたら申し訳ございません。

※後日メモ：nc3でフレームタイトル消すときにいじるファイル
　~~/app/Plugin/Frames/View/Elements/frame.ctp
Kaggle初心者が、AWS（EC2サーバー）を使って画像コンペに挑戦

本記事で、伝えたいこと：
　・AWSで、Jupiter notebookを使ってみる
　・AWSで、GPUを利用して、モデルをトレーニングする
　
本記事が、参考にならない方：
　・AWSのインスタンスを詳しく知りたい方
　・Kaggleのcodeを利用する方


今回、投稿した記事の目的は、画像分類コンペに参加するにあたって、
kaggleのGPU利用制限枠に限界を感じた初心者が、好きなだけGPUを使って、
トレーニングを出来るようになったので、自身のメモ兼、同じように悩んでいる方の参考に
なればと思い、共有させてもらいます。

■ 手順
AWSの日本語チュートリアル通りに行いました。
https://docs.aws.amazon.com/ja_jp/dlami/latest/devguide/what-is-dlami.html

1. GPUの制限緩和
　　まずは、GPUを利用するために、利用制限の緩和を依頼します。

　注意点は、こんなところでした。
　　* リージョンごとに、申請する必要があるため、利用するリージョンで申請する。
　　* 利用目的は、機械学習を行うため。で問題ありませんでした。
　　* 平日の昼間に行わないと、対応が翌日以降になるかもしれません。
　　* スポットインスタンスとインスタンスで、別々の利用制限になっている。
　　　インスタンスの方が、早く対応してもらえる。

2. インスタンスの作成
　　AMIや、コンピュータユニットを設定します。
　
　注意点は、
　　* AMIは、Deep Learning AMIを選ぶと、既に機械学習に必要なライブラリーが
　　　インストール済みで便利。（この時点では、Ubuntu18.04が最新のはずです）
　　　似た名前のDeep Learning Base AMIは、最低限しか入っていないです。
　　* インスタンスタイプは、メモリーや、gpu、ドライブ容量で選択します。
　　　今回は、g4dn.xlargeを利用しました。

3. キーペアの作成、SSH接続
　　キーペアを作成し、ローカルからSSH接続を行います。

　注意点は、
　　* Macならbashから、接続できます。
　　~ % ssh -I 'xxxxxx.pem' user@ec*-*-***-**-**.region.compute.amazonaws.com

4. SSLを証明書発行して、Jupyter notebook起動
　Jupyterの起動は、以下を参考にしました。
　https://docs.aws.amazon.com/ja_jp/dlami/latest/devguide/setup-jupyter.html

5. kaggle APIで、データセットダウンロード
　Kaggle.jsonファイルを利用して、コンペデータをダウンロードします。

6. トレーニング済みのweightをサーバーからダウンロード
　モデルのトレーニングデータをサーバーから、ローカルにダウンロードします。
　ローカルのbashで以下を、実行します。（キーペア名、ユーザー名などは適宜修正）
  scp my.pem user_name download_file_path save_path (@local bash)


参考リンク：
・AWSのチュートリアル
　https://docs.aws.amazon.com/ja_jp/dlami/latest/devguide/what-is-dlami.html

・Kaggle
　https://www.kaggle.com

・AWS
　https://aws.amazon.com/jp/
【コマンドまとめ】Linux/ターミナルの基本コマンド

Linuxやターミナルなどの操作でよく使うコマンドをまとめておきました。
さらに詳しく勉強したい方は以下のサイトにある無料の参考書で勉強してみると良いかと思います！
<a href="https://linuc.org/textbooks/linux/">Linux標準教科書ダウンロード</a>

<h3>【基本コマンド】</h3>
|コマンド  |内容  |
|---|---|
|ls [オプション] [ファイル] |一覧を取得する|
|cp [オプション] コピー元 コピー先 	|ファイルをコピー|
|mv 移動元ファイル　移動先ファイル	|ファイルを移動させる※ファイル名の変更も可能
|rm ファイル名	|ファイルの削除
|pwd	|現在のディレクトリの表示
|cd ディレクトリのパス	|ディレクトリの移動
|mkdir ファイル名	|ディレクトリの作成
|rmdir ファイル名	|空のディレクトリの削除
|cat ファイル名	|ファイルの内容の確認
|find パス -name |ファイル名	ファイルの検索
|which コマンド名	|PATH環境変数配下におけるコマンドのパスを表示
|コマンド　--help	|コマンド実行に使えるオプション表示
|man コマンド名	|マニュアルの表示
|コマンド　> ファイル名	|コマンドの出力結果をファイルに書き込む
|grep [オプション] 検索条件 [指定ファイル]	|ファイル内のデータを検索
|touch [オプション] ファイル名	|タイムスタンプの変更（※ファイルの作成）
|haed [オプション] ファイル名	|ファイル先頭の取得※-fでリアルタイムに
|tail [オプション] ファイル名	|ファイル末尾の取得
|sort [オプション] ファイル名	|データを並び替えて表示
|uniq ファイル	|連続して重複している行を一行にまとめて表示
|tr 文字列1　文字列2	|文字列1を文字列2に置き換え
|diff [オプション]　ファイル1　ファイル2	|ファイル1,2の比較
|sudo [コマンド]	|root権限でコマンドの実行
|chmod [変更内容] [ファイル名]	|ファイルのアクセス権の変更
|./[ファイル名.sh]	|ショルスクリプトの実行
|echo [オプション]　文字列	|引数(変数も可)で与えた文字列を標準出力する
|export 変数名	|環境変数の作成
|env	|環境変数の一覧表示
|set	|シェル変数の一覧表示
|unset 変数名	|変数の削除
|read 変数名	|変数の値を作成・変更
|test [オプション] [ファイル名]	|ファイル属性の確認|

※オプションは毎回”-”付けなくても大丈夫※ダメな場合もある
ex)$ ls -la

<h4>"chmodの8進数表"</h4>
![スクリーンショット 2021-02-16 16.09.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009391/a3926fb6-cf32-14de-2fb7-360593e297fe.png)
参考：linux標準教科書

<h4>【感想】</h4>
<p>初記事あげてみました！記法がMarkDown記法？っていうの知らなくてびっくりです。</p>
<p>もっと綺麗にしたいですが、まずは投稿してみることが大事だと思うので、</p>
<p>今回は雑ですが許していただければと思います</p>
<p>最後まで読んでいただきありがとうございました！</p>
WSL2でRvizやGazeboなどを動かす

## はじめに

WSL2上のUbuntuからWindows上のXサーバーを利用してRvizやGazeboなどを表示させようとすると、Segmentation Faultなどが発生する場合がある。
この記事はその対策についてのメモである。

## 前提

WSL2、Ubuntu、ROS、Rviz、Gazebo等のインストールは済んでいるものとする。

## 検証環境

### ソフトウェア
Windows 10 Pro バージョン 20H2 (OS ビルド 19032.804)
WSL2
Ubuntu 18.04.5 LTS (Bionic Beaver)
ROS Melodic (aptでインストールしたもの)
[VcXsrv](https://sourceforge.net/projects/vcxsrv/) Version 1.20.8.1

### ハードウェア
ALIENWARE m15
Core i7
NVIDIA RTX 2080

## 設定方法

### WSL2上のUbuntu側

`~/.bashrc` に以下を追記して `source ~/.bashrc` する。

```bash

export DISPLAY="`grep nameserver /etc/resolv.conf | sed 's/nameserver //'`:0"
export LIBGL_ALWAYS_INDIRECT=0
```
ここで `export LIBGL_ALWAYS_INDIRECT=0` は `export LIBGL_ALWAYS_INDIRECT=` でも良いようだ。(動作することは確認したが正確な仕様は未確認)

### Windows上のVcXsrvのXLaunch側
XLaunch起動後の画面遷移を順番に貼っていく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/4bc9765e-0a65-af4b-249f-dcf01e887f53.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/1e0116a0-6e42-7365-b41c-64a43ee40a2b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/781e7e99-fe4e-7ff1-e51e-2458e1d9d8d1.png)
`Native OpenGL`のチェックを外す。
`Disable access control`にチェックを入れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/33d16c1f-63c1-9980-e3aa-75c3183811c9.png)

### VcXsrvのWindows Defenderファイアウォールの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/750083a9-9a78-bb20-4cb5-3131a64a1e1c.png)
最低限`パブリック`にチェックを入れること。
恐らくWSL2内とWindowsとの間にはデフォルトゲートウェイが無いので、パブリックネットネットワーク扱いになるのではないかと。

## 動作確認

```bash
$ rviz
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/350c2134-5b97-cb59-9c7e-c9d9a069a7f0.png)

## おまけ。起動に失敗する場合の症状
試しに `export LIBGL_ALWAYS_INDIRECT=1` としてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/a85ebd8a-77c8-774d-c447-fbdba93cc023.png)

試しに `export DISPLAY=` としてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/414be5c2-6b9f-3a25-05cf-d10d9f549095.png)

## 参考
[WSL1からWSL2への移行](http://www.aise.ics.saitama-u.ac.jp/~gotoh/WSL1ToWSL2.html)
【PostgreSQL】一時的に UNIQUE 制約を違反してしまう場合の回避

## はじめに

order という順序を司るカラムがあったとします。
このとき order には NOT NULL 制約 と UNIQUE 制約 がかかっているとします。

| id | order |
|----|----|
| 1      | 1|
| 2      | 2|
| 3      | 3|

↑を↓のように更新したいとします。要は並び替え操作みたいなものですね。

| id | order |
|----|----|
| 1      | 2|
| 2      | 3|
| 3      | 1|


このとき、まずは id が 1 のレコードの order を 2 に更新しようとします。

すると、すでに order が 2 のレコードが存在するため、 UNIQUE 制約に引っかかってしまいますね。

NOT NULL 制約を削除すれば、一旦全て NULL に更新 → 新たに order を設定みたいなことはできますが、

データモデル的には NOT NULL も UNIQUE 制約 もできれば外したくないです。

こういった一時的に UNIQUE 制約を違反してしまう時にどうするかについて書いていきたいと思います。


## SET CONSTRAINTS を使う

SET CONSTRAINTS コマンドは トランザクション内で制約の検査が行われるタイミングを設定できます。

UNIQUE 制約の作成時に SET CONSTRAINTS が有効になるように設定しなければならないので
まずは migration ファイルを作るところから。

まだテーブルを作っていない方はテーブル作成の時に、
すでにテーブルを作ってる方は一旦今の UNIQUE 制約は　DROP して以下の方法で新たに作り直しましょう。

対象の UNIQUE 制約を設定する時に後ろに DEFERRABLE をつけます。
DEFERRABLE は 遅延可能なという意味です。

これによって SET CONSTRAINTS コマンドでトランザクション内で制約検査のタイミングを指定することが可能です。
今回は DEFERRED を使うことででトランザクションの最後に制約検査のタイミングを指定します。

~~~sql:migrationのSQL
ALTER TABLE 対象テーブル ADD CONSTRAINT 制約名(任意) UNIQUE (column, ・・・) DEFERRABLE;
~~~


以下が実際に update を実行する時の SQL です。
このように書くことで、途中でユニーク制約に引っかかってしまうような更新でも、制約の検査はトランザクションの最後で行われるので大丈夫です。

~~~sql:updateのSQL
BEGIN;
  SET CONSTRAINTS 対象の制約名 DEFERRED;
  /* 以下は通常通りの update の SQL を書いていく */
COMMIT;
~~~


## 参考文献

https://www.postgresql.jp/document/11/html/sql-set-constraints.html
【Automation Anywhere】A2019.19 Bot Agentのインストール中に見慣れない画面？

A2019を初めて使うときの手順を、以下の動画で紹介しています。

[【外部リンク】Youtube：A2019を始めよう！アカウント登録から初めてのBot作成まで！](https://youtu.be/L4G0k-ad0LU)

上記の動画の撮影時は、A2019.18(ビルド7560)が最新版だったとのことですが、A2019.19でBot Agentをインストールしてみたところ、.18以前にはなかった画面が表示されることがわかりました。

戸惑う人もいるかもしれないので、ここにメモを貼っていきます。

#以下の画面が表示されたら……

2つのボタンのいずれかを選ばないと進めませんが、選択の基準は以下のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/34593c0b-5663-9077-f4a2-483c806d6156.png)

図中に書いてある「Unattended Bot Runner」がピンと来ない人もいるかもしれませんが、こちらは「スケジュール実行など、無人で起動する用の実行ライセンス」のことです。

当該端末ではBotを開発するだけ（Runnerとしては使わない）で、別にユーザーを限定する必要もないな～というときは、どちらを選んでも大丈夫です。

どちらかを選択するとInstallボタンが活性化するので、ボタンを押すと、あとは動画で案内しているとおりの手順で進める……かな？

あっ！！　もうひとつありました。　↓↓

#デバイスのログイン情報を聞かれたら

上記の画面の先で、デバイスのログイン情報を聞かれる場合があるかもしれません。

「デバイスのログイン情報って何？？」と思った方は、以下の記事をチェックしてみてください。

[【リンク】A2019「デバイスのログイン資格情報」って何？　調べ方・設定方法](https://qiita.com/IQ_Bocchi/items/0b75e2e3aabc74c5084b)

では！
NextCloudの外部ストレージとしてConoHaのオブジェクトストレージを使う

# はじめに
この記事はNextCloudの**外部ストレージ**としてConoHaオブジェクトストレージを使う手順というか方法を記した記事になります。

NextCloudのインストール方法などの説明はありません。
すでにインストールができている前提で解説を進めます。
インストールがまだの場合や、ConoHaオブジェクトストレージに契約してない場合は、他のサイトを参考にしてインストール、契約をしてください。

Nextcloud: 20.0.7

# External storage supportをインストールする
NextCloudのアプリから「External storage support」というアプリをインストールします。
若しくは有効にします。

これで、S3などを外部ストレージとして使うことができます。

# 設定を入力する
設定の「外部ストレージ」からフォルダ名を適当に入力して「OpenStack ObjectStorage」を選びます。
OpenStack v2を選んで、設定の項目を入力していきます。
一番上から「Object Storage Service」「tyo1」「何でもいい」「なんでもいい」「APIのユーザー名」「APIのパスワード」「テナント名」「 https://identity.tyo1.conoha.io/v2.0 」とします。
/tokensは必要ありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201995/1a9a66e2-7aa1-fe7b-dfcb-a8020456661e.png)

これで完了...というわけではなく、エラーが出ます。

# phpファイルを編集する
`lib/private/Files/ObjectStore` へFTPなりSFTPなりでアクセスします。
そこにある、`SwiftFactory.php`をダウンロードします。

SwiftFactory.phpを適当なエディタで開きます。

62行目にこのような記述があります。

```php:SwiftFactory.php
//...
//62行目ぐらい
	public const DEFAULT_OPTIONS = [
		'autocreate' => false,
		'urlType' => 'publicURL',
		'catalogName' => 'swift',
		'catalogType' => 'object-store'
	];
```

この`'catalogName' => 'swift',`を`'catalogName' => 'Object Storage Service',`に書き換えます。

書き換えたら、先程の場所(`lib/private/Files/ObjectStore`)に上書きアップロードします。

これで、再度設定すると、今度はエラーなく通るはずです。

追記1)
ConoHaオブジェクトストレージだけにしか使わない場合は、こちらでいいと思いますが、他のObjectStorageとかのやつに使えなくなると思います。
他で使う予定がある場合は、おすすめしません。

追記2)
NextCloudのアップデートがある毎に書き換える必要があります。

# 原因を考える
APIの結果の一部分がこちらです。

```json:tokens
{
    "endpoints": [
        {
            "region": "tyo1",
            "publicURL": "https://object-storage.tyo1.conoha.io/v1/nc_<
テナントID>"
        }
    ],
    "endpoints_links": [],
    "type": "object-store",
    "name": "Object Storage Service"
},
```

おそらくですが、NextCloudでは、APIの結果を『「object-store」で検索をして「swift」と引っかかったものを使う』的な処理をしているんだと思います。

ですが、ConoHaのAPIの結果は「Object Storage Service」なので、エラーが出て使えない...っていうことだと思います。

# スペシャルサンクス
* ConoHaのサポートに投げて「トークン発行するリンク(項目名は「認証エンドポイント」のリンク違うよ」と教えてくれたサポートの人
* 拙い文章だけど読んでくれた人
Laravel 8 初めて使う(2)

## Starter Kits
ログイン認証系のアプリが2つ用意してあるよ
* Laravel Breeze
* Laravel Jetstream
Breezeで要領掴んでから、Jetstream使ってねって書いてある

## Laravel Breeze
### Installation
まず、.envにてデータベースの設定を済ませておく
インストールまでは済んでいるのでこれだけ

```
php artisan migrate
```
migrationのファイルは、database/migrationsに最初から入っている
多くの場合ここでエラーが出る
usersテーブルの、ストリングユニークキーが作れないというエラー

```
$table->string('email')->unique();
```
この辺りを読んで、Schema::defaultStringLength(191)の対応をしてしまう
https://qiita.com/beer_geek/items/6e4264db142745ea666f
失敗テーブルを巻き戻して、テーブル作成

```
php artisan migrate:rollback
php artisan migrate
```
認証アプリインストール

```
composer require laravel/breeze --dev
php artisan breeze:install
npm install
npm run dev
```
こんなエラーが出たら、nodeをアップデートして再度npm run dev
`Error: You are using an unspported version of Node. Please update to at least Node v12.14`

ブラウザーで/dashboardにアクセスして確認する
登録ログインが動くことでしょう
![スクリーンショット 2021-02-16 18.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72911/868e2317-6340-d336-330a-0b880ae9c854.png)
Laravel 8 初めて使う(1)

## 公式サイトをチェック  
https://laravel.com/
Documentation ぽちー
## Getting Started  
Installation いい流れ  
Why Laravel どうでもいい  
On macOS, On Windows
### On Linux  
Docker is already installed、コンテナで上がっちゃう
### Installation Via Composer  
これにしておく

```terminal
composer create-project laravel/laravel example-app  
cd example-app
php artisan serve (httpサーバーが上がるやつね）
```
ブラウザアクセスしてみるが、ページ開かない。

## Configuration  
いっぱい書いてある、ここで行き詰まる（笑  
何もしないで次へ進んで大丈夫だったりする。  
## Directory Structure  
ログが書き込めないと言ってくるので、下記対応する。  
https://qiita.com/engulisyu/items/ad819d06ea0cd31411df  

画面でた！
![スクリーンショット 2021-02-16 16.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72911/23b45ef5-6d08-e22c-7935-3790e1f3f3f4.png)
matplotlibで日本語化 2021年2月

# matplotlibで日本語化

これでいけました

```
!pip install japanize_matplotlib
import japanize_matplotlib
```


色々、悩んだ挙句、いじり過ぎて悲惨なことになっている方は、こちらもしてみると良いかもしれません。

```
import seaborn as sns
sns.set(font="IPAexGothic")
japanize_matplotlib.japanize()
```

<hr>
**japanize_matplotlib**
https://pypi.org/project/japanize-matplotlib/