OmniAICreator/Qiita-1.07M huggingface dataset:
OpenCV aruco用のARマーカの生成

OpenCVのarucoライブラリで使用されるarマーカーは以下のサイトで簡単に作成することができます.

https://chev.me/arucogen/

サイトを開くと下の写真のようなサイトが表示されます.お好みの辞書(4*4,5*5,6*6,7*7)とマーカーID,マーカーサイズが設定できます.

![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/67ef63e8-15f4-6d27-1a52-e7f5d0f278cf.png)


- 作成テスト1 サイト上の`open`文字からpdf化して,印刷 →
(100mm*100mm)のマーカが(97mm*97mm)くらいで出力された

- 作成テスト2 サイト上の`open`文字からpdf化時に設定を、`余白`: なし,`倍率`を`カスタム`を`100%`に設定

![Screenshot from 2022-09-05 11-47-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/c9c28195-3366-95bd-ed0a-e863bca2cb4e.png)


- 作成テスト3 サイト上の`open`文字から`プリンター`を選択。選択時に設定を、`余白`: なし,`倍率`を`カスタム`を`100%`に設定。

100mm*100mmのマーカーができた

印刷する際に倍率を変えない設定をするのが大事

- 作成テスト4 サイトから`svg`で保存したものを開いて,印刷。倍率100%,余白無しなど設定したが、出力マーカはち

# 追記

コンビニなどで印刷できる最大サイズの用紙はA3だそうで、そのサイズは,297x420mm

30cm x 30cm くらいのARマーカーが作れる

それより大きいサイズは、A3を複数枚使用するなどする or 大判サイズのコピーができる印刷会社などへ依頼が必要
gh コマンドを使って簡単にツールをインストールするスクリプトを書く

