OmniAICreator/Qiita-1.07M huggingface dataset:
nginx digest認証でnonceの有効期限を変更する

#nginxのDigest認証が切れるタイミング
とある業務で、nginxでダイジェスト認証を載せています。
お客さんから、ダイジェスト認証の認証が切れるのっていつ？と質問され、auth_digest_timeoutで指定された時間(デフォルト60秒)ですよと答えたが、これが全然違った。

認証してからauth_digest_timeout時間経過しても、認証用ポップが表示されないという。。
試してみると、auth_digest_timeoutを10秒にして、1分放置しても全然問題ない。。。
いや、401は返されるが、WWW-Authenticateにstale=trueが設定されない！

#原因
なんで？ということで、ソースを確認。
ダイジェスト認証のnonceを捨てる時間は、auth_digest_drop_timeでした。
auth_digest_drop_timeを秒単位で設定(デフォルト300)し、この時間が過ぎるとnonceを捨てていました。
[公式のGitHub](https://github.com/samizdatco/nginx-http-auth-digest)にも書いてなかったので、記事にしてみました
さくらのVPSの Ubuntu 19.10 で IPv6 接続を有効にする

_さくらのVPSに限定した内容ではないけど、久々に契約したさくらのVPSで Ubuntu 19.10 を使ってセットアップしてみたので、その時のメモを。_

さくらのVPSのバージョンは v5 でした。

VPSを契約すると、コントロールパネルで IPv4 と IPv6 のアドレスが割り当てられてるのが確認できます。
ただ、標準のセットアップ直後だと IPv6 が有効になっていないので netplan の設定ファイルに固定アドレスを書いてあげる必要がありました。

今回はひとまず、以下のファイルに v6 のアドレスを追加して `sudo netplan apply` した後、外部から IPv6 で SSH 接続できるようになりました。

```/etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      addresses:
          - "IPv4のアドレス"
          - "IPv6のアドレス"
      gateway4: IPv4のゲートウェイ
      gateway6: IPv6のゲートウェイ
      nameservers:
          search: [ vs.sakura.ne.jp ]
          addresses:
              - "IPv4のDNS"
              - "IPv6のDNS"
```
kerasをインポートしようとしたらFutureWarning：numpyダウングレードで解決

### 環境
- OS:macOS Catalina
- python:                    3.7.4
- tensorflow:                1.14.0
- keras:                     2.2.4
- numpy:                     1.17.2

###状況
機械学習関連の書籍のサンプルを動かしている際の出来事です。
jupyter notebookでkerasをインポートしようとした矢先、以下のエラーが表示されました。
`import keras`
`Using TensorFlow backend.
〜略〜
FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.`

### 対処・結果
numpy 1.17.2がtensorflow 1.14.0に対応していないのが原因と思われる。
numpy 1.16.4にダウングレードを行った。
`conda install numpy==1.16.4`
jupyter notebookを立ち上げもう一度kerasをインポート すると無事以下の表示がされた。
`Using TensorFlow backend.`

### 参考
[[備忘録] tensorflow-rocmでimport時にnumpyのFutureWaringが出た話]
(https://qiita.com/Tarooo000/items/dcce992672c7ea539049)
【PHP】配列の順番が変わった時でも、あまりコードを変更しないで値を取得する方法を考えてみた

CSVファイルを読み込んだ時って、各項目を配列にして処理したりしますよね。
で、`$email = $csvData[5];` みたいにインデックス指定で値を取得したりして。

そして、ある時に突然の仕様変更。

末尾に項目が追加になれば何の問題もないんですが、途中に項目が追加されたら大変です。

今まで`$csvData[5];`で取れてたemailが、`$csvData[6];`になり、それ以降の項目もインデックス値が全部ズレてきてしまう。
項目数が5、6個だったらまだマシだけど、これが50個あったりすると修正ミスも起きやすいでしょう。

そこで、インデックス指定をしないで、配列から値を取得する方法を考えてみました。

#環境
- php7.3
- laravel5.8

#流れ
- CSVファイルの読み込みクラスを作成
- コンストラクタでインデックス変数を定義
- あとは変数を使って配列から値を取得する

#具体例

```php
public class MyCsv{
    public function __construct()
    {
        $this->setIndex();
    }

    private function setIndex(){
       collect([
           'ID',
           'NAME',
           'EMAIL',
           'TEL',
           'ADDRESS',
       ])->each(function($v, $i){
           //メンバー変数（配列のインデックス定数）を動的に生成。順番が大切
           $this->$v = $i;
       });
    }

    /**
     * CSVの1レコードを取得してなんかやる
     * 
     * @param array $csvRecord 1レコードのデータ配列
     */
    public function logic(array $csvRecord){
        $id = $csvRecord[$this->ID];
        $name = $csvRecord[$this->NAME];
        $email = $csvRecord[$this->EMAIL];
        $tel = $csvRecord[$this->TEL];
        $address = $csvRecord[$this->ADDRESS];
    }
```

こんな感じで作っておく。

・・・そして、ある日、仕様変更がはいる。

>「名前」の後ろに「ふりがな」を追加して、「電話番号」の後ろに「携帯番号」を追加するよー。

こんな時でも`setIndex()`の該当場所に項目を追加するだけで、値を取得しているコードの変更はなし。

```php
public class MyCsv{
    public function __construct()
    {
        $this->setIndex();
    }

    private function setIndex(){
       collect([
           'ID',
           'NAME',
           'KANA', //追加
           'EMAIL',
           'TEL',
           'TEL_MOBILE', //追加
           'ADDRESS',
       ])->each(function($v, $i){
           //メンバー変数（配列のインデックス定数）を動的に生成。順番が大切
           $this->$v = $i;
       });
    }

    /**
     * CSVの1レコードを取得してなんかやる
     * 
     * @param array $csvRecord 1レコードのデータ配列
     */
    public function logic(array $csvRecord){
        $id = $csvRecord[$this->ID];
        $name = $csvRecord[$this->NAME];
        $email = $csvRecord[$this->EMAIL];
        $tel = $csvRecord[$this->TEL];
        $address = $csvRecord[$this->ADDRESS];

        //追加で取得する項目
        $kana = $csvRecord[$this->KANA];
        $telMobile = $csvRecord[$this->TEL_MOBILE];
    }
```
Rubyの学習を始めた

 #Rubyの勉強を始めた。
- 理由
    - 時間にゆとりができたから。
    - WEB アプリ系をつくってみたいとふと思ったから
    - 実務では使うことはないが、知識として触って観たかった。
    - １ヶ月くらいで基礎はできるようになりたい。
    - つまり、ほぼ興味。

#今回の練習
- 今回は、ドットインストールで数当てゲームというものを作成した。
- 意外とシンプルにかけるので驚いた。
- ドットインストール久しぶりにプレミアム会員。


``` main.rb
answer = rand(10) + 1
count = 0

loop do
  print "Your guess? "
  guess = gets.to_i
  # count = count + 1
  count +=1
  
  
  if answer == guess
    puts "Bingo! It took #{count} guesses!"
    break
  elsif answer > guess
    puts "Bigger!"
  else
    puts "Smaller!"
  end
end 
```



#概略
概略
    - 数値を入力してその値がランダムの数字とあっているかを確認して、その数値の代償に合わせて、コメントを返す簡単な仕組み。
    - C系をずっとやっていたので、書き方がシンプルですこし違和感がある。セミコロンで終わりがないやつ。とか、はじめと終わりがなかなかわかりづらくて驚いた。
    - else if がelsif と書くのは、気づくのに、数分かかった。確かに短くて便利

#学んだんこと
 - 出力:puts
 - プリント： print
 - ランダム：rand (値)
 - 条件分岐 : if elsif break else end 
 - コメント: #
 - 長文コメント:=begin , =end
 - 入力: gets
 - 改行なし： .chomp
 - 整数入力: gets.to_i

#感想
はじめて触ったがすごく書きやすい。
もう少し勉強しよう。
PHPページの入力フォームでキーワード確定に使用するキー

モバイルアプリ入力フォーム画面でキーワードフィールドへの入力内容の確定に全角カンマ「、」を半角カンマ「,」の代わりに使う方法ご存知ですか。英語圏は半角カンマで機能しているそうですが、全角対応がPCで可能になったのですが、モバイルが機能せず、かつ海外の開発者再度の日本語入力画面では、全角カンマが機能するように修正されています。同様の事例で解決した事あるかたアプローチをシェアいただけないでしょうか。
AWS Lambdaで毎日料金を取得する

# AWS Lambdaで毎日料金を取得する

## TL;DR
AWSのダッシュボード見たほうが早い

## はじめに
監視しようがしてなかろうが、どのみちAWSのコンソールを常に開いている人にとっては、AWSのダッシュボード見たほうが正確で早いです。

しかし、そこまでAWS漬けでもない人にとってはいちいちAWSのコンソールを開き、料金やインスタンスの稼働状況を確認するのは面倒です。そこでSlackに稼働状況を監視して通知するAWS Lambdaの関数を定義して、楽して監視するようにします。


## やりたいLambda関数の疑似コード

* EC2の全インスタンスを取得する
  * タグ情報を取得し、稼働状態を列挙する 
* CostExplorerから料金情報を取得する
  * 現時点の料金を出力
  * 現時点の料金を日数で割り、月の日数倍して予想価格を出す  

料金は直近の1日分料金を取得し、その金額を月の残りの日数分足したほうが正確ですが、これはこれで1日だけ異様に活発だった時等に瞬間風速に引きずられてそこまで正確じゃないので、今回は今までの平均が一番平均に近いという事にします。

## AWS Lambdaでの関数の作成

Lambdaの関数作成(Hello worldする物)は他にいくらでも情報があるので、そちらを参照ください。
権限周りの問題がでなければ、何か見るよりAWSの画面みたほうがわかりやすいです。


関数の作成のため、ユーザーにはiam:PassRoleの権限が必要でした。
関数自体のロールの権限は、以下を付与しました。

実際にコードに書いたメソッドと同じ名前の定義があるので、拡張する場合は適宜追加が必要です。

```
"ec2:DescribeInstances",
"ce:GetCostAndUsage"
```

## nodejsでのAWS sdkの使い方

node.jsからAWS SDKを使う際は、以下にAPIの一覧があります。

* https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html

ほとんどの場合aws cliの記法が正しく、ドキュメントが豊富です。
node.jsであっても同じように書けるので、aws cliの操作を参考にnodeに移行したほうが作りやすいと思います。

> APIドキュメントは何がどう返ってくるのか説明があまりなく、これだけみて作るはかなり難しいと思います。
> 
> 例えば、ローカル環境等で開発する場合~/.aws/credentialsを作成したり、AWS.credentialsでトークンを設定します。
> AWS Lambdaで実行する場合は、AWS.credentialsで権限上書きをしようとしても、関数に割り当てたロールの権限で自動的に初期化され書き換えが行えず、初期化処理も勝手に終わるので、適当に書いてもなんか動きます。

## 実コード

### 実物
https://github.com/ksuzukiTVDn1/awsPriceChecker

### Lambdaへの展開
展開にあたり、aws-sdkはLambda上に既に存在しているため、それ以外のnode_modulesをZIP化してアップロードする必要があります。
アップロードは「コードエントリタイプ」の「.zipファイルをアップロード」から行うことが出来ます。
nodejsにとって必要なlockファイル等は不要です。また、package.jsonをLambda上でいい感じに「npm install」的な事をするという事は出来ません。

### エントリポイント
node.jsの場合、LambdaのエントリーポイントはLambda設定パネルの「ハンドラ」の定義に従って動作するため、デフォルトの「index.handler」の場合、以下が動作します。

* index.js
* export.handler の関数

そのため、今回のコードの場合以下が動作します。

```
# index.js
exports.handler = (event, context, callback) => {
...
  result = ec2_status();
...
  result = costExplorer_status();
...
}
```

### 個々の関数の処理

hanlder関数から呼び出した関数は以下のaws cliの操作を受け持ちます。

* ec2_status
  * aws ec2 describeInstances
* costExplorer_status
  * aws costexplorer getCostAndUsage

処理そのものは返ってくるJSONを掘ってるだけなのでそんなに見どころはないです。
内容を元にslackのpayloadを作成し、slackのhookにPOSTしています。

### 出力例

結果的に以下のような出力が自動的に行われます。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96182/034e43b5-fd68-39e4-c1cf-94cacf365961.png)

### Lambdaの駆動トリガー
関数のトリガーは、Lambdaの「トリガーを追加」から行います。
スケジュール実行の場合は「CloudWatch Events」から定義することができ、cron記法で記載することで定時実行されます。

## まとめ
30日動かしても1円行かないので助かります。
Google Chrome 78以降でMonacaにアクセスした際にサードパーティーCookieでエラーが出る場合の対処法

Google Chrome78以降でセキュリティが向上したようです。Monaca IDEにアクセスすると、次のようなエラーメッセージが出ました。使えないことはないんですが、プレビューサーバに反映されないような状態です。

```
Trying to connect to server. Please make sure that you DO NOT block any 3rd party cookies.
```

![Screenshot_ 2019-11-14 10.54.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/1fbfa2d3-d6bf-39af-2c9e-d2c8c5fa247b.png)

この症状ははてなブログでも確認されていて、サードパーティーCookieをデフォルトで弾くようになったのが影響しているようです。

[Chrome 79（78 以上？） で はてなブログ のヘッダに「サードパーティーCookieが無効になっています」と表示されたり、ニンテンドーアカウントのアイコンがログイン時に表示されずに「ログイン／新規登録」と表示されたりする場合の対処方法 - 約束の地](https://obel.hatenablog.jp/entry/20191026/1572080333)

対処法は上記ブログで書かれている通りで、まず [chrome://flags/](chrome://flags/) にアクセスします。そしてSameSiteで検索します。

![Screenshot_ 2019-11-14 13.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/245572d5-8f18-4e17-5d1b-7051eee52d2b.png)

**SameSite by default cookies** の設定をDisabledにしてGoogle Chromeを再起動すれば完了です。

----

とりあえずはこれで良いとして、今後はサービス提供側で何らかの対応が必要になりそうですね…。
neovim (deoplete.vim + neosnippet.vim ...)でコード補完とかスニペットとか

一応vimrcを以下のようにするといけた。Mac 10.13.6, vimは8.1

```
"
"
" neosnippet
"
" you need to add ~/.vim/snippets/[extension].snip for your own snippets
"
"
Plugin 'Shougo/deoplete.nvim'
if !has('nvim')
  Plugin 'roxma/nvim-yarp'
  Plugin 'roxma/vim-hug-neovim-rpc'
endif

Plugin 'Shougo/neosnippet.vim'
Plugin 'Shougo/neosnippet-snippets'

" Plugin key-mappings.
" Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)
xmap <C-k>     <Plug>(neosnippet_expand_target)

" SuperTab like snippets behavior.
" Note: It must be "imap" and "smap".  It uses <Plug> mappings.
"imap <expr><TAB>
" \ pumvisible() ? "\<C-n>" :
" \ neosnippet#expandable_or_jumpable() ?
" \    "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
smap <expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"

" For conceal markers.
if has('conceal')
  set conceallevel=2 concealcursor=niv
endif
" Enable snipMate compatibility feature.
let g:neosnippet#enable_snipmate_compatibility = 1

" Tell Neosnippet about the other snippets
let g:neosnippet#snippets_directory='~/.vim/bundle/snippets'

" to enable the section below, the following command required:
"
" $ pip3 install --user pynvim
" $ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
" $ sh ./installer.sh ~/.cache/dein
"
if &compatible
  set nocompatible
endif
" Add the dein installation directory into runtimepath
set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim

if dein#load_state('~/.cache/dein')
  call dein#begin('~/.cache/dein')

  call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim')
  call dein#add('Shougo/deoplete.nvim')
  if !has('nvim')
    call dein#add('roxma/nvim-yarp')
    call dein#add('roxma/vim-hug-neovim-rpc')
  endif

  call dein#end()
  call dein#save_state()
endif

filetype plugin indent on
syntax enable

let g:deoplete#enable_at_startup = 1
```

とりま、以下のシェルを実行する必要がありそうだ:

```
" $ pip3 install --user pynvim
" $ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
" $ sh ./installer.sh ~/.cache/dein
```

これで、~/.vim/snippets/[言語名].snip （python.snip/sh.snipとか）を編集すれば、

```
cat ~/.vim/snippets/
python.snip  rust.snip    sh.snip
```
各言語にそくしたスニペットをつくれる、例えば `~/.vim/snippets/python.snip` にて、

```
snippet sample
        import sample
```

`sample` とうって <C-k>(コントロール＋Kボタン)を押すと、 `import sample` を補完してくれる。
（注意: sampleと全部打つ必要あり）

`snippet [エイリアス]` の流れなので、これも注意

こんなかんじかな
Google DriveとColaboratoryの連携問題（？）の解消

*筑波大の佐久間淳先生の[講座](https://www.atmarkit.co.jp/ait/articles/1910/03/news013.html)を勉強してます。*
*Google DriveからColaboratoryのAPPが追加できない事情の解消手順のメモです。*

*接続済みままの状態にはまります。*
*となりのリンク「https\://colab....」をクリックしてください。*
![colab1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/1b80b134-273f-4dcd-766d-d9983c6edc18.png)

*Colaboratoryへようこそを開きます*
![colab2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/d60e9bfc-c5af-406f-eaa4-a5a918a7e78a.png)

*ドライブにコピーを保存をクリック*
![colab3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/96d418fc-7d46-162c-4f0d-ecc8c9800502.png)

*先のページがドライブに保存されたことを確認してください。*
![colab4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/f2d6b17c-5acd-1efe-dd5e-ea3adc040ffc.png)


*再度ドライブの追加ーそのたで見ると...*
![colab5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/39801a92-04db-4b9e-1593-6405c04b1fcf.png)

#おわり
[UE4] BlueprintのBookmark機能


[Window]->[Bookmarks]からブックマークに登録済みの場所やノードを特定することが可能です。
![2019-11-14_13h16_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/e34ac8f7-e836-5aa6-2c9f-8c54e426e55a.png)

☆アイコンを押すと[NewBookmark]登録ボックスが表示されるのでBookmark名を入力すれば完成です。
![2019-11-14_13h17_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/bcd8a15a-92a5-20ca-8f55-7f0f5ae32412.png)

登録済みのBookmarkやCommentは[Bookmarks]タブに一覧として表示し、選択することでBookmarkを付けた箇所にジャンプすることができます。
![2019-11-14_13h22_40.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/22fada13-b4b0-8037-dd83-5f8cb4325083.gif)
vim チュートリアル

#vimってなに?
最高最強のLinux標準テキストエディタさ。もしあなたがvimの虜になりたいというのなら、まず下のコマンドを何も考えず実行しよう。話はそれからだ。

```bash
sudo echo alias emacs=\'vim\'>>$HOME/.bashrc
```

vimにはノーマルモードと入力モードがあって、`i`とか`A`とかで入力モードに移行して、普段は```esc```連打でノーマルモードにして作業します。

##基本操作
###終了方法
vimを学ぶならまず最初に終了方法を学ばなければいけません。かんたん明快、```esc```連打して確実にノーマルモードに移動します。そして

```
:wq
```
これだけで、保存して終了することができます。
`:`でコマンドモードに移行、`white`と`quit`でwqみたいな感じです。
ばらばらでも使える。
###カーソル移動
vimは残念ながら、僕らが慣れ親しんだマウス操作に一切対応していません。もちろんカーソル移動も例外じゃなく、カーソル移動も以下のコマンドで行います。

```
l -> 右移動
k -> 上移動
j -> 下移動
h -> 右移動
```

ちなみに矢印キーでも移動できます。一応。でも矢印キーを使うならvimを使う意味は多分あんまりない。

でもいつも一文字一行ずつ移動してたら生産性なんてあったもんじゃない。さらに便利に移動できる以下のコマンドがあります。

```
w -> 次の単語の先頭に移動
e -> 単語の末尾に移動
b -> 一文字前に移動
0 -> 行頭に移動
$ -> 行末に移動
```
この`w　e　b　0　$`はモーションといい、様々なコマンドと組み合わせて強力な操作の手助けをしてくれます。でも今はとりあえず楽に移動できるんだなぁくらいで大丈夫!またすぐ出てきます。
###文字の挿入と削除###
ここまで進んだのに未だに肝心のコードが書けない!安心してください今から教えますよ。

```
i -> カーソル位置にテキストを追加
A -> 行末に移動してテキストの追加
r -> カーソル位置の文字を置き換え
cw -> 単語の一部、もしくはすべての置き換え
```
###検索、そして置換...
```vim
:s/検索文字列
:s/検索文字列/置換文字列/g
```
以上、見たら何となくやり方が分かると思います。置換の方は最後をgcとすると置換前にいちいち確認が入ります。あと検索にはいくつかオプションがあります。

```vim
:set 
```

##あとがき
こんな記事読むよりLinuxで`vimtutor`って打ってみよう。
超初心者が『Kaggleで勝つ』を読んで分からないところをまとめた（自分用）

#前提
html、css、pythonを少し触ったことがある程度。
機械学習をしてみたいと思い、いきなりKaggleに挑戦してみた。
しかし、どうしたらよいか全くわからなかったので、『Kaggleで勝つ』の本を読んだ。
知識がないので、分からないものは適宜ggりながら読み進めている。
メモ帳としてここにまとめる。


#pandasについて
- データの加工に使う系

<dl>
<dt>drop</dt>
<dd>dataframeから行を指定して削除する</dd>
</dl>
<dl>
<dt>axis</dt>
<dd>・dataframeから列を指定して削除する（dropと使う）</dd>
<dd>・0か1をとる。0の時は行、1の時は列を削除する</dd>
<dd>droped_df = df.drop("label", axis=1) 　　# label列だけ削除 ... 複数列の場合はリストに。</dd>
</dl>
bhyve 初心者メモ

備忘録です。

# PPPoEクライアントを FreeBSD on Bhyve で動かそうとするとパケット（非IP)のやりとりができない。

どこかでヤラカした時に、処方箋を咄嗟には見つけられなかった。
以下リンクにあった。ハマった同じケースはあまりない模様。

https://www.ixsystems.com/community/threads/ethernet-type-pppoe-inside-of-tap-interface-for-vm-bhyve.76970/

<pre>
sysctl -w net.link.bridge.pfil_onlyip=1
</pre>

以下の問題も関連すると思われる（pppoeだけするIFは通常 /etc/rc でタッチしない）

# ホストでIPアサインしていない interface を使う。 
ホストが再起動後にホストがIFだけ外接していて IPを振られてないIFに対して、ゲスト側でIPを振っても通信ができない（virtual switchとリアルなスイッチの間でMACパケットが飛ばない

👉 単純にホスト側で 未使用 IF を　<bold>UP</bold>していない。　
👉 ゲスト起動時に vm で確保した if が　up されているかをチェックしていない。

/etc/rc.conf で アサインしてない IFを使う場合は、UPさせるだけ。
[UE4] ログをすっきりする

ピンポイントな所のログを見たいときに、
ログの左上のフィルタ→Miscellaneous→カテゴリ→カテゴリを表示、非表示することが出来ます。
デバッグとトラッキングにおすすめでござる！！![2019-11-14_12h56_44hhhh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369484/e403edc1-17c5-8b2f-f9c9-73854cff8fc9.png)
Sphinxのドキュメントのテーマをいつものにしたいとき



# はじめに

Sphinxのデフォルトのテーマは、ものすごくスタイリッシュでなんか違うんだよな　になります。

やはり、いつものアレを使いたいですね。

# いつものアレ

https://github.com/readthedocs/sphinx_rtd_theme


![スクリーンショット 2019-11-14 13.12.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/818a8277-1b34-6de2-3e41-b39f17726e7d.png)

やけに使用頻度の高いコレです。

どうやら、これは公式のテーマではなくサードパーティ製のテーマのため、別途インストールする必要があります。

# 手順

テーマを使用したいディレクトリに適用されたPythonのpipで

```python
$ pip install sphinx-rtd-theme
```

をします。

その後、設定ファイルのconf.pyに

```conf.py
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.viewcode',
    'sphinx.ext.todo',
    'sphinx.ext.napoleon',
    'sphinx_rtd_theme'
]
html_theme = 'sphinx_rtd_theme'
```

extensionsとhtml_themeを追記すればよいです。

# テーマサイト

[sphinx-themes](https://sphinx-themes.org)に、使用できるテーマ一覧があるため、
活用するとよさそうです。
[UE4] バグ追跡情報の出力コマンド

#1. 概要
バグ追跡のための情報を出力するためのコンソールコマンドを紹介します。
使い方はコマンドの入力バー(コンソール)を出して**"BugIt**と入力するだけです。

#2. コマンド
**BugIt**
ログ情報(Viewport座標、現在のマップ名、時間、バージョン等)、Slateを含んだスクリーンショット(.png)を出力することができます。

**[ファイル出力先]**
[PROJECT]/Saved/BugIt/の直下となります。
![2019-11-29_17h52_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/0b70228d-108c-42de-118a-51dc304ca59f.png)


**[ログ出力例]**
![2019-11-29_17h55_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/be0baf8a-2116-7f14-9107-c5b2f587f6d0.png)


#3. 実装
実装はCheatManager.cppの以下の箇所で定義されています。

```cpp:CheatManager.cpp

void UCheatManager::BugIt( const FString& ScreenShotDescription )
{
	APlayerController* const MyPlayerController = GetOuterAPlayerController();

	// Path will be <gamename>/bugit/<platform>/desc/desc_ (BugItDir() includes a platform and trailing slash)
	const FString BaseFile = FString::Printf(TEXT("%s%s/%s_"), *FPaths::BugItDir(), *ScreenShotDescription, *ScreenShotDescription);
	FString ScreenShotFile;

	// find the next filename in the sequence, e.g <gamename>/bugit/<platform>/desc_00000.png
	FFileHelper::GenerateNextBitmapFilename(BaseFile, TEXT("png"), ScreenShotFile);

	// request a screenshot to that path
	MyPlayerController->ConsoleCommand( FString::Printf(TEXT("BUGSCREENSHOTWITHHUDINFO %s"), *ScreenShotFile));

	FVector ViewLocation;
	FRotator ViewRotation;
	MyPlayerController->GetPlayerViewPoint( ViewLocation, ViewRotation );

	if( MyPlayerController->GetPawn() != NULL )
	{
		ViewLocation = MyPlayerController->GetPawn()->GetActorLocation();
	}

	FString GoString, LocString;
	BugItStringCreator( ViewLocation, ViewRotation, GoString, LocString );

	// Log bugit data to a textfile with the same name as the screenshot
	LogOutBugItGoToLogFile( ScreenShotDescription, ScreenShotFile, GoString, LocString );
}

```

#4. まとめ
このコンソールコマンドを利用すると問題箇所の特定や調査をするのに役立ちます。
これらをうまく活用してデバッグを効率的に行いましょう。
pythonで書く相性診断プログラム

pythonの相性診断のプログラム

```python
from datetime import date
from time import strptime

new={'双子座':'水瓶座','牡牛座':'乙女座','さそり座':'うお座',\
'獅子座':'射手座','やぎ座':'乙女座','かに座':'牡羊座'}

class seizaandeto:
    def __init__(self):
        self.seiza={1:'やぎ座',2:'水瓶座',3:'うお座',4:'牡羊座',5:'牡牛座',\
                      6:'双子座',7:'かに座',8:'獅子座',9:'乙女座',10:'天秤座',\
                      11:'さそり座',12:'射手座'}

        self.printSeizaandeto()

    def printSeizaandeto(self):
        print('生年月日を入力します。')
        year=input('生まれた年を入力してください。')
        month=input('生まれた月を入力してください。')
        day=input('生まれた日を入力してください。')
        s='%s-%s-%s'%(year,month,day)
        dobj=date(*strptime(s,'%Y-%m-%d')[0:3])
        self.year,self.month,self.day=dobj.year,dobj.month,dobj.day
        x=self.seizaHantei()
        print('あなたと相性がいいのは' + new[x] + 'です。')
        print("生年月日：%s" % dobj)
        print('星座：%s' % (self.seizaHantei()))

    def seizaHantei(self):
        if self.day>22:
            if self.month==12:
                return self.seiza[1]
            else:
                return self.seiza[self.month+1]
        else:
            return self.seiza[self.month]

if __name__=='__main__':
    v=seizaandeto()


```
作り方
①始めに星座の全ての情報を持った集合を作る
②キーを数字、要素を星座情報にした辞書を作り生年月日を入力させるメソッドに飛ばす
③星座を特定する
④相性を適当に決めて出力する
[UE4]コンテンツブラウザのサムネイルをリアルタイム表示

コンテンツブラウザ右下のView OptionsからReal-Time Thumbnailsにチェックを入れることで、マテリアルなど一部のアセットがリアルタイム更新されるようになります。  
![Thumbnails.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/5b700408-6b56-c983-5294-c65f52f7ab91.png)
![Thumbnails.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/4bf8d331-1486-6874-bf35-11391301a49b.gif)
エディタが重くなる可能性もあるのでご注意ください。
Vue.jsのkeyupやkeydownで数秒後に発火する処理を実装したい

# 結論
`@keyup`で呼び出す関数を`lodash`の`debounce`でnミリ秒後指定する。

# Vue.jsでkeyupイベントで発火

さて、keyupやkeydownで発火させるのはかんたんだ…。
でも入力中に毎回発火させるのは嫌だな〜

```vuejs
<template>
  <div>
    <input @keyup="doAlert">
  <div>
</template>

<script>
export default {
  name: 'hogeComponent',
  methods: {
    doAlert() {
      alert('アラートじゃ！');
    }
  }
}
</script>
```

## 数秒後に発火させたい & 時間内にもう一度イベント発火が起こればカウントリセット

### lodashのdebounceに頼る

lodashをインストール（npmでもOK）

```
yarn add lodash
```

1. lodashをimportする
2. doAlertメソッドを`_.debounce()`で指定ミリ秒後呼び出しにする

```vuejs
<template>
  <div>
    <input @keyup="doAlert">
  <div>
</template>

<script>
import _ from 'lodash'

export default {
  name: 'hogeComponent',
  methods: {
    doAlert: _.debounce(function() {
      alert('アラートじゃ！');
    }, 500) // 500ms指定
  }
}
</script>
```
[UE4]プロジェクトをZIP圧縮

ファイル→プロジェクトをパッケージ版→プロジェクトをZIP圧縮を選択すると、
Config、Content、Source、.uprojectがしか入っていないZIP圧縮フォルダーを作ることが出来ます。
プロジェクトを共有したいときに、無駄にストレージを使わないのでお勧めです！

注意：プラグインフォルダーが含まれていないです！

![2019-11-14_12h56_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369484/55c4408e-5214-f2a2-a911-0e7c71adae32.png)
[UE4] Blueprint変数の配列化

Blueprint変数のアイコンを**マウス右クリック**すると配列化、TArray型への変更を簡単にできます。

![2019-11-13_17h44_11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/396082ed-3de2-fc9e-e7b4-3ae5177e2e1c.gif)

配列化の操作って意外と手間ですよね、初日なので簡単な機能のTipsをご紹介しました！

<details><summary>もっと知りたい</summary><div>

このボタンはComboButtonというものを使っており実装は以下の場所にあります。
\Engine\Source\Runtime\Slate\Private\Widgets\Input\SComboButton.cpp
上記のgifでは右クリック(青い波紋)時に切り替わっていますが、既にノードを使用して接続済みの場合は型が変わるので警告ポップアップが出ます。
そのためComboButtonを使用しています。残念ながらComboButtonはWidgetComponentとしてDesignerに追加することはできません。

</div></details>
[UE4] ViewCameraを移動するコマンド

#1. 概要
Viewport Cameraの位置を指定の座標に移動するコンソールコマンドを紹介します。
使い方はコマンドの入力バー(コンソール)を出して**"JumpTo x,y,z"**のフォーマットで入力するだけです。

#2. コマンド
**JumpTo**
・"JumpTo x,y,z"(例:JumpTo 100,100,100)のように移動先の座標を後ろに入力します
・PIEの場合のみ有効、F8でEjectした状態からこのコマンドを入力すると移動できます
・Viewport上(ViewportCamera)の座標を移動するため、特定のものを捜索する場合に便利です
　例：Collision Analyzerからコリジョンイベントの発生源を確認する
　例：BugItコマンドからバグの発生した場所を確認する

![2019-11-14_12h56_42.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/876fc539-6e2a-e02f-0c00-fdf1d05c6146.gif)


以下のようにCallInEditorのイベントを利用することで、ボタン1つで特定の座標に移動できるActorを作成することも可能です。

![2019-11-14_12h51_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/9b151f95-c5b8-5c25-a873-1881a24a18d1.png)
![2019-11-14_12h51_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/e6c28280-cd80-7f79-a58e-1fbc17abec11.png)


#3. 実装
実装はEditorServer.cppの以下の箇所で定義されています。

```cpp:EditorServer.cpp

bool UEditorEngine::Exec( UWorld* InWorld, const TCHAR* Stream, FOutputDevice& Ar )
{
	// ...
	else if( FParse::Command(&Str,TEXT("JUMPTO")) )
	{
		return HandleJumpToCommand( Str, Ar );
	}
	// ...

}

bool UEditorEngine::HandleJumpToCommand( const TCHAR* Str, FOutputDevice& Ar )
{
	FVector Loc;
	if( GetFVECTOR( Str, Loc ) )
	{
		for(FLevelEditorViewportClient* ViewportClient : GetLevelViewportClients())
		{
			ViewportClient->SetViewLocation( Loc );
		}
	}
	return true;
}

```
#4. まとめ
このコンソールコマンドを利用すると問題箇所の特定や調査をするのに役立ちます。
これらをうまく活用してデバッグを効率的に行いましょう。
[UE4]Component Maskノードのショートカット

Shift + Cで呼び出すことができます。
Component Maskはテクスチャやベクター情報などから特定チャンネルだけをマスクすることができるノードです。  
使用頻度が高いわりにMaskと検索しても出てこないのでこのショートカットが有用です。
![2019-11-14_12h47_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/005d0656-49a6-9b85-1530-36baa3e874bd.png)
Rustでprivate repositoryを~/.ssh/configを効かせてインポートする

## .cargo/configに設定する

defaultだとcargoが~/.ssh/configを参照してくれないので以下を追加

**~/.cargo/config**

```toml
[net]
git-fetch-with-cli = true
```

## Cargo.tomlでの指定

**Cargo.toml**

```toml
[dependencies]
pkg-name = { version = "0.1.0", git = "ssh://git@your-repo-host/git-user-or-group/pkg-name.git", branch = "master" }
```

**key points**

gitのフォーマットもcloneする時のURLを使うとエラーになる
- `ssh:` をいれる
- host:username になっていたら host/username などにpathを変更する
jQueryで要素をIDで指定する場合、`#target_id`とすると最初に現れる要素しか適用されない

記述を変えると全部効く

```js
$("#target_id")
// ↓書き換える
$("[id=target_id]")
```

※そもそも同一idの要素が複数あるのはHTMLの書き方としておかしい
Jenkins Job Build with Remote Execution

### Test Environment
---
- Jenkins Version : v2.138.2
- Job Name : HELLO
- Token Name : outCall
![outcall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/ff7af2bd-f70c-961b-71b6-2f4e699b578d.png)

### Jenkins Global Setting
---
- Unchecked 'CSRF Protection'
    - Jenkins Management > Configure Global Security > CSRF Protection > Unchecked 'CSRF Protection'
    ![csrf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/2ad6bf43-f1b6-73f2-3511-867a94d01c63.png)

- Create User API Token
    - Jenkins Management > Manage User > Select User(ex: 'admin') > Configure > API Token > Add new Token > Generate > Creation Token Value(ex: '1140d85eea07a2c01ce01bf9de450c04f6')
    ![api_token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/c3981f15-8883-6ae0-244d-67e36b88335a.png)

### Jenkins Job Setting
---
- Create Job : 'HELLO'
- Configure Job
    - 'HELLO' > Configure > Input 'outCall' keyword in 'Authenitication Token'
    ![configure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/9d60ecd1-76bc-740b-57f6-cfae4cbf0914.png)

### Testing
---
- Call Jenkins Job(ex : 'HELLO') with curl command 

```shell
# curl -X post http://<username>:<API_Token>@<JENKINS_URL>/jenkins/job/<JENKINS_JOB_NAME>/build?token=<TOKEN_Name>
$ curl -X post http://admin:1140d85eea07a2c01ce01bf9de450c04f6@123.123.123.123:8080/job/HELLO/build?token=outCall
```

### Result
---
- Call 3 times
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/1ddd9da1-2120-469c-6cc0-eead49739276.png)
AWSのRoute 53で登録したドメインに、サブドメインを追加する。

投稿するレベルのことではない気がするけど、備忘録として。

Route 53 → ホストゾーン

ですでに登録してあるドメインをクリック。

<img width="1038" alt="スクリーンショット 2019-11-14 10.30.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364454/989386f9-f46a-eff6-9b57-c16f05e1f6fa.png">

そうすると、上記のようなメニューバーが出てくるので、「レコードセットの作成」をクリック。

そうすると下記のようなレコードセット作成画面が出てくるので、「名前」のところに登録したいサブドメインを入力する。
<img width="404" alt="スクリーンショット 2019-11-14 10.27.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364454/dc23d2ad-d166-ccf2-a59e-9b2939d8021d.png">

「値」のところには、該当するIPv4アドレスを入力。

そして「完了」をクリックすれば登録は終わり。
EF6で、クラウド上のPostgreSQLの、template1権限エラーを解決する

#問題　
EntityFramework 6.3で、ElephantSQL、Herokuの、PostgreSQLへの接続を行った時に、

`System.Data.Entity.Core.ProviderIncompatibleException: The provider did not return a ProviderManifestToken string. ---> Npgsql.PostgresException: 42501: permission denied for database "template1"`
のようなエラーが発生。

template1への権限が無いよ、というもの。

#解決方法
ConnectionStringに、
`EntityAdminDatabase=「データベース名」`
を追加

##参考
- [Class NpgsqlConnectionStringBuilder](http://www.npgsql.org/doc/api/Npgsql.NpgsqlConnectionStringBuilder.html?q=EntityAdminDatabase)
- [npgsql - stop using 'template1' database](https://stackoverflow.com/questions/41495767/npgsql-stop-using-template1-database)


##この解決方法に至るまでの試行錯誤
- 2019/10/1時点では、自分の環境ではこの問題は発生していなかった。
- 2019/11/13に、この問題を認識。
- ローカルのPostgreSQLに接続してから、クラウドのPostgreSQLに接続すると、問題は発生しない。クラウドのElephantSQLに、最初に接続すると、問題発生、という現象。
そのため、ローカル接続を行ってからの場合、行わなかった場合、の2パターンで、プロパティの差を調べれば解決できるのでは、と考え、調査。→　プロパティの値に差はあったが、それ以上のことは検索しても分からず。
- template1を調査。
template1は、CreateDatabase（？）を行うために、PostgreSQLが利用しようとしているのだろうと、思い当たる（ここまで半日）
- データベース作成を止める方法を調査。
- `System.Data.Entity.Database.SetInitializer<TContext>(null);`
としていたので、
SetInitializerを、様々に指定して、トライ。→　解決せず。
- 検索キーワードを変えて、検索。ようやく、上記のstackoverflowの記事にたどり着く。
[UE4] コンソールウィンドウを開くコマンド

#1. 概要
ログを出力するためのウィンドウ (以下図の矢印) を表示するコマンドを紹介します。
使い方はコマンドの入力バー、コンソールを出してコンソールコマンドを入力するだけ[^1]です。
下の図の矢印のウィンドウを出したり出さなかったりします。

![2019-11-28_15h38_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/eeed2c4c-c6b6-0fd8-fb42-ab8b918b3a71.png)


#2. コマンド
**ShowLog**
・ログ出力ウィンドウを表示することができトグル方式でON/OFFを切り替えることができる
・起動引数に"-log"を付けて起動[^2]せずともログ出力を確認することができる
・ウィンドウの動的な表示の切替が可能で、ログの出力を都度リセットすることができる
・Shippingでは利用不可、Debug/Development/Testで利用可能
・PIE、Standaloneで利用可能
・コンソール/モバイル実機では利用不可、PCで利用可能

[^1]: コンソールの出し方：コンソールコマンドの入力は"~"キー(日本語キーボードは"@"キー)を押してコンソールを表示してコマンドを入力する。たまにどちらか混同する。

[^2]: -log：ログ出力ウィンドウを表示するための起動引数。Visual Studioを使わないBlueprint Onlyのプロジェクトや、Network関連のデバッグなど、ログで確認した方が良いケースなどでは捗る。

![2019-11-28_15h35_41-min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/afc5e9b5-0e6f-d4a4-7b2c-67617a8875a6.gif)

#3. 実装
実装はUEngineの以下の箇所で定義されています。HandleShowLogCommandの中でShow()を実行しています。

```cpp:UnrealEngine.cpp

bool UEngine::Exec( UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar )
{
	// ...
	else if( FParse::Command(&Cmd,TEXT("SHOWLOG")) )
	{
		return HandleShowLogCommand( Cmd, Ar );
	}
}

bool UEngine::HandleShowLogCommand( const TCHAR* Cmd, FOutputDevice& Ar )
{
	// Toggle display of console log window.
	if (GLogConsole)
	{
		GLogConsole->Show( !GLogConsole->IsShown() );
	}
	return 1;
}

```

#4. まとめ
Windowsでの開発において、StandaloneやPackageでの確認の際に役に立ちます。
これらをうまく活用してデバッグを効率的に行いましょう。
Lookerで軸の表記をいい感じにする方法


Lookerで2軸グラフを作成すると、軸に複数項目が表記される場合があります。
そんな時はここを調整すれば良い。という豆知識を残します。

##やりたい事
Lookerの日付項目の表示内容を調整したい

##発生イメージ
下図のように、２軸グラフを作成した結果、軸が**日付（Date) + 別項目(Volume Sum)で表記されて気持ち悪い感じ**になっている。
![軸の表記をいい感じにする1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/854f89ac-6c42-0dc1-aeb5-e5d4bb05d7b9.png)

→上記の軸表記を日付だけにすればいい感じになると思います。

##対応方法
VISUALIZATIONのEDITを選択
→Xタブを選択
→Axis Value LabelsをONにする
→Time Label Formatに変更したいフォーマットを記入する
![軸の表記をいい感じにする2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/e1919fcb-c19b-9469-fe9d-45da9d1c7441.png)
![Looker下矢印.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/6ce3ef83-995c-3b1a-e7a7-a5425b15353d.png)
![軸の表記をいい感じにする3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/6b46ad58-de27-dcef-85e5-353acd26da28.png)

ここでは、SQLを使う方にはお馴染みの、**`%Y-%m%-d`** を指定
軸のフォーマット変換コードは[こちら](https://docs.looker.com/exploring-data/visualizing-query-results/time-formatting-for-charts)を参照

##まとめ（つぶやき？）
Lookerではデータの型変換はLookMLをメインで活用すると思いますが、設定からも変更可能なものが色々あります。

理想を言えば、**データの型をBIツールで参照しやすい状態まで、テーブル設計した上でデータマート化しておくのが最高**だとは思うのですが、データ基盤エンジニア、データアナリスト、データサイエンティスト、最近ではBIアナリストとか。色々なメンバが関わってデータの分析基盤構築と可視化を形作っていくパターンが多いと思いますので、**BIツール側で色々調整可能な仕組みの方が需要がある気がします**。

ただし、ツールの入れ替わり速度も早い時代なので、この手の設定方法の手順はより単純であると、さらにありがたいとも思います。また、Lookerでは**フォーマット設定の指定方法にもプログラミングコード（基礎的なもの）が必要**なので、その辺の知識もちゃんと知っておく必要がありそうです。
老体エンジニアまだまだ頑張る開発サイト！！２回目WordPress改造案

最近のWordPressではiframeが使えるので下記のようにwp-app内に作成したphp記述のサイトを
iframe埋込独自の投稿（サイトとアプリから）をWordPress上に展開する。更にその埋込に
FaceBookやInstagramまたYouTube等もリンクコピペで埋め込みが可能にしています。

```html:html
<iframe style="border: none;" src="http://wordpressアドレス/wp-app/animalnote.php" width="100%" height="900" frameborder="0" marginwidth="0" marginheight="0"></iframe>
```
wp-app内のphpとDB構築スクリプトはフォルダ内にありDB設定をWordPressと合わせて実行する事によりプラグインとして利用出来るようになります。

WordPressテーマは殆どOKですがやはりiframe不可のテーマもあるようです。
Lightningのテーマを今は利用しています。(下記はfacebook埋込です)

![スクリーンショット 2019-11-14 12.30.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/56f43a4c-7e29-fb48-571e-cf8af7d1cc03.png)
リクエストパラメータのログ出力サンプル Java & SpringMVC

# 前書き
SpringMVCを使用していて、
**リクエストURLやリクエストパラメータをログに出したい！**
ということが度々あり、その度に専用のfilterクラスを作っていたので、

いっそ自分のために記事に残しておいたら今後幸せになれるのでは？

と思い記載しました。完全に自分用のメモです。

# 環境

* Java 8 (11でも動きます)
* Spring Boot 2.2.1
* Spring MVC (バージョンはBootの規定を使用)
* Lombok (バージョンはBootの規定を使用)

※Spring WebFluxでは試していません。

# コードサンプル

```java
package com.example.demo.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

@Slf4j
@Component
public class LoggingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = ((HttpServletRequest)request);
        String uri = httpReq.getRequestURI();

        long start = System.currentTimeMillis();
        log.info(String.format("処理開始. URI: %s", uri));

        // リクエストパラメータを加工して1行のログとして出力する
        Map<String, String[]> params = httpReq.getParameterMap();
        StringBuilder strParams = new StringBuilder("リクエストパラメータ: [");
        boolean isFirstParam = true;
        for (Map.Entry<String, String[]> param : params.entrySet()) {
            if (isFirstParam) {
                isFirstParam = false;
            } else {
                // リクエストパラメータの2個目以降の場合は連結子としてカンマを付与する
                strParams.append(", ");
            }
            strParams.append(param.getKey()).append("=").append(Arrays.toString(param.getValue()));
        }
        strParams.append("]");
        log.info(strParams.toString());

        // 各処理実施
        chain.doFilter(request, response);

        int status = ((HttpServletResponse) response).getStatus();
        log.info(String.format("処理終了. 所要時間 %d millis. STATUS=%d", System.currentTimeMillis() - start, status));
    }

    @Override
    public void destroy() {
    }
}
```

# ログサンプル

```
2019-11-14 11:54:40.297  INFO 2001 --- [nio-8080-exec-1] com.example.demo.filter.LoggingFilter    : 処理開始. URI: /demo/hello
2019-11-14 11:54:40.298  INFO 2001 --- [nio-8080-exec-1] com.example.demo.filter.LoggingFilter    : リクエストパラメータ: [hoge=[1], fuga=[2]]
2019-11-14 11:54:40.327  INFO 2001 --- [nio-8080-exec-1] com.example.demo.filter.LoggingFilter    : 処理終了. 所要時間 30 millis. STATUS=200
```

# 補足

ログフォーマットはSpringBootの規定のままです。
個人的にログ出力は日本語だとわかりやすいため、日本語で記載しています。もうちょっとこうしたほうがいいかな…と思うこともありますが、このような文体で記載することが多いです。
若干拡張For文のあたりがキモいな…と思わなくもないですが、めんどくさくて改定していないです。

なお、このFilterでは配列のパラメータは対応していますが、添付ファイルには対応していません。
IntelliJ gradle2.2→2.6環境移行で躓いたときにやったこと

#概要
会社でPCの交換を強要されて仕方なくIntelliJのgradle環境を移行したときに盛大に躓いたので、
そのときに解決までにやったことをメモします。

知らぬ間にGradleさんのアイコンがぞうさんになってたんですね～

#環境
### 元の環境
- IntelliJ IDEA CE 2017.3
- gradle 2.2

### 移行後の環境
- IntelliJ IDEA CE 2019.2
- gradle 2.6

#先に結論
とりあえず以下の手順でやったら元の環境と同じように動いてくれました。
1. 元の環境から「.idea」フォルダをコピーしてプロジェクトフォルダ内に置く
2. intelliJから開きたいフォルダを「inport project」で開く
3. build.garadleすると以下のエラーが出るので、そいつに従ってgradleを2.6に引き上げる
4. もう一度build.garadleすると多分通る

``` 
Support for builds using Gradle versions older than 2.6 was removed in tooling API version 5.0. You are currently using Gradle version 2.2. You should upgrade your Gradle build to use Gradle 2.6 or later.

Possible solution:
 - Upgrade Gradle wrapper to 2.6 version and re-import the project
```

#何に躓いていたのか
多分 IntelliJ に慣れている人には当たり前のことなのかもしれないけれど、
「.idea」フォルダがないと「import project」ができないっぽい。
という事に気づくのにすごく時間がかかりました。

もともと自分が引き継いだときは「.idea」がなくてもbuild.gradleのあるフォルダを「Open」すれば
勝手にbuild.gradleを見つけていい感じに動いてた様な気がするんだけど、
新環境では移行時にはgradle2.2がサポート対象外となってて、うまくOpenできなかったのかな…？と思ってます。
ちなみに「Open」からでもなんやかんやしてるうちにbuild通りはしたんだけど、
ライブラリー類を一切見つけてきてくれなくて、コード補完が全く使えなかった。。。

多分サポート対象外になってないgradle環境を別なPCのIntelliJに移す場合は、
普通にbuild.gradleのあるフォルダを「Open」すればImportProjectFromGradleが開いて、
Auto-Importにしておけば簡単に移行できるはず。。
【ポエム】Qiitaのビューと読了率を知りたい

プログラミングの知識というより運用のお話が主になりますが、アクセス数（View）は分かっても読了率が分からないので、品質の高い記事になっているか把握できないという問題を感じています。
[参考：Googleアナリティクスで読了率を知りたい-Googleタグマネージャでスクロール測定する方法](https://croja.jp/knowledge/scroll-depth-googletagmanager)

# Qiitaの仕組みを使う
今試みている施策がこちら。
いいね！がどういう目的で使われているか分かりにくい[^1]ので、それならいっそのこと読了率を図るパロメーターにしてしまおうかと思いました。

# 前提：私はバズラーやインフルエンサーではないこと
つまり、運営に影響を及ぼさない、及ぼしにくい立場の人間だからこそ、色々な事にチャレンジしてみようと思った次第です。
固定ファンを持っている方とかだと影響が出まくるので、運営に多大な影響を与えるかも知れないので、その状態だと挑戦するにしても色々あるかなぁ、と。

こういう考え方が日本人的で良くない[^2]んですが、「迷惑をかけない範囲」で挑戦できる事は色々やってみたいというモチベーションです。

# この結果得られること
本懐は先述した通り、アクセス数と読了率を知る事によって、タイトルや内容に齟齬がなく適切であるかどうかを図りたい、というものです。

が、副次的な効果として、私の記事だけではなく他の人の記事にも気軽にいいね！をする風潮を作っていきたいなぁという思いです。
ビュー数に対していいね！数が少ないと書き手のモチベーションなど前向きなアクションが起こりにくくなると感じていて[^3]その結果として記事が増える、内容がブラッシュアップされ結果的に本人のためになる、その内容がこれから入ってきた人にとって良いものになる、というスパイラルが生まれる事を期待しています。

# この結果得られなくなること
単純にバズる記事を書けばよくね？という思想がより強くなるかもしれません。
これはQiitaのみならずWeb界隈だと当然のような風潮があります。

## 補足
もちろん、そういう目的を批判することはしませんが、「隠れた良記事にもっと気付いて欲しい」という独善的なエゴが、なかなか日が当たらなくて嘆いている方に、少しばかりの癒やしを提供できればと思います。

システムも運用も善意による運営を期待したいですね。

# 運用促進の提案
Qiitaのユーザープロフィールなどで自分がおすすめしたい記事とか書いておくと、興味を持ったユーザーさんが見てくれるかも知れません。
いわゆる「セルフレコメンド」というやつですが、効果があるか気になりますね。

# 注釈
[^1]: 【いいね！の目的】どこかで公開されている既知の情報かもしれません。
[^2]: 【日本人的で良くない】何かをやる時にお伺いを立てる、というのはリスクマネジメントではあるんですが、なにかに挑戦する環境としては健全ではないなぁと思います。
[^3]: 【前向きなアクションに期待】エンジニアはアウトプットが少なすぎる！と日々感じています。マサカリを投げるかフォローをするか、フォローをマサカリと感じるかなど受動側のスキルも磨かれます。
新規プロジェクトの技術スタックについて

はじめまして、株式会社PRECSの室（ムロ）といいます。
PRECS社ではECシステムをショップに提供するサービスを行っており、現在は社内のエンジニアが20名ちょい、外部の協力エンジニアも含めると30人程度の体制で開発を行っています。

自分は弊社で進めている新規プロジェクトの開発責任者的なことをやっていて、ガリガリコーディングを・・・というよりかはプロダクトオーナー的な立ち位置にいます。
今回は初めての投稿ということで、新規プロジェクトで採用している技術スタックについて簡単にまとめてみました。
各技術の具体的な内容については、今後、別のメンバーが投稿してくれるのに期待します（笑）
（以下の内容は 2019/11/14 時点でのものです）

# XD

プロトタイプ作成に利用しています。
最近、共同編集やコンポーネントのステート管理もできるようになり、便利になってきたのこと。
今後の Adobe のアップデートに期待。

# React + Redux + TypeScript

フロントのフレームワークとして React を採用。
Redux でのステート管理、TypeScript での型の導入など、大規模だけれどもメンテナンスしやすいように構築しています。
個人的には ReactNative を使ったネイティブアプリを作ったりもしてみたいですね〜

# PHP + Laravel

PRECS社で元々ずっと PHP を使っていたので、サーバーサイドは PHP を採用しました。
最初は軽量化を考え独自フレームワークで構築しようと進めていましたが、結局 Laravel に落ち着きました。
いろいろな機能が揃っていることや外部の協力メンバーが詳しかったこと、また今後のＰＨＰエンジニア採用もしやすくなるだろう、などの目論見もあります（笑）

# MySQL

こちらもPRECS社で元々使い慣れていることもあって RDB として採用しました。

# AWS

PRECS社の既存サービスはオンプレミスでの運用をしていますが、新規プロジェクトではクラウドのインフラ環境で構築を進めています。
スモールスタートや障害時の対応のしやすさはもちろんですが、コスト面も以前と比べてだいぶ下がってきて試算上もメリットがあるだろう見込んでいます。
ローカルの開発環境では docker を利用しており、EKS (Amazon Elastic Kubernetes Service) を用いたデプロイ戦略を目指しています。

以上、簡単に新規プロジェクトの技術スタックについて簡単にまとめてみました。
[Android]端末上のアプリ情報を覗き見る

## 端末にインストールされたパッケージ(apk)のバージョン情報を覗こうとした
とあるプロジェクトにて、アプリのバージョンコード・バージョンネームを上げてビルド。  
出力されたoutput.jsonをみると、どうやらバージョンが変わっていない。

真偽を確かなものとするためapkの情報を覗くことに。  
（注：ここではバージョンが変わらなかった場合の解決方法は説明しません。）

## 前提として
調べたいapkがインストールされた端末がPCと接続されていること。  
adbが使えること。

## dumpsysコマンド
dumpsysコマンドはシステムサービスの状態をダンプしてくれます。  
簡単な例で言うと、バッテリーの残量やメモリの消費量、ネットワーク通信状態などを、コマンド一発で確認することができます。(原文ママ)

開発者としてはぜひ知っておきたいコマンド。

## dumpsys packageでパッケージ情報を覗く
ターミナルにて、以下を実行
```adb shell dumpsys package パッケージ名```
これで107行くらいの情報が出てくる。（長いから載せない）  
`versionCode`と`versionName`を検索するだけ。

### ちなみに
端末上のパッケージ名を羅列するコマンド
```adb shell pm list package```

これだと多すぎて見つけられないのでオススメはしない。

大体は AndroidManifest.xml に`package="パッケージ名"`があるのでそちらを参照。  
  
<br>
<br>
最終的にこのコマンドで、端末上にインストールされた  
アプリのバージョン情報を確認することに成功。
  
<br>
<br>
CocoaPods ライブラリのコード変更を反映させる方法

## はじめに

Xcode でメインプロジェクトを開発＆デバッグ中、ライブラリ側のコードにデバッグプリントを入れたいことがあります。
`Pods/Development Pods/LibraryName` ディレクトリにソースが置いてあるのですが、デバッグプリントを仕込み、ビルドしてもそのままでは変更が反映されません...

`Build System` を `Legacy Build System` に変更することで[解決する方法](https://qiita.com/s2mr/items/1a2c13c247194a5bc9ec)がありますが、できれば `Legacy` に変更したくはありません。 

## 環境

- OS: macOS Mojave 10.14.4
- Xcode: 10.2.1 (10E1001)

## 解決方法

対象のライブラリをビルドに追加することで問題を解決します。

`Xcode メニュー -> Product -> Scheme -> Edit Scheme -> Build -> '+'ボタンを押す`

ボタンを押すとダイアログボックスが表示されるので、リストからビルドに追加するライブラリを選択します。
この設定で、ビルド時に対象のライブラリもリビルドされるようになり、ソースコードに行った変更が反映されるようになります。
IoT@Loft #5  - クラウドとロボティクス、オープンソース活用による次世代ロボットの可能性 を受講したよ!（2019年11月13日実施）

IoT@Loft #5- クラウドとロボティクス、オープンソース活用による次世代ロボットの可能性を受講したよ

一番の収穫は、ASIMOを作っていた本田技研が今も新しいものを作ろうとしていることだよ。

##ソニーロボティクスシステムとROS/ROS2の活用
ソニー株式会社　ソフトウェアエンジニア
###藤田 智哉 氏
Aiboの中にRosが動いている
目などはリアルタイム性が必要なのでLinuxのDeamonで動いているらしい
Githubで公開されていてRosKineticやRosMedricでコンパイルすればすぐ使える
資料
https://roscon.ros.org/2018/presentations/ROSCon2018_Aibo.pdf

ROSCONの資料
https://roscon.ros.org/jp/2018/presentations/ROSCon_JP_2018_presentation_12b.pdf

###![IMG_0830.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/0804fb10-4c88-514b-daee-979223490326.jpeg)

##Honda RaaS Platform - クラウドとロボティクスの融合 “Robotics as a Service” -
株式会社本田技術研究所　研究員
###東 治臣 氏

ホンダ人が中心にしてロボットと協調する社会
HondaRaas PlatformロボットにSimを刺してIoT化し拡張していく

Asimoでお茶出しサービスを行っていたそうで見たかったですね。
![IMG_0832.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d94819a3-cd76-c317-f093-91ad2bbef43e.jpeg)
![IMG_0835.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3ad5fcac-86e3-6ea7-ee09-7b8638e38a94.jpeg)


##AWS RoboMakerと連携するクラウド経由の遠隔制御の取り組み
株式会社アプトポッド　ソフトウェアエンジニア
###酒井 智哉 氏
アプトポッド　ソフトウェアエンジニアGazeboがうまく動かないということでRoboMakerのデモ
TurtleBotでの実働など

![IMG_0836.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ce10c4ac-8f42-6375-b1ce-1a09cd89c075.jpeg)
![IMG_0837.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/4f0d5084-8184-02d2-64b3-1509522a2b58.jpeg)


##AWS と ROS - AWS RoboMaker の紹介
アマゾン ウェブ サービス ジャパン株式会社　AWS RoboMaker シニアソリューションアーキテクト
###河田 卓志

またハンズオンやります
https://awsrobomaker2019dec.splashthat.com/
![IMG_0838.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f36fba77-d8ed-668f-5892-afb6ebe55310.jpeg)

##IoT@Loft ハンズオン#２
アマゾン ウェブ サービス ジャパン株式会社　プロトタイプ ソリューションアーキテクト
###飯田 起弘

#AmazonFreeRTOSを用いた量産向けIoTマイコンデバイス開発プロトタイピングを実施
STM32を使ったハンズオンを実施です。
これは行くしかないですね。
![IMG_0839.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5e721f1a-4a21-441c-6187-95355b8a21ab.jpeg)
rails serverをバックグラウンドで実行する

## コンソールにログを出したくないとき

-d オプションを使う

```sh
# 開始するとき
$ rails server -d

# 終了したいとき
$ kill -9 $(cat tmp/pids/server.pid)
```

## コンソールにログを出したいとき

& を使う

```sh
# 開始するとき
$ rails server &

# 終了したいとき
$ kill $(jobs | grep rails | sed -e "s/\[\([0-9]*\)\].*/%\1/g")
```
VS2015で「このアプリケーションのカスタマイズされた機能は動作しません。K-MENU2 の配置マニフェストに署名するときに使用された証明書が信頼されていないか、アプリケーションが信頼された場所にありません。詳細については管理者に問い合わせてください。」と表示されてインストールに失敗する。

Visual Studio 2015 Professional で作成した
「ClickOnceインストールプログラム」を実行したら

「このアプリケーションのカスタマイズされた機能は動作しません。K-MENU2 の配置マニフェストに署名するときに使用された証明書が信頼されていないか、アプリケーションが信頼された場所にありません。詳細については管理者に問い合わせてください。」

と表示されてインストールに失敗する。

【詳細】を押すと以下が表示された
（パス名やプログラム名の一部は削除しています）

名前: K-MENU2
インストール元: file://xxxx K-MENU2.vsto

************** 例外テキスト **************
System.Security.SecurityException: このアプリケーションのカスタマイズされた機能は動作しません。K-MENU2 の配置マニフェストに署名するときに使用された証明書が信頼されていないか、アプリケーションが信頼された場所にありません。詳細については管理者に問い合わせてください。
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInTrustEvaluator.VerifyTrustPromptKeyInternal(ClickOnceTrustPromptKeyValue promptKeyValue, DeploymentSignatureInformation signatureInformation, String productName, TrustStatus status)
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInTrustEvaluator.VerifyTrustUsingPromptKey(Uri manifest, DeploymentSignatureInformation signatureInformation, String productName, TrustStatus status)
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInTrustEvaluator.VerifyTrustUsingPromptKey(Uri manifest, DeploymentSignatureInformation signatureInformation, String productName)
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.ProcessSHA1Manifest(ActivationContext context, DeploymentSignatureInformation signatureInformation, PermissionSet permissionsRequested, Uri manifest, ManifestSignatureInformationCollection signatures, AddInInstallationStatus installState)
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.VerifySecurity(ActivationContext context, Uri manifest, AddInInstallationStatus installState)
   場所 Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.InstallAddIn()
失敗したアセンブリのゾーン:
MyComputer

【環境】
Windowsドメイン環境下のファイルサーバのフォルダに、C#で作成したOutlookアドインの「ClickOnceインストールプログラム」を発行。
Win10 Pro 数台のパソコンだけが上記エラーを吐いてインストールに失敗していた。

【解決方法】　

◆重要◆レジストリをいじるので自己責任で操作を！！
　　　　もしも該当するレジストリが無い場合は何もせずあきらめてください。

【参考にさせていただいたサイト】　＜　本当に感謝しております。
https://do-gugan.com/blog/archives/2019/08/clickonce_block.html

レジストリエディターを起動し
「\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Security\TrustManager\PromptingLevel」があれば
その中の「LocalInternet」の[値のデータ]を
Disabled　から　→　Enabled　に変更。

その後「ClickOnceインストールプログラム」を再実行したら無事インストールが走ってインストールが完了しました。
＃うまくいかない場合は「Internet」も　→　Enabled　に変更。

◆重要◆インストール成功後は　→　Disabled　に戻すことをオススメします！

ちなみに「Win10のOSバージョン：1903」は上記レジストリ構造は異なっておりましたのでこの方法は無理かと。
でも、これと同じレジストリ構造のパソコンには有効かと思います。

以上
強化学習8　ChainerUIを使ってみる

強化学習7までが終了していいることが前提です。
強化学習をしていくには、その学習過程を見たくなります。
Chainerの可視化・実験管理ツールである「ChainerUI」を使います。

ChainerUI
https://github.com/chainer/chainerui
https://research.preferred.jp/2017/12/chainerui-release/

ChainerUIをインストールします。

```bash
pip install chainerui
chainerui db create
chainerui db upgrade
```

親ディレクトリーに移動してから、プロジェクトを作ります。

```bash
chainerui project create -d CartPole
chainerui server
```

そして、Webブラウザでhttp://localhost:5000/にアクセスします。
このあたりの順番重要です。

scores.txtは、読み込んでくれません。
そこで、以下のコードをtrain.pyに書き足すか、別コードで実行します。

```convert.py
import pandas as pd
import json
import codecs
import numpy as np

scores = pd.read_table('result/scores.txt')
columns = scores.columns  # header情報

data_list = []
for column in columns:
    data_list.append([column, ''])
data_hash = dict(data_list) # 各station dataのhashの雛形

log_json = []
for score in np.array(scores):
    score_hash = data_hash.copy()
    for i in range(columns.size):
        score_hash[columns[i]] = score[i]
    log_json.append(score_hash)

print(log_json)
f = codecs.open('result/log', 'w', 'utf-8')
json.dump(log_json, f, indent=4, ensure_ascii=False)
f.close
```
print(log_json)は不要に思えますが、jupyter　notebookで実行すると、入れておかないとlogファイルの末尾がおかしくなりました。
これで、chainerUIでグラフを見ることができます。

ChainerUIはグラフのX軸が"epoch", "iteration", "episode", "step", "elapsed_time"の５つ固定です。
scores.txtは微妙に違うので、ChainerUIを魔改造します。
連載９回目で魔改造。

まず、ファイルの位置ですが、個人フォルダー内にanaconda3があります。
ここの中を探します。
userFolder/anaconda3/envs/chainer/lib/python3.7/site-packages/chainerui
ここにプログラムが入っています。
userFolder/anaconda3/envs/chainer/lib/python3.7/site-packages/chainerui/static/dist/chainerui.js
このファイルを開きます。
このファイルの中の、
    T = ["epoch", "iteration", "episode", "step", "elapsed_time"],
を、
    T = ["epoch", "iteration", "episode", "step", "elapsed_time","steps","episodes","elapsed"],
に書き換えます。
これで、X軸をstepsなどに指定できます。
wordpress 記事一覧の最大表示数、次のページ・前のページリンクの追加

###記事一覧の最大表示数を変更(デフォルト10)

```php
<?php query_posts('posts_per_page=5'); ?>
```
最新記事5つだけ取得

###記事一覧の前後ページリンクを追加

```php

<?php the_posts_navigation(); ?>
```
次のページ・前のページが表示される

```php

<?php if ( have_posts() ) : ?>
  <?php while( have_posts() ) : the_post(); ?>
    <section class="post-item">
      <!-- タイトルを出力 -->
      <h2><?php the_title(); ?></h2>
　　　<!-- 記事コンテンツを出力 -->
      <?php the_content(); ?>
    </section>
  <?php endwhile;?>

　<!--前後リンクの追加-->
  <?php the_posts_navigation(); ?>
```

[参考](https://thewppress.com/libraries/display-next-and-prev-page-links-on-the-list/)

###前後ページ番号付きリンクの追加

```php

<?php the_posts_pagination(); ?>
```
使用方法は前後ページリンクと同じ

[参考](https://thewppress.com/libraries/display-paginate-links/)

###シングルページでの前後ページリンク

```php
<?php the_post_navigation(); ?>
```
[参考](https://thewppress.com/libraries/display-the-previous-next-post-link/)

※注意※
query_posts　を指定しているページでpost_navigation等を使用するとバグる。。。。
対処法がないか模索中。
Thunderbirdがメモリ不足で強制終了や不安定な挙動になったときの対処法

メーラーに、Thunderbirdを利用しているのですが、
Windows10に変えてから、色々と不具合が発生し頻繁に強制終了するようになってしまいました。
なんとか解決したので、情報を共有したいと思います。

#◆ 発生環境
Windows10
2019.11.14現在
最新の68.2.2 をインストール済み

追記 2019.11.29
Windows7 から Windows10 にOSをアップグレードしたときにも発生します。

#◆ 症状
##・ 常時
メールを受信するとフィルタが適用されずにエラーダイアログが出る
メールを新規に作成していると、
 ATOKのライセンスエラーというダイアログが出る
 途中から文字が表示されなくなる
 強制終了する

##・しばらく時間が経過すると
メールを閲覧していると、文字がところどころ空白になる
メール一覧で右クリックが効かなくなる
メールのプレビュー画面の表示が乱れる
メール一覧や検索結果の一覧でスクロールすると画面バッファがクリアされずに表示が重なっていく
メール内のリンクをクリックしても何も起きなくなる
メールの添付ファイルを開けなくなる

##・なにか操作をしたり、何もせずに更に時間が経過すると
メモリ不足で強制終了する


#◆ 原因と対策（結論）
32bit版が原因ということがわかりました。

**Thunderbirdの 64bit版を上書きインストールで解決しました。**

Thunderbirdの公式にアクセスして
https://www.thunderbird.net/ja/
![Clipboard01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533019/6948615c-7943-4220-b53e-7acc6d709ed8.png)

『無料ダウンロード』 を押すと、自動的にダウンロードになりますが
32bit版がダウンロードされるようです。

ボタンの直下にある
[システムと言語] というテキストリンクに遷移すると
https://www.thunderbird.net/en-US/thunderbird/all/
64bit版をダウンロードすることができます。


#◆ 試行錯誤したこと
・メール件数が多かったのでバックアップを取って、すべて削除
・ツール＞オプション＞詳細
 『グローバル検索と索引データベースを有効にする』のチェックを外す
 『新しいアカウントのメッセージ格納形式』をフォルダー単位(mbox 形式)にする
 『ハードウェアアクセラレーション機能を使用する』にチェックを入れる
・ツール＞オプション＞詳細＞設定エディタ
 gfx.direct2d.disabled を true にする
・フィルターのルールをすべて削除
・新規にメールアカウントを設定し直し
・PCを変える
など試しましたが、改善せず

ちなみに、メールのデータや設定ファイルは
C:\Users\【ログインユーザー名】\AppData\Roaming\Thunderbird
に入っています。