OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsServer2019へのSSHトンネルで公開鍵認証だけが出来ずハマる（たぶん保存先がVirtualStoreだったんだな。。）

## １．基本的にはこの手順なのですが、、
WindowsServer2019へSSHトンネルで公開鍵認証を使う方法はこちらの手順を参考にさせて頂いています。

>Linux踏み台を使わずにWindowsインスタンスへのリモートデスクトップ接続をSSHトンネル化する
https://dev.classmethod.jp/articles/rdp-over-ssh-without-linux-bastion

## ２．今回「[楽天クラウドRHOSP](https://comm.rakuten.co.jp/oshirase/20230131.html)(2023/12/31サービス終了)」を使ったところ、、、
「さくらのVPS for Windows」「KCPS」等、複数のサーバで同手順を使っており、
今回「楽天クラウドRedHat Open Stack Platform（RHOSP」で同手順を行ったところ、
SSHのパスワード認証は出来たのですが、なぜか公開鍵認証だけ出来ずにハマってしまいまして、、
クラウドのサポート担当にも相談[^1]していましたが、
<b>どうやら最終的な原因は「WindowsのVirtualStore」にあった</b>ようなのでここに記録します。
[^1]: もしかすると、他社等のクラウドサポートでしたら、Windowsの設定なので対象外と門前払いされるかと思っていましたが、楽天クラウドサポートさんには実機検証まで行って頂けたことを特記します。

<b>なお、こちらに同課題の解決が書かれているようです。</b>
>Windows10公式のopensshサーバーを起動して、macからsshで接続するまで
https://qiita.com/hatobeam75/items/825ee10a5261835e814b
>>設定ファイルの編集は必ず管理者権限で行いましょう。
WindowsにはVirtualStoreというファイル保護の仕組みがあり、一般ユーザーで変更しても別の場所に保存され、いつまでも更新されません。

## ３．やっと「WindowsのVirtualStore」の問題だ！と気が付いた経緯
（１）先の手順や皆さんが行っている通り、公開鍵認証を通すには「sshd_config」の次の部分をコメントアウトすることは把握していた。

```
#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
```
（２）いつも通り、いざ公開鍵認証接続を試みても弾かれてしまう、、パスワード認証は行ける。

（３）これはデバッグか、、と思い「sshd_config」にデバッグ出力を書いたが、

```
SyslogFacility LOCAL0
LogLevel DEBUG3
```
一向に「logs」に書き出されない。。<b>←この時点で「WindowsのVirtualStore」を疑うべきだった。</b>