[gh コマンド]([https://cli.github.com/](https://cli.github.com/)) は GitHub release からダウンロードする機能があります。これを使って、自動で特定のバージョンのツールの binary をダウンロードするような、簡易的なツールのインストーラーを簡単に書くことが出来ます。

## gh release download の使い方

[https://cli.github.com/manual/gh_release_download](https://cli.github.com/manual/gh_release_download) を見れば大体わかります。

コマンドラインオプションで、リポジトリやダウンロード先を指定できるので、以下のような渡し方をすることで GitHub からのダウンロードツールとして使うことが出来ます。

```bash
# https://github.com/kubernetes/kops/releases/tag/v1.19.1 から kops-darwin-amd64 を tmp にダウンロードする
gh release download -R kubernetes/kops v1.19.1 --pattern 'kops-darwin-amd64' -D "./kops"
```

## どう使うと便利か

自分は、以下のような、「開発で利用するツールをその場でダウンロードして実行する」スクリプトを書いて使っています。

```bash
#!/bin/bash

set -eu

KOPS_VERSION=v1.19.1

cpuarch() {
  case `uname -m` in
    "x86_64" )
      echo "amd64"
      ;;
    "aarch64" )
      echo "arm64"
      ;;
  esac
}

download-kops() {
  local tempdir=$(mktemp -d)
  local OS=$(uname -s | tr '[:upper:]' '[:lower:]')
  local ARCH=$(cpuarch)

  echo "Downloading kops $KOPS_VERSION ..."
  gh release download -R kubernetes/kops $KOPS_VERSION --pattern "kops-$OS-$ARCH" -D $tempdir
  test -d ./kops/$KOPS_VERSION || mkdir -p ./kops/$KOPS_VERSION
  mv $tempdir/kops-$OS-$ARCH ./kops/$KOPS_VERSION/kops
  chmod +x ./kops/$KOPS_VERSION/kops
  echo "Downloaded kops $KOPS_VERSION"
}

# kops がダウンロード済みでなければ https://github.com/kubernetes/kops からダウンロードする
test -x ./kops/$KOPS_VERSION/kops || download-kops

# ダウンロードした kops を実行
./kops/$KOPS_VERSION/kops $@
```

こういうスクリプトを Git リポジトリのディレクトリ (`bin/` など) に置いておく、ということは自分はよくやっています。これにより、

- 複数人の開発で、個々人のセットアップの手間が小さくなる
    - version が固定されているので、version のブレによる違いが起きにくい
    - 元のツールのラッパーのように使うので、version の指定を変更した場合も更新漏れが起きにくい
- CI でのセットアップも行いやすい
    - GitHub Actions では gh コマンドがインストール済みなので、基本的にそのまま使える
- `bin/` のツールを使う習慣を作っておくと、チーム固有の環境設定などをここに投げ込みやすい

というメリットがあります。

自分は現職ではインフラチームに所属しているのですが、日々の開発では様々な CLI ツール (terraform, terraform-docs, kops, velero, etc) を利用しているのですが、いわゆる *env 系のツールがないツールも多く、個々のツールをチームに導入する際に環境構築がハードルになることもあるので、最近ではこういうスクリプトを用意するようにしていて、重宝しています。

## ※ curl を直接使う場合との違い

一応似たような事は curl を使って書くことが出来ます。(Ref: [https://qiita.com/wf9a5m75/items/39528ae6dda687190a3d](https://qiita.com/wf9a5m75/items/39528ae6dda687190a3d)) 

ただし、gh を使う方が、スクリプトとして記述がシンプル、分かりやすくなるメリットがあります。

- curl よりもコマンドラインの見た目が直感的になる
- エラー処理、認証用の token を渡す部分等を記述しなくて良くなる
- download するファイルを pattern で記述できるので曖昧な指定が可能になる
VOICEROID2の音声データをHTTP経由で取得する

## はじめに

自分のPCにインストールしてあるVOICEROID2の音声データ(wav)をVOICEROIDエディタを使わずにHTTP経由で取得できるようにしたいと思います。
HTTP経由で取得できるようにすることで、VOICEROID2の音声を他のプログラムから容易に呼び出すことが可能になります。

## 必要なもの

* 音声データを作成したいVOICEROID2キャラクターの正規ライセンス (公式サイトにてライセンスをご購入ください）
    * +ExはVOICEROID2へのインポートプログラムをインストールすることで使えるようになります。
* [Ebyroid](https://github.com/nanokina/ebyroid)

## VOICEROID2のインストール

通常の手順に従ってVOICEROID2をインストールしてください。エディタで読み上げてくれることが確認できればOKです。
※なお、これ以降の作業においてエディタを起動させておく必要はありません。

## Ebyroidのインストール

[Releaseページ](https://github.com/nanokina/ebyroid/releases)にパッケージ化されたzipファイルがおいてあるので、解凍します。
解凍したフォルダをPowerShellで開き、自分の環境にあわせて適宜設定をします。  

```powershell
PS C:\ebyroid-v0.2.0\ebyroid-v0.2.0> .\ebyroid.exe configure
? Which version of VOICEROID do you use? VOICEROID2
? Is your VOICEROID installed in "C:\Program Files (x86)\AHS\VOICEROID2"? Yes
? Which voice library do you like to use? tsuina_44
? Give an unique name to this voiceroid settings! tsuina
? Add one more settings for another voiceroid? No
? Which one of the voiceroids should be used as default? tsuina
Writing to "./ebyroid.conf.json"...
```

完了すると、同じフォルダに`ebyroid.conf.json`というファイルが生成されます。

## Ebyroid起動

以下コマンドでEbyroidを起動させます。

```powershell
PS C:\ebyroid-v0.2.0\ebyroid-v0.2.0> .\ebyroid.exe start
Loading config from JSON file...
Loaded 1 voiceroid(s): tsuina
Use "tsuina" as default...
Starting up the server, with port 4090...
Server started! - http://localhost:4090/
```

## 音声データの取得

ブラウザを開いて、http://localhost:4090/api/v1/audiofile?text=こんにちは とアクセスすると、設定したキャラクターの音声で「こんにちは」としゃべってくれると思います。
もし何もしゃべらない場合、`ebyroid.exe`が停止している可能性があるので、プロンプトを確認してください。落ちていたら再度コマンド実行で起動すると思います。

## Ebyroidの改造

これでHTTP経由でデータの取得が可能となりますが、このままだとlocalhostでしかアクセスできなかったり、音声のスピードや抑揚を変更したりできません。
そこで、Ebyroidを改造して、localhost以外からのアクセスだったり、音声を変更したりできるようにしました。

ビルドしてパッケージ化したものは、[こちら](https://github.com/omatztw/ebyroid/releases)に置いてあります。

こちらのビルドを用いれば、以下のような形で音声のチューニングが可能になります。
http://localhost:4090/api/v1/audiofile?text=こんにちは&speed=1.2&pitch=0.5&range=0.8

（この修正はとても雑なので出来れば本家で対応して欲しいなぁ:bow: 

## Ebyroidのサービス化

毎回Ebyroidをコマンドで立ち上げるのは大変なので、Windowsのサービス化をしましょう。
Windowsのサービス化には[NSSM](https://nssm.cc/)を使えばOKです。
以下のように設定すればWindowsのサービスとして登録することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115363/094d1f96-c694-f34f-8849-0b6e92a8da64.png)


## (参考) Voiceroid Daemon

HTTP経由で音声データを取得できるようにするツールとして、[voiceroid_daemon](https://github.com/Nkyoku/voiceroid_daemon)というものがありますが、私の環境ではうまく動作しませんでした。
動作させることができるなら、こちらでも問題ないと思います。

## まとめ

Ebyroidを利用してVOICEROID2の音声データをHTTP経由で取得できるようにしました。
VOICEROID2はDLL(aitalked.dll)をたたくことで操作できるため、基本的にはDLLが読み込める言語であればどの言語からでも操作可能です。ただし、それぞれの言語でAPIのラッパーを作成していくのは大変なので、このようにHTTPアクセス可能にしておくことでどんな言語からでも比較的簡単に操作できるようになります。

## 注意事項

* 生成した音声データを配布したり、HTTPサーバーを外部公開することはライセンス違反となる可能性がありますので、利用規約をよく読み遵守するようにしてください。
* 規約違反かどうか判断ができない場合は公式に問い合わせてください。
node.jsのインストール

#結論
nvmを利用しましょう。node.jsを直接インストールすることもそりゃできますが安定バージョンを簡単に取得できるnvmは最強です。ということで、nvmのインストールを解説するよ。

#nvmのインストール

```
$curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
```
##node.jsの安定バージョン

```
$ nvm install stable --latest-npm
$ nvm alias default stable
```

node.jsをインストールすれば一緒にnpmもインストールされてるはずです。念の為最新バージョンにアップデートしておきましょう。

```
$ npm update -g npm
```

#起動

```
$node
```
これでnode.jsをインストールできれば完了です。

#パッケージのインストール
パッケージをインストールするためにはまずinitで初期化処理が必要となります。これはパッケージがどのようなものがインストールされているかなど管理すつためのものだそうです。package.jsonファイルが作成されます。間違って消しちゃわないように。

```
$npm init
```

適当に書き込みを終えてから適当にパッケージをインストールしてみましょう。

```
$npm install socket.io
```
などどうでしょうか。ともかく何かしらインストールしてみて確認してみましょう。
何をインストールしているのかを確認には以下のコマンドです。

```
$npm list
```
#おすすめのパッケージ

```
$npm install express-generator -g
$express -e
$npm install
```
とすることでディレクトリ構成とnode.jsでwebサイトを作る雛形を作成することができます。最後のインストールでは、express-generatorを使う上で必要なパケージがインストールされます。

以上です。
yum updateに失敗したのでshow-leavesを無効化

## 概要

CentOS 7にて`yum`でのupdateやinstall, removeに失敗する。
エラーメッセージは`_rpm.error: invalid header data`。

結論から言うと、`yum`のoptionに`--disableplugin=show-leaves`をつける。それでもだめなら`--noplugins`をつける。


## この方法が有効な場合

失敗時のエラーメッセージが次のようなものでした

```
$ yum update
(略)
Traceback (most recent call last):
  File "/bin/yum", line 29, in <module>
    yummain.user_main(sys.argv[1:], exit_code=True)
  File "/usr/share/yum-cli/yummain.py", line 375, in user_main
    errcode = main(args)
  File "/usr/share/yum-cli/yummain.py", line 281, in main
    return_code = base.doTransaction()
  File "/usr/share/yum-cli/cli.py", line 817, in doTransaction
    resultobject = self.runTransaction(cb=cb)
  File "/usr/lib/python2.7/site-packages/yum/__init__.py", line 1818, in runTransaction
    self.plugins.run('pretrans')
  File "/usr/lib/python2.7/site-packages/yum/plugins.py", line 188, in run
    func(conduitcls(self, self.base, conf, **kwargs))
  File "/usr/lib/yum-plugins/show-leaves.py", line 40, in pretrans_hook
    _old_leaves = _get_installed_leaves(conduit)
  File "/usr/lib/yum-plugins/show-leaves.py", line 34, in _get_installed_leaves
    for po in conduit.getRpmDB().returnLeafNodes():
  File "/usr/lib/python2.7/site-packages/yum/rpmsack.py", line 1296, in returnLeafNodes
    return [ self._makePackageObject(h, mi) for (h, mi) in ts.returnLeafNodes(headers=True) ]
  File "/usr/lib/python2.7/site-packages/rpmUtils/transaction.py", line 176, in returnLeafNodes
    for p in _return_all_provides(h):
  File "/usr/lib/python2.7/site-packages/rpmUtils/transaction.py", line 168, in _return_all_provides
    for prov in hdr[rpm.RPMTAG_FILENAMES]:
_rpm.error: invalid header data
```

そこで、`yum`コマンドに`--disableplugin=show-leaves`をつけるとうまく動いた

```
yum update --disableplugin=show-leaves
```

それでもだめなら全てのプラグインを無効にしてみよう

```
yum update --noplugins
```

## うまくいかなかった対処法

webを調べているとよく見つかる対処法で、次のようなものがあるが、何度やっても解決しなかった。
ただ、環境によっては有効かもしれないのでメモしておく。

```
rm -rf /var/lib/rpm/__db*
rpm --rebuilddb
yum clean all
yum update
```

## 感想

いまいち詳しくないので、こういうエラーが出ると平気で半日潰れてしまいます。つらい気持ちになります。
RedHat8でCtrlキーを半角全角キーに設定する

vim /usr/share/X11/xkb/symbols/jp

以下の行を
key <CAPS> { [ Eisu_toggle, Caps_Lock ]     };

以下にする
key <CAPS> { [ Zenkaku_Hankaku	] };

再起動後に反映される。
※ログアウトしてログインするだけでも反映する情報もあったが、試していない。
Mac上のVisual Studio CodeにおいてCtrl+kでカーソル位置から行末までカットする

# Mac上のVisual Studio CodeにおいてCtrl+kでカーソル位置から行末までカットしてCtrl+yでペーストする．

EmacsやzshなどEmacsキーバインドが使える環境ではCtrl+kでカーソル位置から行末までカットし，Ctrl+yでペースト（ヤンク）できることが多いです．しかし，Visual Studio CodeではCtrl+kで削除はできてもペーストはできません．いろいろ調べたところ，MacrosというExtentionを使うことで実現できそうです．手順は次のとおりです．

1. Visual Studio Codeを立ち上げMacrosというExtentionをインストールする．
2. settings.jsonに次のコードを記入します．

        "macros": {
            "cutLines": [
                "cursorEndSelect",
                "editor.action.clipboardCutAction"
            ]
        },
このコードはカーソル位置から行末まで選択しカットするマクロになります．

3. keybindings.jsonに次のコードを記入します．

        { "key": "ctrl+y", "command":"execPaste", "when":"editorTextFocus"},
        {
            "key": "ctrl+k",
            "command": "macros.cutLines",
            "when": "!editorHasSelection"
        },
Ctrl+kで2で作成したマクロが呼ばれることで，カーソル位置から行末まで削除しクリップボード保存されます．Ctrl+yでペーストします．
Node.js? Express? yarn? ナニソレ

##はじめに
現在，Expressでポートフォリオを作成している大学4回生です．
ポートフォリオ作るにあたっていろいろ調べまくったのでまとめます．

###※注意
* 環境構築に関する記事ではありません．
* これを読んだからといって何を得るわけではありません

##Node.js?
JavaScriptで開発をしている(目指している)方で聞いたことのない方はいないと思いますが，実際Node.jsって何者なんでしょうか？
ずばりNode.jsとはサーバーサイドで開発するためのJavaScript実行環境です！！！
ん?どゆこと？って人はひとまずソーナンダーって思ってください．これを使うことで色々便利なことがあるんです．
###-使う理由
ではなぜブラウザで動くただのJavaScriptではなくNode.jsを使うのでしょうか．だって書くのは同じ言語なのに
先程も説明した通りNode.jsはサーバーサイドのJavaScript実行環境なのでブラウザで動くものより色々自由度が上がるんです．例えばファイルを読んだり，書き込んだりする際ブラウザ上のコードではできません．
なぜならそんなことができてしまうと，あるページにアクセスした際に情報が盗まれてしまうからです．でもそんな制限がある中で開発なんてできるわけありませんよね？ そこでそんな制限をとっぱらったものがNode.jsなんです！！
スゴイデスヨネー
ちなみにnode.jsのバージョン管理やインストールにはnvm(Node Version Manager)を使って入れます．

##Express？
でもNode.jsを使って開発するゾーってなっても，ん？なにから書けばええんや？ってなりません？
そこでありがたいのがExpressというフレームワークです．
ところでフレームワークって何者なんですかね．
日本語で言うところの骨組み。。。プログラミングで使う骨組みってなんだ？
ずばり，基本的にみんなが共通して使うような機能をまとめて，コードを書き易くしてくれるものです．

##yarn(ヤーン)？
※嫌って意味ではありません．(いやーんっていうボケです．はい．流してください）
yarnの前にnpmの話をしましょう．
npmとはNode Package Managerの略でNode.jsで使えるライブラリの管理やインストール、アンインストールなどをしてくれるもので、yarnはnpmの上位互換みたいなものでとりあえずyarnを使っておけば大丈夫そです．

###まとめ
* Node.jsはJavaScriptの実行環境
* Node.jsのバージョン管理はnvm(Node Version Manager)
* Expressはフレームワーク
* yarnはnpmの上位互換

##以上！！
Moment.jsを用いて今月が何週あるのか（今日が第何週か）を求める

#内容
moment.jsを使い、今月が何週あるのかを求めました。
ついでに、「今日が月の第何週か」も求めます。
参考でピッタリハマるものがなかったので、備忘録として残します。

追記として、puppeteer用いたカレンダーのループ処理を記述予定です。

#対象

・年の第何週かではなく、月の第何週かを出したい方
・moment.jsを使う方
・初心者の方

#目的
やりたかったことは、今月のカレンダーのループ処理を書くことでした。
具体的には、「2021年3月1日〜2021年3月31日の1ヶ月の日毎の会計データを全件取得する」が目的です。つまり、毎日の会計処理データをすべて取得するというものでした。

ループ処理を記述する該当のカレンダーは、Xpathを使用して選択する方法で行いました。

```
//対象のカレンダー：2021年3月9日のXpath
~/div/table/tbody/tr[2]/td[3]/div
=> ~/div/table/tbody/tr[月の第2週目]/td[日曜始まりの週で３日目]/div を表している
```
カレンダーの復数のXpathを復数見比べてみると`tr[]`の部分で月の週番号を表しており、`td[]`の部分で1週間のうち何日目かを表しているのが分かったので、その2点をfor文で処理を書けば良いと判断出来ます。

###インストール
早速、moment.jsのインストールから使う準備までを行います。

```
$ npm install moment.js
```

使用するJavaScript(app.jsなど)のページ内、上部に以下を記載。

```
const moment = require('moment');
```
これでmoment.jsを使うことが出来ます！

#やったこと

###必要だったのは情報は3つ
1. 今月は第何週あるか
2. 月初の週は何日あるか
3. 月末の週は何日あるか


月初を求める式を、文章で表すと以下の通りです。
★ 今月は何週あるか = 月末の週番号(年間の第何週) - 月初の週番号(年間の第何週) + 1 

moment.jsは月の第何週を求める関数は無いので、年間の週を使って求められます。
2021年3月では、 5週 ＝ 14 - 10 + 1　と表せます。

####1. 今月は第何週あるか
実際に書いていきます！

```javascript

//今月の月初と月末の日付を求める
var startOfMonth = moment().startOf('month');
var endOfMonth = moment().endOf('month');

//月初と月末の年の週番号を求める
var startOfMonthOfWeekNum = moment(startOfMonth).format('w');
var endOfMonthOfWeekNum =  moment(endOfMonth).format('w');

// 今月は何週あるか = 月末の週番号（年間の第何週） - 月初の週番号（年間の第何週） + 1 
var targetWeekNum = endOfMonthOfWeekNum - startOfMonthOfWeekNum + 1;
```

moment.jsには簡単に年始や月初や月末などが簡単に求められる`startOf`, `endOf`を使用します。上段で求めた日付を使用し、中段で`moment(対象の日付).format(w)`を使い、年の何週目かを求めます。下段では、文章で表した式にあてはめ、今月が何週あるのかを求められます。　※変数名は適宜変更してください！

####2 , 3 . 月初・月末は何日あるか

月初・月末は1週間のうち何日あるのかを、曜日番号を使って求めます。

```javascript

//月初、月末の曜日番号を求める
var dateStartOfMonth = moment(startOfMonth).weekday();
var dateEndOfMonth = moment(endOfMonth).weekday();
```
`moment(対象の月).weekday()`で簡単に曜日番号が求められます。ただ、moment.jsを使った曜日番号は(0〜6)なので`tr[ ]`に入れて繰り返し処理を行う際は、+1をすることで対応します。

###ちなみに今日が月の第何週目か
★ 対象の日付の週番号 = 対象の日付の年週番号 - 対象の日付の初月の年週番号 + 1
2021年3月9日の場合　2 週目 = 11 - 10 + 1

```javascript

//今日の日付を求める
var today = moment();

//今日が年で何週目かを求める
var todayOfYearOfWeekNum = moment(today).format('w');

//今日が月の何週目かを求める
var todayOfMonthOfWeekNum = todayOfYearOfWeekNum - startOfMonthOfWeekNum + 1;
```

これで、今日（対象の日付）が何週目かを求めることができました。

#まとめ
今月が何週あるのか。また、月初・月末は曜日番号はバラバラ（毎回7日間あるわけではない）だったので、これをどう解決するかに悩みました。振り返ってみればなんてことないですが、JavaScriptを初めてまだ2週間も経っていなかったのでつまずきました.....

####スクレイピングの分岐記述
ここまでで、目的であったmoment.jsを用いた今月の週番号を取得するができました。
次回はいよいよfor文やif文を用いた条件指定の繰り返し処理を書こうと思いますが、長くなるかつ理解していない部分があるので時間がかかる予定です。あしからず.......

#参考
・[Moment.js(公式サイト)](https://momentjs.com/)
・[全61件！Moment.js日付フォーマット実例](https://blog.capilano-fw.com/?p=908#_8-10)
・[[PHP]対象の日付が月の何週目なのかを調べる](https://www.kabanoki.net/3686/)
・[[Javascript] Moment.jsを使って日付を扱おう](https://www.yoheim.net/blog.php?q=20180201)

以上
VScodeでインデントが出来なくなった

# ある日

VScodeで　
急に　インデントが出来なくなりました👼


ポップアップが出てきたので読んでみました。


![4928F1CA-3CA3-4EA5-918F-065B82FA8504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/2d9c834f-dc50-c91c-4f65-7f4fe640be38.png)



The Prettier extension will use 'node_modules/prettier/index.js' for validation, which is installed locally in folder 'プロジェクト名'. 
Do you allow the execution of this Prettier version including all plugins and configuration files it will load on your behalf? 

Press 'Allow Everywhere' to remember the choice for all workspaces. Deny Allow Allow Everywhere



Prettier拡張機能は、検証に「node_modules / prettier / index.js」を使用します。
これは、フォルダー「プロジェクト名」
にローカルにインストールされます。 代わりにロードするすべてのプラグインと構成ファイルを含む、このPrettierバージョンの実行を許可しますか？  [すべてを許可]を押して、すべてのワークスペースの選択を記憶します。 どこでも許可を拒否許可


# 無事


Allow を選びました。


インデント出来たーー！
【BigQuery初心者の雑記 vol.2】 MySQL との違いに戸惑う

株式会社オズビジョンのユッコ (@terra_yucco) です。
FF14 再生零式、ボズヤ零式全部終わったので業務に更に精が出る今日このごろ。

前回 [【BigQuery初心者の雑記 vol.1】BigQuery Scripting で集計バッチ要らず](https://qiita.com/terra_yucco/items/a56a1242cee2289c0212) では、PHP+MySQL という従来どおりの作り方をしていたら大変そうだった処理が、BigQuery Scripting でなんとかしたら比較的簡単に作れてしまったという話を書きました。
実はまだこの集計要件は続いており、日々 BigQuery とまだお付き合い中なので、MySQLとの違いに戸惑ったりした点と対応策をメモしておきます。(将来の自分へ)

# 前提

相変わらず既存データを力技で集計しています。
ただし中間を全部すっ飛ばして最終結果だけ集計すると、ロジックにミスが有っても見つけられないため、かなり細かく処理を切って中間テーブルに結果を保存していっています。(正規化なにそれ？)

なのでテーブルの設計変更がかなり頻繁に発生している。

# テーブル操作編
## 設計変更でテーブルを RENAME したい

- rename できない

```sql 
ALTER TABLE xxx RENAME TO yyy;
-- ALTER TABLE does not support RENAME TO action
```

- 同じ構造のテーブルが作れない
    - GUI からはテーブルをコピーできるのでそれで対応

```sql
CREATE TABLE xxx LIKE yyy;
-- CREATE TABLE LIKE is not supported at [1:44]
```

- 結局以下のように対応
    - 例えば hoge_dataset.xxx から hoge_dataset.yyy に変更する場合

```sql
-- GUI で xxx から yyy にコピー
-- データを一部変更する場合などは
INSERT INTO hoge_dataset.yyy
SELECT hoge,
       'xxx',
       fuga,
       ...
  FROM hoge_dataset.xxx;
```

# データ操作編
## 値の変換だけさせたい

- DUAL は使えないが、FROM 句を使わなければいい

```sql 
SELECT CASE WHEN CURRENT_DATE = '2021-03-16' THEN TRUE ELSE FALSE END FROM DUAL;
-- Table name "DUAL" missing dataset while no default dataset is set in the request.

SELECT CASE WHEN CURRENT_DATE = '2021-03-16' THEN TRUE ELSE FALSE END;
-- True
```

## group_concat がしたい

- 対応した型じゃないとそれはそれで怒られる

```sql

SELECT STRING_AGG(target_date)
  FROM hoge_dataset.xxx;
-- No matching signature for aggregate function STRING_AGG for argument types: DATE. Supported signatures: STRING_AGG(STRING); STRING_AGG(STRING, STRING); STRING_AGG(BYTES); STRING_AGG(BYTES, BYTES) at [2:1]

SELECT STRING_AGG(CAST(target_date AS STRING))
  FROM hoge_dataset.xxx;
-- 2021-03-15,2021-03-14,2021-03-16
```

## テーブルの中身を全件消したい

- DELETE には WHERE が必須

```sql
DELETE FROM hoge_dataset.xxx WHERE 1 = 1;
```

また思いついたら書いていきます。
pythonでタプルを直接比較してみる

ふと気になったのでメモ。
環境は macOSX10.15.7 + pyenv + python3.8.3です。


解決方法としては以下の通りでしょうか。
まあロジック自体見直したほうがよいと思います。

- `set()`でうまいことやる
- ループでやる
- `__lt__` とか `__gt__`を再実装する

---


#### 双方のリストが同値のとき
```
>>> a = (100, 200, 300)
>>> b = (100, 200, 300)
>>> a == b
True
```
これはまあ当然。

#### リストの要素数が異なるとき
```
>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 100)
>>> a > b
True
```
これも当然。


#### リストの値が異なるとき
```
>>> a = (100, 100, 100, 100)
>>> b = (200, 100, 100, 100)
>>> a < b
True

>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 100, 200)
>>> a < b
True
```
値の位置関係は特に関係がなく、想像通りの返り値が得られた。

```
>>> a = (100, 200, 100, 100)
>>> b = (200, 100, 100, 100)
>>> a < b
True

>>> a = (100, 200, 200, 200)
>>> b = (200, 100, 100, 100)
>>> a < b
True
```
と思いきや、先頭に近い要素のほうが支配的っぽい。

```
>>> a = (100, 100, 100, 100)
>>> b = (200, 200, 200)
>>> a < b
True

>>> a = (100, 100, 100, 100)
>>> b = (200, 100, 100)
>>> a < b
True

>>> a = (100, 100, 100, 100)
>>> b = (100, 100, 200)
>>> a < b
True

>>> a = (100, 100, 100, 100)
>>> b = (200, 100)
>>> a < b
True

>>> a = (100, 100, 100, 100)
>>> b = (200, )
>>> a < b
True
```
要素が少ないことよりも、比較できうる要素同士の結果のほうが優先らしい。

```
>>> a = (100, 300, 300, 300)
>>> b = (200, )
>>> 
>>> a < b
True
```
なんでやねん


#### ロジックどうなってるの？
調べてみたところ、リストやタプルに対して比較演算を行ったときは、下記のような処理になっているみたいです。
間違っていれば指摘(あるいは編集リクエスト)いただけると嬉しいです。

1. 要素を双方からひとつ取り出す
1. 値を比較する
    -  同値の場合: 1に戻る
    -  同値ではない場合: 3に進む
    -  どちらかが空の場合: 空のほうにマイナス無限大を挿入し、3に進む
    -  両方が空の場合: 双方にマイナス無限大を挿入し(？)、3に進む
    -  比較できない型同士の場合: TypeErrorを送出する
1. 演算子に対応した真偽値を返却し、処理を終了する


ちなみに公式ドキュメントを見てみてもフワッとしか書かれておらず、やらないほうがいいっぽい雰囲気を感じます。
https://docs.python.org/ja/3/reference/expressions.html#comparisons
>比較の結果が等価となる2つのコレクションは、同じ型、同じ長さ、対応する要素どうしの比較の結果が等価でなければなりません (例えば、 [1,2] == (1,2) は型が同じでないので偽です)。
>順序比較をサポートしているコレクションの順序は、最初の等価でない要素の順序と同じになります (例えば、 [1,2,x] <= [1,2,y] は x <= y と同じ値になります)。 対応する要素が存在しない場合、短い方のコレクションの方が先の順序となります (例えば、 [1,2] < [1,2,3] は真です)。
【メモ】scikit-learnの決定係数の範囲を確認しました

* 製造業出身のデータサイエンティストがお送りする記事
* 今回はメモとして、scikit-learnの決定係数$R^2$の取り得る範囲について整理しました。

##はじめに
過去に[評価指標](https://qiita.com/DS27/items/2204b10888a19869e083)については整理しておりますが、今回は決定係数の取り得る範囲について確認しましたので、メモとして残しておきます。

##決定係数
決定係数$R^2$では、推定された回帰モデルの当てはまりの良さを評価します。
[scikit-learn](https://github.com/scikit-learn/scikit-learn/blob/0fb307bf3/sklearn/metrics/_regression.py#L499)の計算式は下記の通りです。

```math
\begin{eqnarray}
R^2 = 1 - \sum \frac{(y_i - \hat{y_i})^2}{(y_i - \bar{y})^2}
\end{eqnarray}
```

$y_i$ : $i$番目サンプルの実測値
$\hat{y_i}$ : $i$番目サンプルの予測値
$\bar{y}$ : 実測値の平均

##決定係数の取り得る範囲を確認してみた
scikit-learnのExamplesを参考に決定係数の取り得る範囲を実際に確認してみました。

```php
from sklearn.metrics import r2_score
y_true = [1, 2, 3, 4]
y_pred = [1.1, 2, 3, 3.9]
r2_score(y_true, y_pred)
#0.996

y_true = [1, 2, 3, 4]
y_pred = [3, 2.5, 3, 4]
r2_score(y_true, y_pred)
#0.15000000000000002

y_true = [1, 2, 3, 4]
y_pred = [100, 2.5, 3, 4]
r2_score(y_true, y_pred)
#-1959.25
```

決定係数$R^2$は、あまりにも精度が悪いと大きなマイナスの値を取るんですね。実際に確認できると、今後、関係者へ説明する際に自信持って言えますね。
ksnctf #7 Programming

#Programming
[問題](https://ksnctf.sweetduet.info/problem/7)

Programming：プログラミング

問題をみると、[program.cpp](https://ksnctf.sweetduet.info/q/7/program.cpp)がある。
拡張子からc++で書かれたプログラムかなと思ったけど、見てみると全然違った。

```:program.cpp
#include   	 	<stdio.h>    
	
     	#include  	  <string.h>	
	
  int   	  	main		 
	()
   {   	const		char 	* 
s	=
 "     	    " 
"0123456789"	
"     "
	
"		   "
"			         							  				 			 "    	  
	 "ABCDEFGHIJ" 	;
	 printf	(
   	  "%c"	,		strlen 
(s)	
 );  int  i	  =	020000000	+	001000000	+
000600000	
  +000040000
+000007000
+000000500
+000000020
+000000002  	;
   	  	printf		(	
	"%s"
     	,&  	 i		
	)
;        	 	 
	long
    long 
			   							  				 		 	 					 l
	  =	 
 	
  2LL   		 
	    *
 	11LL
     	 		
	  	 *
 	229LL
     		 
	    *
 	614741LL
     		   
	    *
 	9576751LL
     		 	 
	  	 +
 	5LL
     	 	   
	    
 	;
     		  	
	  	 
 	printf
     	  	  (
	  "%s"  
 	
     	    ,	 
	  	 
 	
    & 	    
	    
 	
     		l	 
	    
 	
    ) 			 
	    
 	
     		 		;
	  	 
 	
    float 	 	
	    
 	
     	f		 =	
	    
 	
     1.0962664770776731080774868826855754386638240000e-38f	  
	  	 
 	
     ;	  
	    
 	
     printf(		"%s"	  
	  	 
 	
     	 ,		 
	    &f
 )	
    ; 	   	 
	double  	 
 	
d     		 			=
	6.7386412564254706622868098890859398199406890000e-308  	 
 ;	
  printf
("%s"
,&d);
}
```

includeとかint mainとか、printfとかc言語っぽのが書かれているけど、
もちろんそのままコンパイルして実行してみてもダメ。

これは**[WhiteSpace](https://ja.wikipedia.org/wiki/Whitespace)**という言語で書かれたプログラムらしい。難解プログラミング言語の１つで、スペースとタブだけで構成されていてそれ以外の文字はコメント扱いになる。

[ここ](https://vii5ard.github.io/whitespace/)で実行できる。「WhiteSpace online compile」とかで調べたら出てくる。

ソースコードをコピペして右のdebugの[Run]をすると![スクリーンショット 2021-03-16 19.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182752/98403537-7638-f795-cbca-14608473973a.png)
readiで処理が止まっていて、outputに書かれているPINの入力待ち状態になる。PINの値はわからない。右のdebugを見てみると、readiの2行下に「push 33355524」と書かれており、とりあえずこの値をPINとして入力してみる。PINを入力したら再び[Run]を押して実行するとFLAGが得られた。

#まとめ
スペースとタブでのみで書かれた言語があることに驚いた。
難解プログラミング言語はなんのために作られたのだろうか。
UNIX~ショートカットキー~

ここではUNIXのショートカットキーについてまとめていきます。

＊control+c▶次のコマンドに移ることができます。
＊control+a▶コマンドの頭に戻ります。
＊control+e▶コマンドの尻に戻ります。
＊control+u▶途中まで打ったコマンドをクリアします。
＊control+k▶カーソルの位置から右側のコマンドを消します。
＊control+W▶ワード単位で消してくれます。

ファイル系の長いの打ちたくないなってときのショートカットキー
＊↑▶１つ前の入力内容を出してくれる。
anyenv経由でいれたnodeを完全に消したい

anyenv経由でインストールしていたnodeですが、
いろいろあってnvm経由でいれることになったので、nodeをアンインストールすることになりました。

### 解決法

```bash
# nodenvのアンインストール
anyenv uninstall nodenv

# anyenvの削除
rm -rf $(anyenv root)

# bashrcの戻し
vi ~/.bashrc
# npmなどで追加したものを手動で削除
```

自分は以下で囲まれた部分を削除しました。

```bash
###-begin-npm-completion-###
###-end-npm-completion-###
```
環境変数が読み込めない【Next.js】

# 問題
Next.jsを用いたプロジェクト内で以下のように環境変数を参照しようとしても参照できない(特にエラーメッセージなし)

```:.env
VAL=sample
```

```React
// 環境変数VALを表示
console.log(process.env.VAL);
```

# 解決方法
変数名を`NEXT_PUBLIC_~`としていないのが原因でした。

`VAL`を`NEXT_PUBLIC_VAL`と変更すると解決できました。

詳細は[こちら](https://nextjs.org/docs/basic-features/environment-variables)

```:.env
NEXT_PUBLIC_VAL=sample
```

```React
// 環境変数VALを表示
console.log(process.env.NEXT_PUBLIC_VAL);
```
pkg-configのパッケージ名の取得

__pkg-config__コマンドで、指定できる__パッケージ名__が分からないとの質問がきたので、パッケージ名の取得方法を記事にしておきます。

pkg-configコマンドで、簡単にパッケージ名の一覧が取得できます。

```
pkg-config --list-package-names
```

pkg-configの情報を全部、取得したい場合は、--list-allで取得できます。

```
pkg-config --list-all
```

何故か? 二回づつ出てくる!?
多分、__--cflags__と__--libs__の2回分だと思う。
Vue.jsにGoogleAnalyticsを導入

#概要
SPA化したVue.jsにGoogleAnalyticsを導入したので手順をメモします。
vue-analyticsを利用しました。

##環境
Vue.js 2.5.17
vue-analytics 5.22.1

#実装
##前提
Googleアカウントを持っていて、プロパティを作成し終えていること。

こちらを参考にさせていただきました。
[Googleアナリティクスでサイトを追加（プロパティ作成）する方法](https://www.sakurasaku-labo.jp/blogs/google-analytics-add-new-site)

##手順１　vue-analyticsインストール
https://github.com/MatteoGabriele/vue-analytics

```
npm install vue-analytics
```

##手順１ GoogleAnalyticsのプロパティIDをコピー
GoogleAnalyticsにログインします。

ヘッダーから対象のプロパティを選択→「UA-XXXXXXX」のIDをコピーします。


##手順２　実装
私は全てのページに適用させたかったのでvue-routerに実装しました。

```router.js
import VueAnalytics from 'vue-analytics'

const router = new VueRouter({
  mode: 'history',
  routes: [
  //省略
  ],
})
Vue.use(VueAnalytics, {
  id: 'UA-XXXXXXXX',
  router
})

```

```.js
Vue.use(VueAnalytics, {
  id: 'UA-XXXXXXXX',
  router
})
```

このIDのところに先ほどコピーしたIDをペーストします。

#まとめ
GoogleAnalyticsを開いて確認してみるとしっかりと接続されていました。
【CSS】first-letterで最初の位置文字を指定する方法

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

#first-letterとは
　ブロック要素の最初の文字にスタイルの要素を適用できる疑似要素である。

```css:first-letterの使い方
要素名(.クラス名):first-letter{
  /*適用したいCSSスタイルを記述*/
}
```

##サンプルプログラム

```html:sample.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>sample</title>
  <link rel="stylesheet" href="sample.css">
</head>
<body>

<p>Sample</p>

</body>
</html>
```

```css:sample.css
p:first-letter{
  color:#5bc0de;
  font-size:300%;
}
```

表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/5ce08977-de60-b13a-ed2e-5aef41cb31e6.png)

#first-letterのメリットとデメリット

##メリット

- コードの量を減らしてデザイン性を高められる
- 多くのブラウザに対応する


　HTMLをspan要素などで複雑にすることなく、スタイルを統一できる。first-letterは昔からある要素なので昔のブラウザでも使用することができる。

##デメリット
　デメリットというデメリットではないが、注意しなければならない点がある。

- ブロック要素にしか効かない
- 利用可能なCSSのプロパティが限られている

　最初に説明したように、インライン要素やインラインブロック要素のようなブロック要素以外では適応しないので注意が必要である。また、背景や色、マージンやパディングやボーダーなどの簡単なスタイルは使えるが、ディスプレイ要素の変更や位置の調整はできない。なので、そういう場合はspan要素で囲ってCSSを適応するのが望ましい。

#参考文献
[::first-letter (:first-letter)](https://developer.mozilla.org/ja/docs/Web/CSS/::first-letter)
[CSSだけで見出しや文章の一文字目をスマートに装飾する方法](https://cunelwork.co.jp/blog/web/first-letter-is-smart/)
[CSSでfirst-letterを使って最初の一文字を指定する方法【初心者向け】](https://techacademy.jp/magazine/9363)
【SSMS】SQL Server Management Studioでサーバーの接続情報を保存する

## はじめに
SQL ServerでSQL Server Management Studio (SSMS)を使用して、サーバーの接続情報を保存する「サーバー登録」について、画像付きで紹介します。

本記事では、SSMS バージョン17.9を利用しています。

## サーバー登録方法

### 1. 登録済みサーバーウインドウを表示する
メニューの[ 表示 ]から**[ 登録済みサーバー ]を選択**します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385044/d7d5b3c7-d539-ee7c-86f9-13ec8d1614ad.png)

### 2. 新しいサーバーグループを登録する
登録済みサーバーウインドウが表示されたら、
[ データベースエンジン ] → [ ローカルサーバーグループ ]を展開し、
[ ローカルサーバーグループ ]を右クリックして、**[ 新しいサーバーグループ ]を選択**します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385044/484da093-93b9-b2a1-6f8e-e7f95d36b3f2.png)

立ち上がったウインドウにグループ名とグループの説明を入力します。
グループの説明は入力しなくても構いません。
ここでは仮に「develop」としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385044/4549465a-f137-409d-1416-4f87261181c0.png)


### 3. 新しいサーバーを登録する
先ほど作成した新しいサーバーグループを右クリックし、**[ 新規サーバーの登録 ]を選択**します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385044/fab2ef29-ac13-127b-13cc-f9281e9538c8.png)


**[ サーバー名 ]、[ 認証 ]、[ ログイン ]、[ パスワード ]をそれぞれ入力し、保存**をクリックします。
ここで保存する前に[ テスト ]を押すことで、パスワード等が合っているか確認することができます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385044/a6731225-9914-ed12-fdf1-2f80a124bc87.png)

これで完了です。
dockerを起動すると.envがnot directoryと言われる

# エラー

`docker-compose up -d`でdockerを起動しようとすると，

```
Encountered errors while bringing up the project 
...（中略）... not a directory ...
```
のようなエラーがでました．

要約すると，.envがディレクトリではなくファイル形式になっているよという内容のようでした．

たしかに.envをディレクトリにすると直るのですが，ファイル形式でないと環境変数などが記述できず意味がない…

# 解決方法
一度イメージごと削除して再起動したら直りました．
（ただの`docker-compose down`では直りませんでした）

```
# イメージごと削除する
docker-compose down --rmi all
```

```
# 起動
docker-compose up -d
```
さくらVPSのCentOS7でMongoDBのEnterpriseを始める話

#初めに
MongoDBのインストールからユーザー認証の設定までしちゃいます。タイトルがなんとも限定的になってはいるものの、別にさくらVPSでなくともCentOS7をインストールされているものであれば同じような動作をすることができると思います。
###前提
・CentOS7をインストールしている。

#MongoDBのインストール
現在、2021年の３月１６日現在に公開されてる最新のドキュメントを参考に進めていきます。[公式のドキュメントはこちら](https://docs.mongodb.com/manual/installation/)
まず最初にMongoDBのCommunityとEnterpriseの2つのサーバーエディションのどちらを選ぶか選択します。

以下の海外のサイトを参考にCommunityとEnterpriseを比較すると、EnterpriseはCommunityに比べてセキュリティ面で優れており、デメリットが特に内容に見えたのでとりあえず自分はEnterpriseをインストールしました。
>https://developpaper.com/comparison-table-of-mongodb-community-version-and-enterprise-version/

一応この記事では両方のインストール方法を書いておきます。
##Communityのインストール
↓参考にさせていただいた公式
>https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/#overview

```
$sudo vim /etc/yum.repos.d/mongodb-org-4.4.repo

[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc
```
CentOS7ガチ初心者さんがいないとも限らないので、:wで保存、:qでvimコマンド終了であることを注釈しておきましょう。

```
$sudo yum install -y mongodb-org
```
以上のコマンドを打つとインストールされます。質問されることがあれば、全部yとしておけばインストールは完了されるはずです。

##Enterpriseのインストール
↓参考にさせていただいた公式
>https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-red-hat/

```
$sudo vim /etc/yum.repos.d/mongodb-enterprise-4.4.repo

[mongodb-enterprise-4.4]
name=MongoDB Enterprise Repository
baseurl=https://repo.mongodb.com/yum/redhat/$releasever/mongodb-enterprise/4.4/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc

$sudo yum install -y mongodb-enterprise
```
以上のコマンドでインストールは完了です。

#インストールしてから
何事にもソフトウェアとは開始させなければ開始しません。

```
$sudo systemctl start mongod.service
$sudo systemctl status mongod.service
```
２つ目のコマンドで無事activeと表示されていればOKです。
お試しに

```
$mongo
```
とコマンドをうってみればmongodbが起動するはずです。
起動されてなければstatusでエラーのヒントが出ているはずなので、それにそって頑張って修正してみてください。頑張れ！

それから、そのままmongoシェルの中で

```
>show dbs
```
と確認しておいてください。何か表示されたことを覚えておくだけでいいです。

#ユーザー認証
自分が１ヶ月ほど悩み通したところです。わかってみれば簡単なことでしたので、それほど構えなくとも大丈夫な簡単なところです。

```
$mongo
>use admin
switched to db admin
> db.createUser({user:"自分で", pwd:"決めてね", roles:["root"]})
>exit
$
```
ユーザー管理用のスーパーユーザーを作成します。userの名前に悩むようであれば、安直に'admin'などに仮設定してみればどうでしょうか。

```
$vim /etc/mongod.conf

#securiity:
  authorization: enabled
↑ここ注意！スペース２個分だけです！
```
スペースはタブでもいいかとpython思考で入力していれば一ヶ月どっかの誰かさんのようにどこにも問題のない迷路に迷うことになるので注意ですね。まったく！どこの誰でしょうね！

```
$sudo systemctl restart mongod
```
リスタートして

```
$mongo
```
で普通に起動すればとりあえず一安心。

```
>show dbs
```
で何も表示され内容になっていれば問題なしです。

```
>exit
$mongo -u 自分の設定したユーザー名
```
その後、パスワードが求められるので先程入力した通りに入力しましょう。
入ってから

```
>show dbs
```
と入力して４つほど表示されればスパーユーザー作成は成功です！
お疲れ様でした！
[Rails] Bootstrapを使ってHerokuにDeployするとBootstrapが反映されない

#参照
https://qiita.com/1024xx4/items/56172d140d7208230e32

#起こっていること
Rails6でHerokuにデプロイしたところBootStrapが効かなかったのですが解決できたのでメモとして残しておきます。ちなみに開発環境では最初から正常に動いていました。

#環境
Ruby 2.6.6
Rails 6.0.3

#手順
##1.RailsにBootstrap/jQueryを追加する
bootstrapやjqueryを追加するために下記のコマンドを入れます

```
yarn add jquery bootstrap popper.js
```

##2.`app/javascript`に`stylesheets/application.scss` を追加

```:app/javascript/stylesheets/application.scss
@import '~bootstrap/scss/bootstrap';
```

##3.`app/javascript/packs/application.js`に以下を追加

```:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

// 新規追加
import 'bootstrap';
import '../stylesheets/application';
```

##4.最後に`app/views/layouts/application.html.erb`の一部を修正します
```
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
```

---
以上で`git push heroku master`でしっかりとBootStrapが効いていました。私の原因としては
最後の手順のapplication.html.erbに`<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>`が記述されていなかったのが原因でした。この違いで何が変わったのかは正直のところわかりません。
お詳しい方、ご教授くださると嬉しいです。
Ubuntu 20.04 LTS DNS設定

# Ubuntu 20.04 LTS環境での DNSリゾルバ設定

resolveconf のスタブリゾルバを働かせたくない場合の設定方法

## DNSを固定してしまう
例えばGoogle DNS(8.8.8.8)

```
$ systemd-resolve --set-dns=8.8.8.8 --interface=enp0s25
```
その後、適宜再起動・設定確認する。
```
$ systemd-resolve restart
$ systemd-resolve --status
```

## resolvconf をアンインストール
乱暴だがこれでも解決する。

```
$ apt purge resolvconf
```

後にresolv.confにnameserverを通常通りDNSアドレスを記述する。
メモリ使用量の確認方法

Visual Studioのパフォーマンスプロファイラーで、簡単に（HLAppの）メモリ使用量を確認することができます。

# 手順

## 1. パフォーマンスプロファイラーを起動

Visual Studioの**デバッグ > パフォーマンスプロファイラー**を選択して、**Azure Sphere Memory Usage**をチェックした後、**開始**ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/20f8b284-1e56-9047-a454-33f6218ae039.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/0f419467-9fe1-1367-10d2-dca7e43e7aa9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/1817b461-454f-da9d-bee2-31f243fd6176.png)

## 2. アプリをデバッグなしで開始

Visual Studioの**デバッグ > デバッグなしで開始**を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/7a085080-d694-4a4d-f6c1-049a75dda725.png)

# 結果の見方

User列がHLAppのメモリ使用量です。
Peak User列はHLAppのメモリ使用量のピーク値です。
（Total列はOSのメモリ使用が含まれるので参照する必要はありません。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/993c2f67-af21-a5cf-3761-2bd7bfd30e1b.png)

# 補足

デバッグ有りでHLAppを実行（デバッグの開始）した場合は、User/Peak Userにデバッガー（GDB Server）のメモリ使用も加算されるため、参考になりません。

現在のAzure Sphere(MT3620)は、HLAppで使用できるメモリは256KBです。User/Peak Userがこの値以下になるようにしてください。（HLAppが上限以上にメモリを要求すると、SIGKILLが発生します。）

# 参考

* [Memory use in high-level applications @Microsoft Docs](https://docs.microsoft.com/en-us/azure-sphere/app-development/application-memory-usage?WT.mc_id=IoT-MVP-5002686)
IBM Power Systems Virtual ServerでLPAR間のネットワークを有効にする

IBM Cloud上でAIXやIBM iを使えるIBM Power Systems Virtual Serverについての記事です。

Power Systems Virtual Serverは、デフォルトでは異なるLPAR間の通信が無効になっています。
下記docsにあるように、Caseを起票し、LPAR間のルーティングを有効にしてもらう必要があります。この作業は各サブネットに対し、初回のみ必要となります。
　
https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-configuring-subnet&locale=ja#networking-considerations

>Power Systems Virtual Server インフラストラクチャーでプライベート・ネットワークを構成するには、Power Systems Virtual Server に対するサポート・チケットを開く必要があります。 例えば、ユーザー・インターフェースからサブネット 172.10.10.0/24 を追加し、そのサブネットに接続した仮想サーバー・インスタンス間で通信が必要な場合は、サポート・チケットを開き、ユーザー・インターフェースに表示された以下のサブネット情報を入力する必要があります。

今回の例では、AIX1が192.168.1.0/24、AIX2が192.168.2.0/24に配置されていて、その間を疎通させたいとします。

#静的経路の設定

まず、AIX側の設定として、それぞれのAIX上で、相手のセグメントへの静的経路を追加します。

```:AIX1
Destination        Gateway           Flags   Refs     Use  If   Exp  Groups
192.168.2/24       192.168.1.1       UGS       0         6 en1      -      -  
```

```:AIX2
Destination        Gateway           Flags   Refs     Use  If   Exp  Groups
192.168.1/24       192.168.2.1       UGS       0        34 en1      -      -   
```

# case起票

次に、管理ポータルで、各AIXサーバーの詳細画面の下部にある、プライベートネットワークの情報をcaseで伝えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/b87dfe62-5748-2a62-9d90-8faec20f3877.png)

疎通させたいAIXの情報を、下記のような感じでcaseで伝えます。

```
Can you make it possible to communicate between these two AIXs?

AIX Name / Subnet Name  / IP address / Gateway / MAC address / VLAN ID  / CIDR
aix-tmgw01 / subnet01 / 192.168.1.58 / 192.168.1.1 / fa:55:f6:05:86:21 / 376 / 192.168.1.0/24
aix-tmgw02 / subnet02 / 192.168.2.231 / 192.168.2.1 / fa:07:2d:fd:36:21 / 377 / 192.168.2.0/24
```

Power VSのサポートスタッフが対応してくれると、LPAR間が疎通するようになっています。

```:AIX1
# ping 192.168.2.231          
PING 192.168.2.231 (192.168.2.231): 56 data bytes
64 bytes from 192.168.2.231: icmp_seq=0 ttl=253 time=0 ms
64 bytes from 192.168.2.231: icmp_seq=1 ttl=253 time=0 ms
64 bytes from 192.168.2.231: icmp_seq=2 ttl=253 time=0 ms
```

なお、以下のようなケースでも、同様にcaseでリクエストする事で間を疎通するようにできます。

・2台の配置されたサブネットが同じ場合
同じサブネットにあってもデフォルトでは疎通していないため、上記と同様にcaseでLPAR間の疎通を有効にしてもらうよう依頼する必要があります。（サブネットが同じ場合は各AIXでの静的経路の追加は不要です）

・2台のAIXが、同一リージョンの異なるPower VSインスタンスにある場合
この場合も、caseで依頼し、各AIXで静的経路を設定する事で、疎通可能になります。
【発展】お気に入りに登録を非同期にしよう！

前回の記事の発展的な内容にになります。

https://qiita.com/mitaninjin/items/3a8b364c7cd13b961d83

上記のお気に入り機能が実装されている前提で話を進めていきます。

#####完成イメージ
![62d5738ed5b4bfc18a736c19712cff74.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140333/ac0245a6-9371-abd9-54ac-01475db71d27.gif)

##ビューファイルの編集
link_toメソッドに**remote: true**を追加します。

```erb:app/views/recipes/show.html.erb
#中略
<% if current_user != @recipe.user %>
  <div class="recipe-like">
    <% if @recipe.liked_by(current_user).blank? %>
      <%= link_to "お気に入りに保存", recipe_likes_path(@recipe), method: :post, remote: true, class: "btn btn-success btn-sm" %> #編集
    <% else %>
      <%= link_to "保存済み", recipe_like_path(@recipe,@recipe.liked_by(current_user)), method: :delete, remote: true, class: "btn btn-outline-success btn-sm" %> #編集
    <% end %>
  </div>
<% end %>
#以下略
```

##コントローラーの編集
redirect_toから**respond_to**に変更します。
respond_to :jsと記述することによってjs形式でレスポンスを返すようになり、<font color="Red">app/views/コントローラ名/アクション名.js.erb</font>が出力されます。

```ruby:app/controllers/likes_controller.rb
class LikesController < ApplicationController

  def create
    @like = current_user.likes.build(like_params)
    @recipe = @like.recipe
    if @like.valid?
      @like.save
      respond_to :js #編集
    end
  end

  def destroy
    @like = Like.find(params[:id])
    @recipe = @like.recipe
    if @like.destroy
      respond_to :js #編集
    end
  end
```

##js.erbファイルの作成、編集
respond_to :jsで出力するファイルを作成していきます。

```:ターミナル
touch app/views/likes/{create.js.erb,destroy.js.erb}
```
それではcreate.js.erbから編集してきましょう。

.recipe-likeでclassを取得し[.html](http://alphasis.info/2011/10/jquery-api-html-htmlstring/)の()内のHTMLに置き換えます。

```javascript:app/views/likes/create.js.erb
$('.recipe-like').
html('<%= link_to "保存済み", recipe_like_path(@recipe,@recipe.liked_by(current_user)), method: :delete, remote: true, class: "btn btn-outline-success btn-sm" %>');
```
同じ要領でdestroy.js.erbも編集します。

```javascript:app/views/likes/destroy.js.erb
$('.recipe-like').
html('<%= link_to "お気に入りに保存", recipe_likes_path(@recipe), method: :post, remote: true, class: "btn btn-success btn-sm" %>');
```

以上で実装完了です。
それでは挙動を確認してみましょう。
![62d5738ed5b4bfc18a736c19712cff74.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140333/ac0245a6-9371-abd9-54ac-01475db71d27.gif)
多群間の比率の検定

多群間での比率の検定では、~~分散分析のように、まずは「全体として群間で比率に差があるか」を検定する。
その結果が有意であるならば、さらに、下位検定として比率の検定の多重比較を行う。~~

(2021/3/17)
https://www.jstage.jst.go.jp/article/kagakutoseibutsu/57/10/57_571007/_article/-char/ja
上記の文献によると、必ずしも全体としての検定をする必要はないようです。


以下はその例。

```r
L1 <- 22
L2 <- 26
L3 <- 43
U1 <- 11
U2 <- 40
U3 <- 23

#まず全体としての比率の差をテスト
#fisher.test(matrix(c(L1,L2,L3,U1,U2,U3),ncol=2,byrow = T))

#続いて多重比較
library(RVAideMemoire)
fisher.multcomp(matrix(c(L1,L2,L3,U1,U2,U3),ncol=2,byrow = T))
```

結果

```r
#> fisher.test(matrix(c(L1,L2,L3,U1,U2,U3),ncol=2,byrow = T))
#
#	Fisher's Exact Test for Count Data
#
#data:  matrix(c(L1, L2, L3, U1, U2, U3), ncol = 2, byrow = T)
#p-value = 0.001586
#alternative hypothesis: two.sided
#
> fisher.multcomp(matrix(c(L1,L2,L3,U1,U2,U3),ncol=2,byrow = T))

        Pairwise comparisons using Fisher's exact test for count data

data:  matrix(c(L1, L2, L3, U1, U2, U3),2,T)

         A       B
B 0.001421       -
C 0.082826 0.08283

P value adjustment method: fdr
```
【Rails】assert_matchの使い方

<h2>assert_match</h2>

Railsテストで使うメソッドで、第一引数の正規表現の値と第二引数の値がマッチすれば成功になるメソッドです。

第三引数にメッセージを設定すると、失敗時のメッセージを指定できます。(指定は任意です)

また、HTMLを評価する際に、assert_selectではタグを指定する必要がありますが、assert_matchではタグを指定する必要がありません。

````ruby:assert_match
#基本構文
assert_match(正規表現, 文字列 [, メッセージ])

#HTMLを評価するときの使い方(Railsチュートリアル第13章より)
assert_match @user.microposts.count.to_s, response.body

```



<h2>参考</h2>
Rails ドキュメント
https://railsdoc.com/test

Ruby STUDIO Railsのテスト
http://ruby.studio-kingdom.com/rails/guides/testing#2
[Rails][環境構築]rails newを実行すると「gyp: No Xcode or CLT version detected!」が発生

#参照
https://qiita.com/dmrt/items/90ad12850c0ed29758a2

https://qiita.com/baby-0105/items/18f6fbc073e160bf83ac
#環境

macOS Catalina 10.15.7
yarn 1.22.10

#エラー内容
railsでプロジェクトを新規作成しようとしたところ以下のエラーが発生、正常にプロジェクトを作成できませんでした。

```
$ rais new
gyp: No Xcode or CLT version detected!
gyp ERR! configure error 
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/Users/dmorita/.nodebrew/node/v10.15.2/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:345:16)
gyp ERR! stack     at ChildProcess.emit (events.js:189:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
gyp ERR! System Darwin 19.3.0
gyp ERR! command \"/Users/dmorita/.nodebrew/node/v10.15.2/bin/node\" \"/Users/dmorita/.nodebrew/node/v10.15.2/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js\" \"rebuild\"
gyp ERR! cwd /Users/projects/XXXX/client/node_modules/watchpack/node_modules/fsevents
gyp ERR! node -v v10.15.2
success Saved lockfile.
✨  Done in 156.15s.
```

yarnではXcodeが見つからないとしてsuccessの表示が出てしまうのですが、yarnやnpmあたりに不具合が起こるので解消していきます。

#解決方法
今回は２つの方法を紹介していきたいと思います。
私は２つを実行してみて両方のやり方で解決できました。
一つの方法はディレクトリ削除を行うので両方見た上で良いと思った方を試してみることをお勧めします。

###方法１
`xcode-select -print-path`を実行し現在Xcodeが参照しているパスを確認

```
% code-select -print-path
/Applications/Xcode.app/Contents/Developer
```

ふむふむパスは合っているのになぜか動かないな、、色々悩みながら記事を探していたところどうやら
`/Library/Developer/CommandLineTools`のディレクトリが悪さをしている模様。なのでそのディレクトリを削除してから`xcode-select --install`を実行し解決完了


###方法2
`xcode-select -print-path`を実行し現在のパスを確認

```
% xcode-select -print-path                    
/Applications/Xcode.app/Contents/Developer
```
もう一つのやり方はステップ１で削除した`/Library/Developer/CommandLineTools`
にパスを切り替える方法です。(削除する前に実行してください)

```
% sudo xcode-select -switch /Library/Developer/CommandLineTools
```
`sudo`コマンドでパスを切り替えました。そしてもう一度`xcode-select -print-path`を実行

```
% xcode-select -print-path
/Library/Developer/CommandLineTools
```

#解決！
この状態でもう一度`rails new`コマンドを叩くと

```
% yarn
yarn install v1.21.1
info No lockfile found.
[1/4] 🔍  Resolving packages...
warning nuxt > @nuxt/webpack > @nuxt/babel-preset-app > core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > vuex-class@0.3.2" has unmet peer dependency "vue@^2.5.0".
warning " > vuex-class@0.3.2" has unmet peer dependency "vuex@^3.0.0".
warning " > vuex-class@0.3.2" has unmet peer dependency "vue-class-component@^6.0.0 || ^7.0.0".
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 150.13s.
```
プロジェクトは正常に作れました。
今回は２つの解決方法を紹介しましたが`/Applications/Xcode.app/Contents/Developer`
と`/Library/Developer/CommandLineTools`のパスの違いでどのようなことが起こるかは正直不明です。わかる方いたら教えていただけると幸いです。
AWSでCloudWatch Logsのフィルター後のURLの作り方




## やること
CloudWatch Logsのフィルタリング後(filter pattern)入力後のURLを生成

## 環境
python 3.8
aws

## 背景
CISベンチマークに関するアラート通知を作った。
AWS公式ドキュメントに記載のある、フィルタリング条件で、CloudWatch Logsでフィルタリング後のURLを通知したかった。
https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-cis-controls.html

## やってみた

実際に[CIS3.1](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-cis-controls.html#securityhub-cis-controls-3.1)を例にやってみる。
CloudWatchLogsには検索文字列、開始日時、終了日時の３つを指定できるため、それぞれ作成して最後にくっつける。

### フィルタリング条件

```bash
{($.errorCode="*UnauthorizedOperation") || ($.errorCode="AccessDenied*")}
```

下記手順でできる。

1. 2回URLエンコードする。
2. `%2520`(エンコード後の空白)を`+`に変換する。
3. `%`を`$`に変換する

```python
import urllib.parse

# safe=''を指定しているのは、デフォルトが`/`を除外するから。
filter = urllib.parse.quote(urllib.parse.quote(filter, safe=''), safe='').replace('%2520', '+').replace('%', '$')
```

### 日時
UNIXTIME指定のため、`datetime`型や`date`型等は変換する。
変換した後は少数点以下3桁がある`float`型になるため、1000倍する。 -> これをしないと URLの日付の値が小さすぎるため、1970年が指定される。
ex.)`1615820400000`の13桁

```python
import datetime

# dtより30分前から
start_time = int((dt- datetime.timedelta(minutes=30)).timestamp() * 1000)
# dtまで。
end_time = int(dt.timestamp() * 1000)
```

### url生成

```python
# 他ロググループ、ストリーム、リージョンは変更しないため、固定値にした。
# `CloudTrail/logs`ロググループ
# `{*****アカウントID*****}_CloudTrail_us-east-1`ログストリーム
url = 'https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups/log-group/CloudTrail$252Flogs/log-events/{*****アカウントID*****}_CloudTrail_us-east-1'
url += '$3FfilterPattern$3D' + filter + '$26start$3D' + str(start_time) + '$26end$3D' + str(end_time)
```

ex.)生成されたURL

```bash
https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups/log-group/CloudTrail$252Flogs/log-events/{*****アカウントID*****}_CloudTrail_us-east-1$3FfilterPattern$3D$257B+$2528$2524.errorCode+$253D+$2522$252AUnauthorizedOperation$2522$2529+$257C$257C+$2528$2524.errorCode+$253D+$2522AccessDenied$252A$2522$2529+$257D$26start$3D1615881063411$26end$3D1615882863411
```
気をつけるところとしては`CloudTrail$252Flogs`をみてわかる通り、URLで使われている`/`以外の`/`もURLエンコードしないといけない。
フィルタリング条件と同様にURLエンコードにひとクセある感じ。

## 所感
わかってしまえばなんてことはないんですが、URLエンコードするだけでなく、文字列変換のロジック組まないといけないのは、ちょっと面倒くさいですね。
また、フィルタリング時に文字列検索なら`"`で囲うのも意外と忘れがち。
Push済みのコミットのコメントを変更する方法

# 概要

リモートへPushしてしまったコミットのコメントを変更する方法を記載する。

# 手順

## 変更したいコミットを指定する

指定した数値分、現在の状態から前のコミットを見ることができる
以下のようにすると3個前のコミットまで見ることができる。

```
$ git rebase -i HEAD~3 // 数値は可変
```

## 変更したいコミットを選択

コミットの一覧が`pick ～ コミットコメント`という形で表示されるので、変更したいコミットの`pick`を`edit`に書き換えて保存する。


## コミットコメントの編集

以下のコマンドでコミットコメントが変更できるようになるので、任意のコミットコメントに編集し保存する。

```
$ git commit --amend
```


## コミットコメントの編集終了

以下のコマンドでコミットコメントの編集を終了する。
**※変更したいコミットが複数ある場合、1つ前の手順に戻り手順を繰り返す。**

```
$ git rebase --continue
```


## リモートにPushする

強制的にPushを行う。
以下のようにするとmasterにPushすることができる。

```
$ git push -f origin master // ブランチ名は可変
```
Java学習　基礎編　~ 配列と繰り返し処理 (拡張for文)~

Java学習の備忘録になります。
内容は初心者なので基礎的な部分となります。
Javaに興味がある方やJava学習初心者の参考になれば幸いです。

* * *
#### 配列とfor文
下記のように、配列**names**の要素をすべて出力するために、for文を用いて記述すると、配列の要素の値を簡単に一覧表示できる。

```Main.java
String names[] = {"おおた", "すだ", "ささき"};

for (int i = 0; i < 3; i++) {
  System.out.println(names[i]); // iが0、1、2の間、繰り返される。
}
```
#### lengthとは

配列には、要素の数を数える「**length**」という機能が備わっている。
使い方は「**配列.length**」というように、ドット「.」でつなぎ、配列の要素数を気にする必要がなくなるメリットがある。

上記例をlengthを用いて記述する。

```Main.java
String names[] = {"おおた", "すだ", "ささき"};

for (int i = 0; i < names.length; i++) {
  System.out.println(names[i]); 
}
```
### 拡張for文の文法

for文には、配列用に特別な構文を用意しており、これを使えば上記for文よりシンプルに記述することができる。
拡張for文では、配列の各要素の値を順に代入する変数を用意する。

```Main.java
for (データ型 変数名: 配列名) {
  繰り返す処理;
}
```
下記では、繰り返しの度に、変数nameに配列namesの要素が順に代入されていく。
また、拡張for文では、自動的に要素の数だけ繰り返しが行われる。

上記の例を拡張for文を用いて記述する。

```Main.java
String names[] = {"おおた", "すだ", "ささき"};

for (String name: names) {
  System.out.println(name); 
}
```

* * *
#### おわりに
拡張for文の方が、シンプルに記述でき便利なので覚えておきましょう。
なお、ご指摘などございましたら、遠慮なくお願いいたします！！
FontAwesomeがIE11で表示されない

FontAwesomeを使用してアイコン表示しようとしたが、
表示されずにハマったので備忘録的に残しておこうと思います。
皆さんの参考になれば幸いです。

<h1>環境</h1>
Webサーバ　　：IIS
ブラウザ　　　：IE11
FontAwesome　：V4.4（Webサーバのfontsフォルダに配置）
プロトコル　　：https

<h1>原因</h1>
FontAwesomeには、特定の条件でアイコンが表示されないことがあるようです。
[参考]
https://github.com/FortAwesome/Font-Awesome/wiki/Troubleshooting#im-hosting-fonts-on-my-server-and-icons-dont-show-up

[内容抜粋]
サーバーでフォントをホストしていますが、アイコンが表示されません
以下を確認してください。

１．サーバーのMIMEタイプを適切に構成しました
２．クロスオリジンリソースシェアリング（CORS）を適切に構成しました
３．Internet Explorerの場合：no-storeキャッシュ制御ヘッダーにオプションがあるファイルは提供されません
４．Internet ExplorerおよびHTTPSの場合：no-cacheプラグマヘッダーにオプションがあるファイルは提供されません
５．Internet Explorerの場合：@font-face定義内のクエリ文字列を削除してみてください。カスタムcssファイルが必要です

web.configに以下の設定を行っており、３、４の条件にハマっていました。

```web.config
    <system.webServer>
     <httpProtocol>
       <customHeaders>
         <add name="Cache-Control" value="no-store" />
         <add name="Pragma" value="no-cache" />
       </customHeaders>
     </httpProtocol>
    </system.webServer>
```

<h1>対策</h1>
単純に３，４の条件となっている設定を外すことができるなら、それでも良いと思います。

単純に３，４の条件を外すことができない場合、
以下の対策を行うことでアイコンが表示されるようになりました。

```web.config
    <system.webServer>
     <httpProtocol>
       <customHeaders>
         <add name="Cache-Control" value="no-store" />
         <add name="Pragma" value="no-cache" />
       </customHeaders>
     </httpProtocol>
    </system.webServer>

    <location path="fonts">
      <system.webServer>
        <httpProtocol>
          <customHeaders>
            <remove name="Cache-Control" />
            <remove name="Pragma" />
          </customHeaders>
      </httpProtocol>
      </system.webServer>
    </location>
```
＜location＞～＜/location＞の内容を追記しました。
FontAwesomeのファイルはキャッシュしても問題ないと判断したため、
それらを格納しているフォルダ"fonts"のみ、Cache-Control、Pragmaの設定を外しました。

<h1>おわりに</h1>
こういうのって簡単にどんぴしゃな情報がヒットせずに苦労しますよねぇ( ´Д｀)=3 ﾌｩ