（４）クラウドサポート担当さんから「[鍵認証で接続可能な事を確認できました。](https://dev.classmethod.jp/articles/rdp-over-ssh-without-linux-bastion)」と連絡が入り、後は自力となる。。

（５）「sshd_config」を比較しようと、クラウドサーバから、RDPクライアント（Windows10pro）に転送してみたところ、
転送された「sshd_config」が全く編集されていないことに気が付いた。。
![1_クラウドサーバーの「sshd_config」がローカル上では編集されているが、RDPクライアントへ転送すると編集されていない.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667967/4f027fb6-c68b-c2d8-6f85-6a4c8ab2b49d.gif)

（６）「なぜか知らないけどC:\ProgramDataは仮想フォルダなのかな？」と思いつつ、転送した「sshd_config」を編集して、クラウドサーバに戻して、
![2_「sshd_config」をRDPクライアントで編集後、クラウドサーバーに転送しSSHサーバサービス再起動.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667967/af721e73-625a-d5b5-bbd3-5a2ac36da4b4.gif)
SSHサーバサービスを再起動したところ、、、公開鍵認証接続ができた！

（７）なぜか知らないけど（略）の件をネット検索して、「WindowsのVirtualStore」という機能があることを知る。→おそらくこのクラウドサーバも「VirtualStore」を使っているのだろうと推測をしました。

以上です。
Tera Term 私的おすすめ設定

自分が普段 Tera Term をインストールしたときに必ずやっている初期設定を紹介します。
それぞれ、

* 危険な機能の無効化
* 利便性向上
* 個人的好み

のいずれかを目的としたものです。特に「危険な機能の無効化」カテゴリのものは万人にお薦めします。

なおこの記事は Tera Term 4.106 を前提に記載しています。

# インストーラーでの設定

## 追加プラグインを全て有効化する
![clip_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43183/308e9c72-3f01-3af4-a2c2-2ad49392b869.png)

<dl>
<dt>カテゴリ</dt><dd>利便性向上</dd>
<dt>変更理由</dt><dd>デフォルトでは追加プラグインは「TTXResizeMenu」と「TTXttyrec」しか有効になっていない。しかし個人的には「TTXKanjiMenu」もしばしば使うため。</dd>
</dl>

# インストール後の TERATERM.INI のカスタマイズ

## ConfirmPasteMouseRButton を off から on に変更

<dl>
<dt>カテゴリ</dt><dd>危険な機能の無効化</dd>
<dt>変更理由</dt><dd>off だと右クリックした瞬間にクリップボードの内容が貼り付けられてしまい、誤操作によって致命的な支障を生むコマンドが投入されてしまう恐れがあるため。これを on にすることで、右クリックしただけでは貼り付けられず、明示的に「貼り付け」をクリックすることで初めて貼り付けられるようになる。</dd>
</dl>

## VTFont を「Terminal,0,-19,128」から「ＭＳ ゴシック,0,-14,128」に変更

<dl>
<dt>カテゴリ</dt><dd>個人的好み</dd>
<dt>変更理由</dt><dd>デフォルトのフォントサイズが大きすぎるため。</dd>
</dl>

## AutoWinClose を on から off に変更

<dl>
<dt>カテゴリ</dt><dd>危険な機能の無効化</dd>
<dt>変更理由</dt><dd>on だとセッション切断時に自動的にウィンドウが閉じられてしまい、誤操作や障害で切断された際にそれまでの操作ログを喪失するため。</dd>
</dl>

## HistoryList を on から off に変更

<dl>
<dt>カテゴリ</dt><dd>個人的好み</dd>
<dt>変更理由</dt><dd>on だと接続先リストが自動的に更新され、予め設定していたものが流れてしまうため。</dd>
</dl>

## AutoTextCopy を on から off に変更

<dl>
<dt>カテゴリ</dt><dd>危険な機能の無効化</dd>
<dt>変更理由</dt><dd>on だと範囲選択した瞬間にクリップボードにコピーされてしまい、意図せずクリップボードの内容を喪失してしまうため。</dd>
</dl>

## ClearOnResize を on から off に変更

<dl>
<dt>カテゴリ</dt><dd>利便性向上</dd>
<dt>変更理由</dt><dd>on だとウィンドウサイズ変更時にバッファの内容が消えてしまい不便なため。</dd>
</dl>

## IMERelatedCursor を off から on に変更

<dl>
<dt>カテゴリ</dt><dd>利便性向上</dd>
<dt>変更理由</dt><dd>on の方が IME の状態が分かり易くなるため。</dd>
</dl>

## ResizeMenu を以下のように定義

```
ResizeMenu1= 80,  0
ResizeMenu2=120,  0
ResizeMenu3=160,  0
ResizeMenu4=240,  0
ResizeMenu5=  0, 24
ResizeMenu6=  0, 40
ResizeMenu7=  0, 56
ResizeMenu8=  0, 72
```

<dl>
<dt>カテゴリ</dt><dd>利便性向上</dd>
<dt>変更理由</dt><dd>ある程度のウィンドウサイズにさっと変更できると便利なため。</dd>
</dl>
Google Cloud の階層構造について

#### 階層構造について

![スクリーンショット 2021-07-15 18.14.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740345/2e35a5e8-927e-78e7-46bc-a664df3a154e.png)

```
https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy?hl=ja
```

GCPのリソース階層は下位層から 見ていったほうがわかりやすいです。
プロジェクトは、フォルダにまとめることができます。フォルダには他のフォルダも格納できます。

組織が使用する全フォルダとプロジェクトは組織ノードの下にまとめられます。プロジェクト、フォルダ、組織ノードには、まとめてポリシーを定義できます。
一部のGCPリソースでは 個別にポリシーを定義できます。
たとえばCloud Storageバケットです。

ポリシーは階層の下位に 継承されます。すべてのGCPリソースは、１つのプロジェクトに属します。
プロジェクトはGCPサービスを使用する際の基本単位です。APIの管理、課金の有効化、 共同編集者の追加と削除などを行います。
各プロジェクトは独立した区画であり、各リソースは、1つの区画にのみ属します。

プロジェクトごとに異なるオーナーと、ユーザーを作成して個別に管理できます。
各GCPプロジェクトに、名前とプロジェクトIDを割り当てます。プロジェクトIDは永続的かつ不変で、GCP全体で一意である必要があります。

このIDは、さまざまな場面で使用します。そうすることで、GCPに作業対象のプロジェクトを指示します。
プロジェクトには、好きな名前を付けられます。
各プロジェクトには固有のプロジェクト番号も割り当てられます。

プロジェクトはフォルダにまとめることができます。フォルダは作業を楽にするためのツールです。
たとえばフォルダを使用して、組織内の各部門、チーム、アプリ、環境を表すことができます。

フォルダを使ってチームの管理権限を委任すれば、各チームが独立して対応できるようになります。
フォルダ内のリソースは、そのフォルダのIAMポリシーを継承します。

たとえばプロジェクト３と４が、同じチームによって管理される場合。
フォルダBにIAMポリシーを適用しますと、プロジェクト３と４のそれぞれに同じポリシーを 適用する手間もエラーの発生も抑えられます

フォルダを使用するには、階層の最上位に組織ノードが必要です。

社内の全プロジェクトは、１つの構造にまとめることができます。
大体の企業では、リソースの使用状況の確認と ポリシーの適用を一元的に行う必要があると思うのですが、それを可能にするのが組織ノードです！

組織ノードは階層の最上位階層であり、特別な役割を持っています。
たとえば、組織ポリシー管理者を指定して、管理者だけがポリシーを変更できるようにできます。

プロジェクト作成者の役割も割り当てられます。購入を行えるユーザを管理する効果的な方法です。

ただ、組織ノードはどのように作成するのでしょうか？
これは、会社がG Suiteを利用しているかどうかによって異なります。

G Suiteドメインがある場合、GCPプロジェクトは、自動的に組織ノードに属します。

そうでない場合は、Google Cloud Identityを使用して作成できます。
新しい組織ノードを作成した時点では、ドメイン内の全員が引き続き、プロジェクトと請求先アカウントを作成できます。
これは混乱を避けるためです。

なので、新しい組織ノードを作成したら、まずこれらの操作を許可するチームメンバーを決定したほうがよさそうです。
組織ノードを作成すれば、その下にフォルダを作成して、そこにプロジェクトを配置できます。

リソース整理の例を紹介します。
３つのプロジェクトがあり、それぞれが複数のGCPサービスのリソースを使用するとします。

この例ではフォルダを使用していませんが、プロジェクトはいつでもフォルダに移せます。
リソースは親リソースからポリシーを継承します。

たとえば組織レベルで設定したポリシーは、自動的にすべての子プロジェクトに継承されます。継承が遷移するということです。
つまり、プロジェクト内のすべてのリソースが、ポリシーを継承します。
MAMPに複数のSSL化したVirtualHostを建てる

```httpd-ssl.conf
NameVirtualHost *:443
<VirtualHost *:443>
    DocumentRoot "C:\MAMP\htdocs\set_tsuko"
    ServerName local-set-tsuko.com
    ServerAdmin admin@local-set-tsuko.com
    ErrorLog "c:\mamp\logs\ssl_error.log"
    TransferLog "c:\mamp\logs\ssl_access.log"
    SSLEngine on
    SSLCertificateFile "C:\MAMP\conf\apache\keys\server.crt"
    SSLCertificateKeyFile "C:\MAMP\conf\apache\keys\server.key"
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "C:\MAMP\cgi-bin">
        SSLOptions +StdEnvVars
    </Directory>
    BrowserMatch "MSIE [2-5]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
    CustomLog "c:\mamp\logs\ssl_request.log" \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>                                  


<VirtualHost *:443>
    DocumentRoot "C:\MAMP\htdocs\avhub"
    ServerName local-avhub.com
    ServerAdmin admin@local-avhub.com
    ErrorLog "c:\mamp\logs\ssl_error.log"
    TransferLog "c:\mamp\logs\ssl_access.log"
    SSLEngine on
    SSLCertificateFile "C:\MAMP\htdocs\avhub\keys\server.crt"
    SSLCertificateKeyFile "C:\MAMP\htdocs\avhub\keys\server.key"
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "C:\MAMP\cgi-bin">
        SSLOptions +StdEnvVars
    </Directory>
    # <Directory "C:\MAMP\htdocs\avhub">
    #     AllowOverride all
    # </Directory>

    BrowserMatch "MSIE [2-5]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
    CustomLog "c:\mamp\logs\ssl_request.log" \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>  
```


```httpd-vhosts.conf

~~~~~~省略~~~~~~~~
<VirtualHost *:443>
    DocumentRoot "C:\MAMP\htdocs\set_tsuko"
    ServerName local-set-tsuko.com
    SSLEngine on
    SSLCertificateFile "C:\MAMP\conf\apache\keys\server.crt"
    SSLCertificateKeyFile "C:\MAMP\conf\apache\keys\server.key"
    <Directory "C:\MAMP\htdocs\set_tsuko">
        AllowOverride all
    </Directory>
</VirtualHost>
~~~~~~中略~~~~~~~~
<VirtualHost *:443>
    DocumentRoot "C:\MAMP\htdocs\avhub"
    ServerName local-avhub.com
    SSLEngine on
    SSLCertificateFile "C:\MAMP\htdocs\avhub\keys\server.crt"
    SSLCertificateKeyFile "C:\MAMP\htdocs\avhub\keys\server.key"
    <Directory "C:\MAMP\htdocs\avhub">
        AllowOverride all
    </Directory>
</VirtualHost>
```

[参考](https://ssl-process.com/support/etc/apache_multidomain/index.php)
JavaScriptの更新が反映されないときの対処

#結論

ブラウザで古いJavaScriptファイルがキャッシュされており、更新後のファイルを読み込めていなかった。

#前提知識

>Google Chrome、Mozilla Firefox、Internet Explorerなどのウェブブラウザは、インターネット上にある情報を取得・閲覧するソフトウェアアプリケーションです。ブラウザは、私たちが探しているウェブサイトやその他の情報を、URL経由で検索、発見、表示しています。

>キャッシュとは、一度アクセスしたサイトのデータ（画像やHTMLなど）をブラウザで一時的に保管しておく仕組みです。こうしてデータを保管しておく目的は、帯域幅の混雑を避けページの表示を高速化することにあります。

>つまり、次回同じページを閲覧する際に、キャッシュに保存されたページデータが読み込まれるため、インターネット上から読み込むよりも速く表示することができるのです。

>言い換えれば、ページデータがキャッシュに保管されていれば、ブラウザは新しくHTMLリクエストを送信する必要がありません。そのため、古いWebサイトが表示される、という結果になるのです。

参考：[ブラウザのキャッシュとは？](https://blog.hubspot.jp/what-is-browser-cache-faqs)

「.js」に限らず静的なファイル（.jpgなども）はブラウザにキャッシュされているので、更新した後はサーバにあるファイルを再度読み込む必要がある。

#確認

開発者ツールの「Network」タブにて確認する（例はGoogle Chrome）。

1回目のページ読み込み。
「validation.js」という17.3kBのファイルを93msで読み込んでいることがわかる。
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874156/69b72a5e-b855-3a86-2482-d809e24a895c.png)



2回目のページ読み込み。
ファイルサイズを示す「Size」に(memory cache)が表示されている。通信を行っていないのでTimeも0ms。

「validation.js」はブラウザで保持しているので、jsファイルをとるリクエストが必要なく高速にページを表示できる。
...のはいいが変更した「validation.js」を再度読み込んでほしいので、これでは困る。

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874156/a7a6cb27-a056-8e80-a4c7-540a773d77e6.png)



#対処

###1．ハード再読み込みを使用する

Ctrl+Rでページの更新を行うことができるが、Ctrl+Shift+Rでキャッシュを破棄しつつページの更新を行うことができる。
（Macの場合はCmd＋Shift＋R）

###2．開発者ツールの設定を変更する

「Disable cache」にチェックを入れることでブラウザでキャッシュを保持しなくなる。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874156/715bd670-6d91-5b03-8ee5-847868e01de6.png)
[VRC]Unityでアバターのシェイプキーの値を変えるとメッシュが消えるバグの解決法

VRCの知り合いから、この現象について質問されて、なんとか解決できたのでついでに記事にします。
## 解決策
Edit→ProjectSettings→Player→OtherSettings→GPUSkinningをオフにする。
これだけで動きます。
![24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649195/b8835341-26e4-7ebc-9244-82a2574fc325.png)
[参考記事](https://www.programmersought.com/article/20174814399/)

## 起きた事象について
### 環境
* Windows10
* Intel Corei3 2100 3.10GHz
* GPU無し
* Unity2018.4.20f1
* [ミントちゃん](https://booth.pm/ja/items/2258111)
* [Sunao Shader](https://booth.pm/ja/items/1723985)

### 事象
UnityでVRC用のアバターをアップロードしようとしていたところ、アバターのシェイプキー(BlendShape)の値を少しでも変えたら、そのメッシュが表示されなくなるという現象が起こりました。
そしてこの現象は、どのシェイプキーどんなアバターでも、またUnityProjectを作り直しても、またUnityEditorを再インストールしても治りませんでした。
また、このときConsoleには
> Platform dose not support compute shaders

というエラーが表示されました。
実際に起きてるときの画像を貼ります。

シェイプキーをいじる前
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649195/8064b775-d262-517c-b714-a5e990d4ca83.png)

シェイプキー(VRC.v.aa)の値を変えたとき
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649195/e9386761-01ef-9492-37f3-0976e3898634.png)

シェイプキー(blink)
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649195/90e6aa59-d9a9-3e06-a6bf-dbd833e5443b.png)

### 解決法について
めっちゃ検索したところ、上で貼った参考記事が出てきて、なんとか解決しました。
記事を要約すると、GPUSkinningという機能がErrorを起こしているのが原因なので、この機能をオフにすると解決、とのことでした。
おそらく、この事象が起きたパソコンにGPUが搭載されていないことで、該当機能がErrorを起こしていたのではないかと自分は思っています。

その通りにしたら動きました。ミントちゃんもニッコニコです。
![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649195/a78535dd-57cf-b673-af33-e10a8f556da1.png)

## 最後に
GPUはいいぞ！
phpSpreadSheet の環境構築とよく参考にするサイト

# 背景
仕事の作業の自動化に excel 生成が必要そうなので phpSpreadSheet を勉強することにしました。
ここでは環境構築の手順と勉強するときに参考になったサイトを紹介しております。

自分が作業する際に見るようの記事なので、読みづらかったら申し訳ありません。

# 環境
Amazon Linux release 2 (Karoo)
PHP 8.0.8 (cli)
Composer version 2.1.3

# 環境構築
## php の導入

php を入れます。

```
sudo amazon-linux-extras install php8.0
```

## phpSpreadSheet の導入

composer が必要なので導入します。

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer.phar
sudo ln -s /usr/local/bin/composer.phar /usr/bin/composer.phar
alias composer="php /usr/bin/composer.phar"
alias sudo='sudo '

composer -V
Composer version 2.1.3 2021-06-09 16:31:20
```

関連パッケージのインストールします。

```
sudo yum install php-xml
sudo yum install php-gd
sudo yum install php-mbstring
```

phpSpreadSheet を導入します。

```
sudo composer require phpoffice/phpspreadsheet
```

## 動作確認
公式ページの Hello World を試します。

https://phpspreadsheet.readthedocs.io/en/latest/

```
sudo vi index.php

<?php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('HelloWorld.xlsx');
```

実行します。

```
sudo php index.php
```

生成したエクセルをローカルに持ってきて開く。
今回は TeraTerm の ssh scp の機能を利用した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184532/fe718cb1-03a6-3698-0808-37de4d6a565f.png)

A1 のセルに Hello World が挿入されていたので動作確認OK！

# 参考サイト
## 公式サイト
公式サイトに phpSpreadSheet の使い方が書いてあります。
ネットで軽く調べて分からなかったら、公式サイトを見ます。

https://phpspreadsheet.readthedocs.io/en/latest/topics/accessing-cells/

## よく使う操作が簡潔に書いてあるサイト
リンクフリーとの記述がありましたので、掲載させていただきました。
デフォルトフォントの指定など、よく使いそうな操作が一通り記述しています。

https://vertys.net/php-spreadsheet-often-use-process/

## セルのスタイルの指定が詳しく記述してあるサイト
セルのスタイルの記述が分からなくなったときに参考にさせていただく記事です。
ボーダーの種類等詳しく書いてます。

https://qiita.com/yshishido/items/023358535cf7bdf7e9c0

# 最後に
私が作業するときに見るようの記事ですので、まとめサイトのような構成になっております。
読みづらかったら申し訳ありません。
DocValuesとは

# DocValuesとは？

DocValues とは、フィールドの値を内部的に記録する方法。
ソートやファセットなどの一部の目的では、従来のインデックスよりも効率的。

全文検索は [転置インデックス](https://ja.wikipedia.org/wiki/%E8%BB%A2%E7%BD%AE%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9) を使って高速な検索を行う。
転置インデックスは、ソート/ファセット/グルーピングなどの処理には不向き。

そこでDocValues。

* ドキュメントをキーに値を持つ、列指向のインデックス
* FieldCacheよりメモリ効率が上がる（？）
* ソート/ファセット/グルーピングのための検索が早くなる
* 他にも /export handler, Stream Expressions など DocValues 前提の機能が使える
* FieldCacheは最初のクエリー時に構築されるが、DocValuesはインデクシング時に構築される
  * 頻繁に更新されるデータ（NRT）向き
* JVMのヒープを圧迫しないようOSのメモリを使う（ファイルに書き出される）

# DocValuesの有効化

## Solrでの設定方法

```xml:schema.xml
<field name="field123" type="string" indexed="false" stored="false" docValues="true" />
```

フィールドの定義やフィールドタイプの定義に docValues="true" を追加するだけ。
ただし、全データの再インデックスが必要。

本当は `uninvertible=”false”` にして、必要な所で `docValues="true"` することが強く推奨されている（その場合 `indexed=”true” docValues="false"` だとソート/ファセット/グルーピングが出来なくなる）。

## 型ごとの対応状況

| フィールド | multi-valuedでの重複可否 | ソート |
|:---|:---:|:---:|
| StrField<br/>UUIDField | 重複不可(除去) | - |
| BoolField | 重複不可(除去) | - |
| DatePointField<br/>DoublePointField<br/>FloatPointField<br/>IntPointField<br/>LongPointField | 重複可 | single-valueの場合、ソートのためにDocValues必須 |
| EnumFieldType | 重複不可(除去) | - |
| CurrencyFieldType | 重複不可(除去) | - |

その他、非推奨フィールドのいくつかに対応している。
multi-valuedの場合、値はソート済みの状態で保持される。挿入順ではないので注意。
また、 `*PointField` のみmulti-valuedでも値を重複して保持でき、他のフィールドタイプと挙動が異なるので注意。

## その他

DocValues関連のデータはメモリとディスクに保存される（Luceneデフォルト）
`docValuesFormat=Direct` で全てメモリ上に保存できる
`docValuesFormat=Disk` で全てディスク上に保存できる（最小限のデータをメモリに読み込む）
Luceneはデフォルトの挙動しか保証していない。将来的に無効になる可能性はある。

# DocValuesの使い方

## 値の保持について

`useDocValuesAsStored=”true”` にすると値も保持できる（スキーマバージョン1.6以上の場合 `true` がデフォルト）。
`useDocValuesAsStored=”false”` の場合、

* `fl=*` にマッチしないのでレスポンスに含まれない（ `q=*:*` も）
* フィールド指定すれば値を取得できるが、DocValuesは列指向のためコストがかかる
* multi-valuedフィールドでは値はソートされ、重複排除される（ `SORTED_SET` の場合）
* multi-valuedフィールドでも `stored=”true”` にすれば挿入順で取得できる（サイズ増）

## パフォーマンスへの影響

`docValues="true"` のフィールドのみ取得した場合、パフォーマンスが上がる可能性がある

* ディスクにアクセスせず、全てのデータをメモリから取得できるから
* メモリから落ちてる部分はディスクから取得することになりそう？

# 参考情報

https://qiita.com/takaishi/items/6f08325c2eb3922bf166

https://yomon.hatenablog.com/entry/2017/08/01/234336

https://www.it-swarm-ja.com/ja/solr/solr%E3%81%AEdocvalues%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F%E3%81%84%E3%81%A4%E4%BD%BF%E3%81%86%E3%81%B9%E3%81%8D%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/805640063/
PagerDutyのオンコール担当をチャンネルのトピックに設定する

# 概要

PagerDutyのオンコール担当になっていることをうっかり忘れたことが何回かあったので、なにかよい方法ないかなと探してたら、「pd-oncall-chat-topic」というものがあったので早速試してみました。

https://github.com/PagerDuty/pd-oncall-chat-topic

仕組みはとてもシンプルでした。
1. Lambdaが5分おきに動いてPagerDutyのAPIからオンコール担当を取得
2. Slackのチャンネルにトピック登録

# 手順

手順はReadmeに記載の通りで特に詰まるところもなく設定できます。

## SlackでBotを設定する

ここからBotを作成します。
https://my.slack.com/services/new/bot

![bot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/ebaf13a2-20c1-2334-528f-4e79d56ded39.png)

APIトークンをメモしておきます
![bot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/85f00ccd-355b-afcf-767d-4118f049b7f0.png)

トピック設定するチャンネルを右クリックして「リンクをコピー」します。
CDXXXXXXXの部分がSlackChannelIDになるのでメモしておきます。
https://example.slack.com/archives/CDXXXXXXX
![slack1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/c8c22483-c1cb-07aa-2c32-1f3b8ace95aa.png)

チャンネルのインテグレーションから「アプリを追加する」を選択して、先ほどつくったbotを追加します。
![slack2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/80a099ee-5164-6d2c-d35d-18ca1bc7c256.png)

## PagerDutyのスケジュールIDを取得する
On-Call Scheduleから該当のスケジュールを選択しURLのPXXXXXXXX部分をメモする
https://example.pagerduty.com/schedules#PXXXXXXXX

## PagerDutyのMyProfileからAPIトークンを発行する

「Create API UserToken」からトークンを発行します。

![pd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/253a095f-0c1b-78aa-7ab4-fc7434c5011b.png)


## AWSのリソースを作成する

1 Makefileの修正


```
$ git clone git@github.com:PagerDuty/pd-oncall-chat-topic.git
$ cd pd-oncall-chat-topic
$ vim Makefile
-------------------------------
# STACKNAME_BASEを書き換える
STACKNAME_BASE=example-pagerduty-oncall-chat-topic 

```
2  STACKNAME_BASEに指定した名前でS3バケットを作成する（example-pagerduty-oncall-chat-topic）
3 リソースの作成

```
$ make deploy
$ make put-pd-key
PagerDutyで作成したユーザートークンを指定
$ make put-slack-key
BotのAPIトークンを指定
```

## DynamoDBに通知先の情報を登録する

![スクリーンショット 2021-07-15 18.25.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/18cc1703-5ce3-f84e-adf4-bf12a4eed3fc.png)

# 動作確認

5分おきにLambdaが動き、チャンネルにトピックを設定してくれます。
![slack3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32289/7457b48c-8f4b-e128-dd71-2a57c29fc6dc.png)

うまく動かない場合はLambdaのログが出ていますので確認しましょう。
foliumで「重ねるハザードマップ」を重ねる

foliumで[国土地理院のサイト](https://maps.gsi.go.jp/development/ichiran.html)で提供されている、タイルの情報を地図の上に重ねる方法を紹介します。
調べてみると、ベースマップのタイルを変える方法は見付かるのですが、別のレイヤーをオーバーレイする方法は見つからなかったので。
foliumの細かい話は省略です。

# folium.raster_layers.TileLayer
タイルを重ねて表示するには`folium.raster_layers.TileLayer`というクラスを使います。
具体的にはこんな感じです。

```python
fmap1 = folium.Map(
    location=[35.1158021, 139.0839284],
    tiles = "OpenStreetMap",
    zoom_start = 15, 
    width = 800, height = 800
)

folium.raster_layers.TileLayer(
    tiles='https://disaportaldata.gsi.go.jp/raster/05_dosekiryukeikaikuiki/{z}/{x}/{y}.png',
    fmt='image/png',
    attr="hogehoge",
    tms=False,
    overlay=True,
    control=True,
    opacity=0.7
).add_to(fmap1)

folium.LayerControl().add_to(fmap1)

```

パラメータでハマりそうなところをいくつか書いておきます。

## tiles
ハマる、というほどではないんですが、似たようなことが出きる`WmsTileLayer`では、`url`という引数になっています。

## attr
例では`hogehoge`としていますが、右下に出る権利表示です。
このパラメータが空だと動かないんですが、エラーを見た時にattributeのことだと思うと混乱します。

特に外に公開する場合などは`hogehoge`とかせずちゃんと書きましょう。

## tms
タイルの座標を決める方式のようです。
とりあえず、両方試して正しそうな方を選ぶのがよいかと。
VS CodeでLive Sass Compilerを使っている人へ

## みんな古いLive Sass Compilerを使っていませんか？


業務でCSS書くのにVS CodeでLive Sass Compilerを使用しています。
[Live Sass Compiler](https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass)

ダウンロード数も多いし、ブログ等のリソースもほとんどこっちです。
[Googleで最新1年以内で検索](https://www.google.com/search?q=Live+Sass+Compiler+VS+Code&biw=2141&bih=1447&tbs=qdr%3Ay&sxsrf=ALeKk01uHS6CmqYKH-NNbk-EdWvhLaoD7w%3A1626341173571&ei=Nf_vYM-rIvTSmAXf7a74Dg&oq=Live+Sass+Compiler+VS+Code&gs_lcp=Cgdnd3Mtd2l6EAMyBAgAEBMyCAgAEAgQHhATMggIABAIEB4QEzoECCMQJzoCCABKBAhBGABQtT1Y1KABYIulAWgBcAJ4AIABgQGIAb4DkgEDMS4zmAEAoAECoAEBqgEHZ3dzLXdpesABAQ&sclient=gws-wiz&ved=0ahUKEwiPmrz_4OTxAhV0KaYKHd-2C-8Q4dUDCA4&uact=5)して上位表示しているブログでもこちらを利用しています。

でもよくよくログをみると、前者のLive Sass Compilerの開発はすでに2018年で止まっています。
![Live Sass Compilerのversionlog](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111743/b967f13c-b650-edfe-2b9b-395c9251f599.png)


## 新しいLive Sass Compilerに乗り換えましょう！

実は新しいLive Sass Compilerがあるんです。
[Live Sass Compiler](https://marketplace.visualstudio.com/items?itemName=glenn2223.live-sass)

マーケットプレイスで検索したら出てくるので見たことある人もいると思います。
![vscodeのスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111743/e26d3bdf-1862-7c20-92ce-e30d384f2d50.png)

理由はそこの説明の一番下にあります。
> A big thank you to @ritwickdey for all his work. However, as they are no longer maintaining the original work, I have released my own which has built upon it.

開発停止した前者のソースを後者の方が引き取って開発を継続している模様です。

## なんでわかったの？

自分も前者の拡張機能をつかっていたのですが、autoprefixの設定をしていて、以下のように「not dead」を含むとコンパイルができなかったのでググって判明しました。

``` json:setting.json
"liveSassCompile.settings.autoprefix": [
     "> 0.5%",
     "last 4 versions",
     "not dead"    
 ]
```

[Not dead in settings.json (vs code plugin) make live Sass compiler doesn't work #252](https://github.com/ritwickdey/vscode-live-sass-compiler/issues/252)

そこで後者の開発者がコメントを入れていてその事実が判明しました。
当時のBrowserslistに"not dead"が入ってなかったのでエラーが起こる模様。
> @Unknow-max is right, this extension is no longer being maintained. But don't worry, it's not all bad news! I've actually released my own version which does support the latest autoprefix browser queries! (it has some extra features in there too). It's currently on the VS Code marketplace here.

## 最後に
ってことで、古い方を使っている方は新しい方に乗り換えましょう。
[Live Sass Compiler](https://marketplace.visualstudio.com/items?itemName=glenn2223.live-sass)

~~設定等は引き継がれているようなので新機能がない限りは記述は変わってないと思います。~~
設定が若干変わってました。がほとんどは以前のものが使える感じです。

* [古い方の設定](https://github.com/ritwickdey/vscode-live-sass-compiler/blob/master/docs/settings.md)
* [新しい方の設定](https://github.com/glenn2223/vscode-live-sass-compiler/blob/master/docs/settings.md#livesasscompilesettingsautoprefix)

まだサクッとしか見てないですが、.mapファイルも1行にminifyされていて前よりいい感じがします。

あとは導入するときはブログの情報を鵜呑みにしないで、開発が止まっているかどうかも確認しないといけないなあと思いました。
ChIPseekerでゲノムの位置情報にアノテーションをつける

ゲノムの位置情報があったときに、さくっと近傍の遺伝子などを知りたいとする。
bedtoolsとアノテーションファイルを使えばわかるかもしれないが、それよりも全自動で注釈をさくってつけてくれた方が楽でしょう。

そんなときにChIPseekerが使えるぽい。

https://github.com/YuLab-SMU/ChIPseeker

https://guangchuangyu.github.io/2014/04/chipseeker-for-chip-peak-annotation/

ChIPseekerは文字通り、Chip-seq用のツールですが、アノテーションをつけたい場合は汎用的に使えそうです。

```R
## loading packages
library(ChIPseeker)

# Gene
library(TxDb.Hsapiens.UCSC.hg38.knownGene)
txdb <- TxDb.Hsapiens.UCSC.hg38.knownGene

chr    <- c("chrX", "chrX", "chrX")
start  <- c(71349, 77124, 86364)
end    <- c(72835, 77836, 88378)
strand <- c("-", "+", "*")

# Genomic Range
peak <- GRanges(seqnames = chr, ranges = IRanges(start, end), strand = strand)

# Annotation
peakAnno <- annotatePeak(peak,
                         tssRegion=c(-3000,3000),
                         TxDb = txdb,
                         annoDb="org.Hs.eg.db")

result <- as.GRanges(peakAnno)
```

こんな結果が得られる。
| seqnames | start | end   | width | strand | annotation | geneChr           | geneStart | geneEnd | geneLength | geneStrand | geneId | transcriptId | distanceToTSS     | ENSEMBL | SYMBOL          | GENENAME |
|----------|-------|-------|-------|--------|------------|-------------------|-----------|---------|------------|------------|--------|--------------|-------------------|---------|-----------------|----------|
| 1        | chrX  | 71349 | 72835 | 1487   | -          | Distal Intergenic | 23        | 276322  | 303353     | 27032      | 1      | 55344        | ENST00000399012.6 | -204973 | ENSG00000182378 | PLCXD1   |
| 2        | chrX  | 77124 | 77836 | 713    | +          | Distal Intergenic | 23        | 276322  | 303353     | 27032      | 1      | 55344        | ENST00000399012.6 | -198486 | ENSG00000182378 | PLCXD1   |
| 3        | chrX  | 86364 | 88378 | 2015   | *          | Distal Intergenic | 23        | 276322  | 303353     | 27032      | 1      | 55344        | ENST00000399012.6 | -187944 | ENSG00000182378 | PLCXD1   |


他にもいろいろ便利な関数がついているようです。

```R
plotAnnoPie(peakAnno)
```

今回の場合だと、全部intergenicであまり意味のあるグラフになりませんが…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/42a54553-e69c-1486-6b7d-0b2203e8fc7a.png)

また同じ作者の `clusterProfiler` を使ってenrichment解析にもっていけるようになっているようです。

この記事は以上です。
PC-8001にCH376をつないでみた。

CH376というUSBメモリをSPIなどで読めるようにするモジュールを以前購入して部品箱に死蔵していました。

![CH376.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/74ef715c-ec45-2d33-9c49-de4b54d0f2e3.jpeg)

USBメモリのフォーマットはFATでFAT16やFAT32が読めます。

このチップはSPIのほかにシリアルや8Bit パラレルIOでもデータの処理ができます。

CH376はCH372の後継で、CH372はUSBデバイスになれるチップだったようです。CH376はホストとデバイスになれます。CH375という製品もあり、こちらはCH376同様にホストにもデバイスにもなれますが、FATの処理が無いようです。

これをPC-8001にパラレルIOで接続する事を思いつきました。

手元のモジュールはパラレルで使うときのジャンパーの設定はこうしました。

![JP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/56843187-de6a-cd11-8c4d-42f973048b83.png)

TTLのストックが無く秋葉にも行けないので、GALでアドレスデコードします。

```
title    CH376S IO UNIT 
pattern  CHIO 
revision A 
author   yamori813 
date     07/13/21 
chip chio gal6001 

; The following pin list order mustly be followed strictly: 
; 1. device pins 1 to 24 
; 2. slmc 7 to slmc 0 
; 3. buried feedback (OLMC 14) to buried feedback (OLMC 23) 

; pins 1  2  3  4  5  6  7  8  9  10  11  12 
       i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 gnd 

; pins 13   14  15  16  17  18  19  20  21  22  23  24 
       oclk o14 o15 o16 o17 o18 o19 o20 o21 o22 o23 vcc 

; slmc7 slmc6 slmc5 slmc4 slmc3 slmc2 slmc1 slmc0 
  nc    nc    nc    nc    nc    nc    nc    nc 

; buried feedback to AND array from OLMCs. 
; bur14 bur15 bur16 bur17 bur18 bur19 bur20 bur21 bur22 bur23 
  nc    nc    nc    nc    nc    nc    nc    nc    nc    nc 

; specify the User Electronic Signature (UES) 

@ues chio
  ; 8 ues bits are used per character. 

equations 

; ILMC         : asynchronous inputs. 
; IOLMC        : asynchronous feedback to AND array. 
; SLMC         : not used. 
; OLMC 14-18   : asynchronous outputs (output always enabled). 
; OLMC 19-23   : D-type registered outputs (output always enabled). 
;      buried feedback of OLMCs not used. 
; asynch reset : not used (default is registers cannot be reset).  

; RESET
;o14  = /i1 

; RD =  RD | IORQ
o14  =  i2 | i3
; WR =  IORQ | WR
o15  =  i3 | i4

; CE ADDRESS A1-A7 FC(252),FD(253) 11111100 11111101

/o16 = /i5 & i6 & i7 & i8 & i9 & i10 & i11

; end of example 5 
```

ispLEVERが使えなくなったのでVerilogではなくて古式ゆかしいEQNファイルです。

そもそもアドレスデコードごときにVerilogは大げさすぎます。

i14の接続を間違えていてチップが見えなかったのですが、確認して誤配線に気づきEQNファイルを修正しました。

以下をDumpListEditorでwavにしてPC-8001でCLOADします。

```
10 C=&HFD
20 D=&HFC
30 OUT C, 1
40 PRINT INP(D)
```

![IMG_20210715_182308.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a0caa657-2b41-41b2-7451-8af8172c431b.jpeg)

[SD-DOS](https://github.com/chiqlappe/SD-DOS)をポートできないか調べてみるつもりです。

アセンブラめんどくさいなと思って調べていたら、なんとすでにアセンブラのコードを書いている人がいましたが、初期化の部分しかないようです。

https://github.com/anchorz/z80-ch376

MSXにつなげてる人もいました。

http://rookiedrive.com/en/home/

Atariで使えるようにした人もいました。

http://bhabbott.net.nz/micro_expander.html

おそらくCH376には8051系のCPUが入っているような気がします。PC-8001の純正のFDDにもZ80が入ったので8Bit CPU間でのデータ処理という事では同じ手法とも思えます。

PC-8001のBASICでUSBメモリのファイルを読み書きできるようになりました。

https://github.com/yamori813/CHOS

![CHOS_ORIGINAL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/2cc27bdd-abdf-8560-3dd6-c1c5ea43b0e0.png)
Vue-Component に Bootstrap の Cleckbox Class をあと付けする

# 環境
Vue.js
Bootstrap
javascript
css

# 前の記事
https://qiita.com/ryo2020/items/1092427d7b8f2d82a80b

# 結論

```javascript:app.js
const bootStrapCkeckbox = Vue.component('bootstrap-checkbox', {
    template:`
    <div>
        <template
            v-for"(opt, idx) of options"
        >
            <div
                :key="idx"
                :class="classes.div||''"
                >
                <input
                    type="ckeckbox"
                    :class="classes.input||''"
                    :name="name"
                    :id="name+idx"
                    :checked="value.indexOf(opt) !== -1"
                    v-bind:value="opt"
                    v-on:change="onChange"
                />
                <label
                    :for="name+idx"
                    :class="classes.label||''"
                >
                {{opt}}
                </label>
            </div>
        </template>
    </div>
    `,
    name:String,
    props:{
        classes:{
            type:Object,
            default: () => {
                return {
                    input,label, dev
                };
            }
        },
        value:{
            type:Array,
            default: () => {
                return [];
            }
        },
        options:{
            type:Array,
            default: () => {
                return [];
            }
        }
    },
    data(){
        return {
            values:[]
        };
    },
    methods:{
        onChange(event){
            let elem = event.target;
            let val = elem.value;

            if(elem.checked){
                this.values.push(val);
            }else{
                this.values = this.values.filter((v) => {
                    return (v !== val);
                });
            }

            //update bind value.
            this.$emit('input', this.values);
        }
    },
    created(){
        //Memory of initial selection value.
        this.values = this.value.concat(this.values);
    }
});

let app = new vue({
    el: '#app',
    components: {
        'bootstrap-checkbox': bootstrapCheckbox
    },
    data: {
        values: ['りんご']
    }
});
```

```html:index.html
<div id="app">
    <fieldset class="form-group">
        <div class="row">
            <legend
                class="col-form-label col-sm-2 pt-0"
            >Vue-Component Bootstrap Checkbox Demo</legend>
            <bootstrap-checkbox
                name="checkbox_demo"
                class="col-sm-10"
                :options="['りんご','みかん','なし']"
                :classes="{
                    'div':'form-check',
                    'input': 'form-check-input',
                    'label': 'form-check-label'
                }"
                v-model="values"
            >
            </bootstrap-checkbox>
        </div>
    </fieldset>
</div>
```

# 参考
上記のコードを参考の事

## メモ
* Vue-Component で Class 属性の binding は、template の一番外側（親要素）にしか binding されない
* 子要素とも言えない template の内部要素に関しては、props 経由でやるしかない（私が知る限り）
* Vue-Component の汎用性は下がるが、Bootstrap を選択した時点で、ある程度は Bootstrap 側の仕様に合わせたほうが得策なので、一旦目をつぶる
[React Native] ScrollView, FlatList使用時のwarning修正



```
 WARN  VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
```

## 原因
ScrollViewの中にflatListを入れている

## 解決策
リストと一緒にスクロールしたいコンポーネントは flatList の以下の props に渡す。
・ ListHeaderComponent
・ ListFooterComponent

## 参考文献
以下の情報を参考にさせていただきました。

https://nyxo.app/fixing-virtualizedlists-should-never-be-nested-inside-plain-scrollviews

https://reactnative.dev/docs/flatlist#listfootercomponent
Laravelのテスト用接続先データベースを切り替える

# 経緯
TDDを使ってLaraveで開発する。
開発環境でちょくちょくテストを動かすことになるが、
テスト実行しているとデータベースが汚れてしまう。(*1)
このためテストだけのデータベースを別にしたい。


# 設定
データベースを２つ用意
ひとつは mydev
もうひとつは mydev_testing
ユニットテストでは mydev_testing データベースを使う。

# やりかた .envを２つ作る方式でやる
通常の開発用の設定は .envファイルに記述。
ユニットテストでは .env.oreore_testing ファイルに記述。
Laravelのプロジェクトルートにある
.envをコピーして .env.oreore_testing ファイルを作る。
.env.oreore_testingのデータベース接続先を mydev_testing に変更する。

# phpunit.xmlを変更
APP_ENVのところにテスト設定ファイルの後ろの部分を記述。
こんな感じ

```xml
    <php>
・・・中略・・・
        <server name="APP_ENV" value="oreore_testing"/>
・・・中略・・・
    </php>
```
# 追記 2021/10/27
Laravel 6.20の環境でphpunit.xmlのAPP_ENVをoreore_testingに切り替えたら、Session is missing expected key エラーが出た。
phpunit.xmlの
         bootstrap="tests/bootstrap.php"
を
         bootstrap="vendor/autoload.php"
に切り替えて、エラーを回避した。



注 *1
use DatabaseTransaction;を使うとテストが終わった時にrollbackするので、データベース汚れないですが、
テスト実行終了時にどんなデータが残ってたか確認できないと開発やりにくいから、use DatabaseTransaction;は使わない。
便利なコマンドの紹介(ターミナルで昔実行したコマンドを検索する方法)

# 昔打ったコマンドを思い出せなくて困った時はないですか？
今回皆様のその悩みを解消するコマンドを紹介します。上級者はターミナル(bash shell)で使えるコマンドは頭に入っていると思うので、昔打ったコマンドが思い出せなくて困っている方のみこのページを見てください。

# 今回使うターミナルのコマンド

* history
* grep

##history
　historyコマンドとはターミナルで前に実行したコマンドを全て出すことができる。

```ruby:qiita.rb
# 自分のターミナルで実行
history

# 出力(結果)
# 316  cd ..
# 317  ls
# 318  cd final_execise
# 319  ls
# 322  python synonyms.py
# 328  cd ..
# 329  ls

```
こんな感じ

ここから何かを検索するためにgrepを使います

## grep　[文字列]

このコマンドはgrepの後に文字列を入れ、その文字列が入っている文章を取り出します。
grepとhistoryを組み合わせて、ターミナルから検索したいと思います。

その時に必要なことがもう一つだけあります。それは|です。何を言っているのかわからない人もいると思いますが、|について詳しく説明したいと思います。

## これ→ |

これはコマンドとコマンドをつなげる記号です。コマンドとコマンドの間に挟むことでふたつのコマンドを同時に実行しすることができます。

## 便利な検索の紹介

今回は先ほどのhistoryからgrepを用いて、「python」が含んでいるコマンドを取り出したいと思います。

```ruby:qiita.rb
# 自分のターミナルで実行
history|grep python

# 結果
#327  python synonyms.py

```

このコマンドは意外と使えます

便利なコマンドの紹介でした。
AWSの自動デプロイ設定を行ったら、画像が表示されなくなった(Railsアプリ)

##はじめに

オリジナルアプリの完成が近づいてきました。もっともっと盛り込みたい機能が山ほどあるのですが、転職活動のほうも疎かにできないので、とりあえずAWSにはデプロイしようということで作業を進めていました。

AWSにデプロイするにあたって、アプリの改修などをした際に、結構たくさんのコマンドを打たなければならなくて、大変なので自動デプロイを導入しました。

Capistranoという自動デプロイツールを使って導入したのですが、完成後、手動デプロイしていた時にはしっかり表示されていたアプリ内で使われている画像たちが表示されなくなってしまいました。

~~明確な理由はわからないまま、自分なりに仮説を立てて解決できましたので記事に残しておきます。~~
よろしくお願いします。

##画像が表示されなくなった
私の画像は```app/assets/images```の配下に置いていて、img_tagで呼び出していました。
手動でデプロイを行なっていた時は、ちゃんと呼び出されていたのですが、自動デプロイをした後に小さな画像が壊れたようなマークだけが表示されて、目的の画像が表示されていなくなりました。



確実に自動デプロイの過程で問題が生じたとしか考えられませんでしたので、その辺を振り返っていたところ、そういえばアプリのファイルたちの階層を一段階深くしたために、パスを書き換えた作業を思い出し、これが怪しいんじゃないかと思いました。

##解決

もしかするとパスが変わっているのかもと思い、その周辺をネットで嗅ぎ回っていたところ、やはり自動デプロイの際に画像がコンパイルされ、パスが変わるのだとおっしゃっている方がいました。あまり意味はわかっていませんが。。。

その方が言うには↓（下記のコードは私のコードをもとに作成しています）

```erb
<%= image_tag "Textbook student.png" %>
```

このようなコードを

```erb
<%= image_tag asset_path("Textbook student.png"%>
```

というふうに書き換えることで解決できるそうなので試してみました。
しかし、私の場合うまくいきませんでした。。。

パスが悪いのかどうかわからないですが、他にパスを書き換えるとしたら、、、と考えていたら一つ思い浮かびました。
もしpublicフォルダの配下に置いたらどうなるのかな、と思いまして、画像たちをpublicフォルダ配下へお引越しさせ、パスを下記のように書き換えました。

```erb
<%= image_tag "/Textbook student.png" %>
```

public配下の時は相対パスで``` / ```を置いてあげるだけで場所を示せるのですね。
初めて知りました。

これでどうだと言わんばかりにデプロイしてリロード押したら、見事に画像の表示に成功しました！

##本当の解決
実はこの記事を書いた後に、理由が判明しました。
自動デプロイをした際にいじっていたNginxの設定に記述ミスがありました。
こちらその設定画面↓

```conf
upstream app_server {
  # Unicornと連携させるための設定
  server unix:/var/www/リポジトリ名/shared/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name Elastic IP;

  # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
  client_max_body_size 2g;

# 接続が来た際のrootディレクトリ
  root /var/www/リポジトリ名/current/public;

# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    root /var/www/リポジトリ名/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}
```

コメントアウトで「**assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定**」と書かれている中の、リポジトリ名に置き換えるところを、置き換え忘れていました。

通りでpublicだったら反映されたわけですね。。。
今後気をつけたいと思います。


##最後に
~~assetsの配下に置いていた画像も実は一部ちゃんと表示はできていたので、パスはあまり関係なかったと思います。画像の容量が大きかったのかなと言う気もします。わかる方がいればコメントお願いします。~~
ネットを徘徊していた時に思ったことは、本来publicの使い方とassets/imagesの使い方はそれぞれ特徴があり、どこに画像をおくべきかはいろんな意見があるように感じました。

またちゃんと理解した時に記事書けたらなと思います。
Vue.js で Checkbox を Template 化する

#環境
vue.js
javascript

#やりたいこと
* Vue-Component を用いて、data-binding しつつ、選択肢としての options も Component 外部から渡したい。
* data-binding されている値が、options に含まれているのであれば、初期選択状態にしたい。
* 可能な限り再利用可能な汎用的な構成にしたい

#結論

```javascript:app.js
const vueCkeckbox = Vue.component('vue-checkbox', {
    template:`
    <div>
        <template
            v-for"(opt, idx) of options"
        >
            <div :key="idx">
                <input
                    type="ckeckbox"
                    :name="name"
                    :id="name+idx"
                    :checked="value.indexOf(opt) !== -1"
                    v-bind:value="opt"
                    v-on:change="onChange"
                />
                <label
                    :for="name+idx"
                >
                {{opt}}
                </label>
            </div>
        </template>
    </div>
    `,
    name:String,
    props:{
        value:{
            type:Array,
            default: () => {
                return [];
            }
        },
        options:{
            type:Array,
            default: () => {
                return [];
            }
        }
    },
    data(){
        return {
            values:[]
        };
    },
    methods:{
        onChange(event){
            let elem = event.target;
            let val = elem.value;

            if(elem.checked){
                this.values.push(val);
            }else{
                this.values = this.values.filter((v) => {
                    return (v !== val);
                });
            }

            //update bind value.
            this.$emit('input', this.values);
        }
    },
    created(){
        //Memory of initial selection value.
        this.values = this.value.concat(this.values);
    }
});

let app = new vue({
    el: '#app',
    components: {
        'vue-checkbox': vueCheckbox
    },
    data: {
        values: ['りんご']
    }
});

```

```html:index.html
<div id="app">
    <fieldset>
        <legend>Vue-Component Checkbox Demo</legend>
        <vue-checkbox
            name="checkbox_demo"
            :options="['りんご','みかん','なし']"
            v-model="values"
        >
        </vue-checkbox>
    </fieldset>
</div>
```

# 参考
上記コードを参照の事
独学プログラマーのまとめ　その3

#初めに
本章からより重要度があがった気がする。


###4章　関数

- 関数は1つのことをすべきで、そのことに特化するべき。

- **関数を呼び出す**とは、その関数が必要とする入力値(**引数**)を渡し、命令を実行し、出力値を返すこと。
- 関数定義はdefで行いここでも**:(コロン）**が大事になってくる。

```python
# def [関数名]([引数]):
#     [〜関数定義〜]

def f(x):
    return x * 2
```

- 組み込み関数
    - 最初から用意されている関数。前回もprint関数を用いていた。
    - len,str,int,float,などがあり、使いながら覚えるとよい。
    - 必須引数とオプション引数がある。必須引数がないとエラーとなる。
- スコープ
    - 変数を読み書きできる範囲のこと。グローバル変数、ローカル変数。
- 例外処理 
    - tryとexceptで例外処理が行える。

```python
a = input("type a number:")
b = input("type another:")
a = int(a)
b = int(b) 
try:
    print(a / b)
except ZeroDivisionError: 
    print("b cannot be zero.")
```


 

# まとめ
例外処理を覚える
Linuxのtreeコマンドで罫線が文字化けする

# 現象
TeratermでAmazon Linuxにつなげてtreeコマンド実行したら文字化けした。
<img width="600" alt="2021_07_15 17_43_51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461268/6296b9d6-7755-bf00-d9ad-ff7722c42801.png">

# 対策
`--charset=C`オプションをつけたら表示されるようになった。
<img width="600" alt="screen_img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461268/9ae86d77-a740-fc35-5c21-75f218abefa3.png">
C#でテキストファイルを読み込む方法 

本記事は以下のURLをもとに、<strong>C#(VisualStudio2019)でのテキストファイルの入出力を説明してみる試み</strong>です。

・StreamWriter クラス
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.streamwriter?view=net-5.0

・StringReader クラス
（https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stringreader?view=net-5.0
→StreamWriterと対になっているのは、このURLだと思いますが、こちらは意図した通りに動かなかったので、以下を参照。）
https://docs.microsoft.com/ja-jp/dotnet/standard/io/how-to-read-text-from-a-file

まず、最初にプログラム冒頭で以下を定義
using System.IO;

StreamWriterのサンプルコードは以下。Cドライブの中身を.txtファイルに吐き出させます。

```C#:qiita.C#
namespace StreamReadWrite
{
    class Program
    {
        static void Main(string[] args)
        {
            // Get the directories currently on the C drive.
            DirectoryInfo[] cDirs = new DirectoryInfo(@"c:\").GetDirectories();

    // Write each directory name to a file.
            using (StreamWriter sw = new StreamWriter("CDriveDirs.txt"))
            {
                foreach (DirectoryInfo dir in cDirs)
                {
                    sw.WriteLine(dir.Name);
                }
            }

            // Read and show each line from the file.
            string line = "";
            using (StreamReader sr = new StreamReader("CDriveDirs.txt"))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
         }
    }
}
```


これを実行することによって、Cドライブ直下のファイルのリストを
以下のフォルダに.txt形式で取得できます。
C:\Users\xxxx\source\repos\xxxx\xxxx\bin\Debug
（xxxx:各PCの設定に依存）

引き続き、このファイルを読み込むために以下のサンプルプログラムを使用します。


```C#:qiita.C#
namespace StreamReadWrite
{
class Program
    {
        public static void Main()
        {
            try
            {
                // Open the text file using a stream reader.
                using (var sr = new StreamReader("CDriveDirs.txt"))
                {
                    // Read the stream as a string, and write the string to the console.
                    Console.WriteLine(sr.ReadToEnd());
                }
            }
            catch (IOException e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }
        }
    }
```



new StreamReader部分でテキストファイルを吐き出させたファイル名を指定すれば、読み込むことができます。
また、try-catch関数を使うことによって、
ファイルがない場合、ファイルが指定のフォルダ直下に無い旨を、コマンドプロンプト上のエラー文で明言できます。
KintoneカスタマイズをReact+webpackでやる

## やろうと思ったきっかけ
* 複数アプリで同じような記述が増えていき、いろいろと共通化したかった（これが一番）
* 上記に似ているが、複数アプリに同じファイルを適用していると、変更時に差し替えるアプリを把握しきれなかった＆その作業時間が無駄だなと感じた
* 素のjavascriptで書くのに疲れた＆Reactを使いたかった

## 導入時にしたこと
* [目指せ！JavaScriptカスタマイズ中級者（１） 〜webpack編〜
](https://developer.cybozu.io/hc/ja/articles/360040220451-%E7%9B%AE%E6%8C%87%E3%81%9B-JavaScript%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E4%B8%AD%E7%B4%9A%E8%80%85-%EF%BC%91-webpack%E7%B7%A8-)(CDN)　を参考にしました
* npmでReactを入れる
  * バージョンの相性があるみたいで、私は以下のバージョンで使っています（困ったのはこの辺だったと思う、、曖昧）

|  package  |  version  |
| ---- | ---- |
|  react  |  16.8.6  |
|  react-dom  |  16.5.2  |
|  webpack  |  4.44.2  |
|  webpack-cli  |  3.3.12  |
|  webpack-dev-server  |  3.1.14  |
|  style-loader  |  2.0.0  |
|  css-loader  |  5.2.6  |

* babelrcの設定
  * 正直よく分かってないけどReact使うにはpresetsをこうしないといけないっぽい。（babelrcを理解してない）

```js:.babelrc
{
  "presets": [
    [ "@babel/preset-react", 
      {
      "targets": { "node": true }
      }
    ],
    [ "@babel/preset-env", 
      {
      "targets": { "node": true }
      }
    ]
  ],
  "plugins": [
      "@babel/plugin-proposal-class-properties"
  ]
}
```

## これまで作ったモジュールの移行＋αでやったこと
* src/commonに、大量データ処理用APIを置いた。
  * GETは　[レコード一括取得の JavaScript コーディング例：カーソル API を利用する方法](https://developer.cybozu.io/hc/ja/articles/360031191791#use_cursor)(CDN)　を参考に
  * POST/PUT/DELETEは　[【kintone】上限を気にせずPOST, PUT, DELETEする](https://localbias.work/1559)　を参考に
* [kintone UI Component](https://www.npmjs.com/package/@kintone/kintone-ui-component) v0.8.0 を入れた
  * v1系はReact非対応だそう。最初v1を入れてしまい、ちょっと悩みました
* [kintone-spinner](https://www.npmjs.com/package/kintone-spinner)を入れた
* [ReactでFont Awesome 5を使用する方法](https://www.digitalocean.com/community/tutorials/how-to-use-font-awesome-5-with-react-ja)　を参考に、Font Awesomeを入れた
* style-loaderとcss-loaderを入れた

## 感想
* 最初からこれでやればよかった。が、Kintoneを触り始めた時はこんな風にできるとは知らなかったので、Kintoneに慣れてきたこの時期にできたのは良かったと思います。
* webpack導入前から[customize-uploader](https://developer.cybozu.io/hc/ja/articles/360015889812-customize-uploader%E3%81%A7%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E7%94%A8%E3%81%AEJS-CSS%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%8B%E3%82%89%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%82%88%E3%81%86-)を使っていて、その時は保存したら自動アップロードしてくれていましたが、webpack入れてからは保存→``npm run build``でビルド→自動アップロードという手順になるので、うっかりビルド忘れたら変更が反映されず、え？ってなることが多々あるので慣れるまでは気を付けないとです。
* 他にもエラー出たところたくさんあった気がしますが、もうよく覚えていないので、この辺で。
RedshiftのCOPYコマンド実行中の特殊ケースにおける挙動

## 概要

S3上にあるParquetファイルをRedshift内部テーブルへインポートするためCOPYコマンドを実行。データ量が多く、COPYコマンド完了までに数時間かかった。その間、別のバッチが動き、COPYコマンド実行中のS3パスに対してのデータ出力とCOPYコマンド実行が走ってしまった。その際の挙動について記載します。
(2021/07/15時点の内容です。)

## ケース

S3上にあるParquetファイルをRedshift内部テーブルへインポートするためCOPYコマンドを実行。（データ量が多く、完了に数時間かかる）
上記実行中に別のデータ処理バッチが動き以下のヤバそうな処理が実行される。（上記実行開始してから数分後です）
(1)上記COPYコマンドのFROM句に指定しているS3パス配下にParquetファイルを出力（Unloadコマンドによる）
(2)さらに(1)で出力されたファイルをRedshift内部テーブルへインポートするCOPYコマンドを実行（対象テーブルは上記COPYコマンドと同一）

## 挙動

まず(2)については、処理が開始されない（エラー終了するわけでもない）。最初に実行しているCOPYコマンドによって該当テーブルへの書き込み処理がロックされてる感じ？ （コマンド実行は中断させたので放置していたらどうなっていたかはわかりません）
(1)については、出力は問題なくされました。気になるところは最初のCOPYで、この後から出力されたファイルがCOPYの対象になるかどうかですが、対象になりませんでした。タイミングによっては変な動きとかするかもしれませんが、基本的にCOPYコマンドを実行した時点でCOPY対象をファイル単位で確定させているという感じですかね。

## 感想

上記のケースは特殊ケースかつRedshiftの操作としてよろしくないものであり、本来防ぐべき事象だったかと思いますが、Redshift側の挙動は非常に助かる最善と言っていい動きだったと思います。
未経験からCCNA取得までの道のり　ver11

WLCの論理インターフェイスと物理ポートがごちゃごちゃになって、問題解く時に間違えまくったからアウトプット！！
___

WLCの論理インターフェイス

🚩Serviceインターフェース
サービスポートと関連づけられるインターフェイス！
(アウトバンド管理)

🚩Managementインターフェース(管理インターフェイス)
WLCの管理用インターフェイス、WLCの設定時のアクセス先や、Pingの宛先や、WLC間の通信の制限などで使用する。
(インバンド管理)

🚩Virtualインターフェース(仮想インターフェイス)
仮想インターフェースで、モビリティがある。DHCPサーバとして認識される。

🚩Dynamicインターフェース(動的インターフェイス)
SSIDとVLANのマッピングを行うインタフェース
_______________

WLCの物理ポート(WLCと他のデバイスを接続する際に使用)

🚩コンソールポート
・コンソールケーブルによりPCと接続
・WLCの設定や、WLCの障害対応を行うために使われる

🚩ディストリビューションシステムポート
・LANケーブルによりスイッチと接続(スイッチ側はトランクポートモードにする)
・通常にトラフィックや管理トラフィックを送受信するために使われる
・LAGに対応(複数のポートを同一のスイッチに接続して帯域幅を拡張する技術)

🚩サービスポート
・LANケーブルによりスイッチと接続(スイッチ側はアクセスポートモードにする)
・ネットワーク障害時のシステム復旧とメンテナンスで使用するアウトオブバンド管理になる(通常のトラフィックは流さない)ので、ディストリビューションシステムポートで輻輳などがあっても影響を受けずに障害対応が可能

🚩冗長ポート
・LANケーブルによりWLCと接続
・大規模なネットワークでWLCを冗長化するために使われる

___
※サービスポートと冗長ポートはWLCの上位機種に備えられている
※アウトオブバンド管理=一般ユーザのトラフィックと管理トラフィックを分ける方式(上位機種ではこちらが可能になる)
※インバンド管理=一般ユーザのトラフィックと管理トラフィックを分けない方式
No route matches [POST]  エラー解決方法　form_with namespace使用時

<h3>前提</h3>
ECサイトを作成しています。
商品登録ページで以下のようなルーティングエラーが発生しました。

今回、namespaceを使い管理者側(admin)、顧客側でルーティングをわけていました。
![スクリーンショット 2021-07-15 17.32.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/8a4dc10c-afa3-2082-ca9c-135db6a33f7b.png)


<h3>エラーの内容</h3>
![スクリーンショット 2021-07-15 17.35.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/06723793-d479-eafa-0b67-df27ce2e72c0.png)

createアクションはあるし、POSTになっている。
![スクリーンショット 2021-07-15 17.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/3c023a3f-ff8b-5066-e972-5e20658ae4bd.png)

<h3>解決方法</h3>

```<%= form_with model:@item, local:true do |f| %>```を、以下の通り書き換え。

```
<%= form_with model:@item,url:admin_items_path,local:true do |f| %>
```

データが、form_withの判断で/itemsに送られていました。
namespaceを使っており、本来飛ばすべき先は、admin_items_pathでした。



<h3>エラーの原因はform_with namespace使用時には注意！</h3>

```<%= form_with model:@item, local:true do |f| %>```

商品の新規登録画面でform_withを用いてフォームを作成していました。

```<%= form_with model:@item, url:'admin_items_path', local:true do |f| %>```

このようにフォームで入力したデータの送信先をurlで指定することもできるというのは知っていましたが、
resoucesを使用してルーティングしていたので、urlの指定は不要という認識でいました。
Gradleでbootstrap導入

java開発でbootstrap導入の場合、以下の3つの方法がある。

* CDNのURLを貼り付ける ※公式サイトの「[Getting Stared (v.4.6)](https://getbootstrap.com/docs/4.6/getting-started/introduction/)」参照
* bootstrapからダウンロードして配置する  ※公式サイトの「[Getting Stared (v.4.6)](https://getbootstrap.com/docs/4.6/getting-started/introduction/)」からDownloadできる
* WebJar for BootstrapをMVN Repositoryから取得 **※今回はこの方法の紹介**

# 前提環境

* Java 11
* Spring Boot 2.5.2
* Thymeleaf 3.0.12

# 導入方法

## gradle

```gradle
dependencies {
(省略)
	implementation 'org.webjars:jquery:3.5.0'
	implementation 'org.webjars:bootstrap:4.4.1-1'
(省略)
}
```

## thymeleaf

```html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" lang="ja">
<head>
<link th:href="@{/webjars/bootstrap/4.4.1-1/css/bootstrap.min.css}" rel="stylesheet"/>
</head>
<body>
    <script th:href="@{/webjars/jquery/3.5.0/js/jquery.min.js}"></script>
    <script th:href="@{/webjars/bootstrap/4.4.1-1/js/bootstrap.min.js}"></script>
</body>
</html>
```