OmniAICreator/Qiita-1.07M huggingface dataset:
SELECT2 検索ボックスの削除ボタンのバブリングやってみた

#前書き

select2を使っていて、検索ボックスで一回名前を選択した後にやっぱり消そう～てなって消したときにプルダウンが開いてしまうのが気になったので今回やってみました！

※jsファイルに記述を足す必要があるのでダウンロードしている前提で書きます

#手順
① jsファイルを開き1541行目までいく
そうするとこんな感じの記述が↓

  ```
this.$selection.on('click', '.select2-selection__choice__remove',
      function (evt) {
      var $remove = $(this);
      var $selection = $remove.parent();
      
          var data = $selection.data('data');

      self.trigger('unselect', {
        originalEvent: evt,
        data: data
      });
    });
  };
```

② 後はfunction(evt)内に ```evt.stopPropagation();```を記述して終わりです

```
 this.$selection.on('click', '.select2-selection__choice__remove',
        function (evt) {
            var $remove = $(this);
            var $selection = $remove.parent();

            evt.stopPropagation();

            var data = $selection.data('data');

            self.trigger('unselect', {
                originalEvent: evt,
                data: data
            });
        });
```

#最後に
初投稿でおかしな点もあるかもなのでもしありましたら教えてもらえると幸いです。
以上
IAM ROLEをEC2に適用し、一時的なAccessKey、SecretAccessKeyを取得する方法

アクセスキーとシークレットアクセスキーはIAMのユーザーで「アクセスキーの生成」で作れます。しかし、この方法だとアクセスキーを一定期間で交換しなければならないのでかなり手間です。
そこでEC2にIAM ROLE を割り当ててアクセスキーとはオサラバの予定でしたがIAM ROLE を適用したら以前に書いていた一時的なAccessKey、SecretAccessKeyが取得できなくなってました。
以前はこんなふうに書いていました

```java
AWSCredentials credentials = new BasicAWSCredentials("アクセスキー", "シークレットアクセスキー");
AWSSecurityTokenServiceClient sts = new AWSSecurityTokenServiceClient(credentials);
GetSessionTokenRequest req = new GetSessionTokenRequest();
GetSessionTokenResult res = sts.getSessionToken(req);
Credentials tmpCredentials = res.getCredentials();
String accessKeyId = tmpCredentials.getAccessKeyId();
String secretAccessKeyId = tmpCredentials.getSecretAccessKey();
```

簡単に調べたのですがassumeRoleがよさげです。
本来は異なるアカウント間のリソースをいじるものみたいですが、
これでいいんじゃないかと。

```java
AWSSecurityTokenService sts = new AWSSecurityTokenServiceClient();
AssumeRoleResult assumeRoleResult = sts.assumeRole(new AssumeRoleRequest()
		.withRoleArn(ROLE_ARN)
		.withRoleSessionName(ROLE_SESSION_NAME));

Credentials credentials = assumeRoleResult.getCredentials();
System.out.println("AccessKeyId=" + credentials.getAccessKeyId() + " SecretAccessKey=" + credentials.getSecretAccessKey()+ " SessionToken=" + credentials.getSessionToken());
```
ROLE_ARN、ROLE_SESSION_NAMEって何指定したらいいの？となって調べたところROLE_ARNはロールのARN

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167877/e655eb00-9441-84c0-1e6a-e101d42fb567.jpeg)

ROLE_SESSION_NAMEはてきとーな文字列
ex.「role_session」みたいな

最後に使いたいロールに

```json
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::xxxxxxxxxxxx:role/full_ec2_lambda"
            ]
        }

```

のポリシーを追加すればOKです

これで一時的な認証情報が取得できます。
GoogleMap で使える行政区画のデータを取得する

## ページ遷移
1. サイトに移動
2. ページ内の `2. 政策区域` -> `行政区域` をクリック
3. 都道府県選択
4. データ作成年度選択
5. アンケートに回答
6. 利用約款合意
7. ZIP解凍
8. JSONファイルを開く

### サイトに移動
[国土数値情報　ダウンロードサービス](http://nlftp.mlit.go.jp/ksj/index.html)

### 都道府県選択
今回は北海道で。
<img width="727" alt="都道府県選択.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/ced13bfb-f081-f34a-18ba-3f63a45f307b.png">

### データ作成年度選択
今回は最新の平成30年のみ。
まだ令和はない。
<img width="624" alt="年度選択.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/fe81e9ca-33d9-c431-cfb7-9bab30035cd3.png">

### アンケートに回答
今までコンバージョンボタンは右にあったのに、なぜか「回答」ボタンが左にあるので間違って戻らないように。
<img width="655" alt="アンケートに回答" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/003053a2-63eb-47c3-3f4d-97082e0c7f90.png">

### 利用約款合意
内容をよく読んで「はい」を押す。
やっぱりボタンが左にあるので気をつける。

### ダウンロード
<img width="619" alt="4_ダウンロード.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/8ddc65dd-26b3-30c5-e433-41de43ed2ce2.png">

### ZIP解凍
ZIP 形式でダウンロードできるので適宜回答する。
<img width="609" alt="5_解凍後ファイル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/4320f734-6c19-f63c-f272-ffd8b6993336.png">

### JSONファイルを開く
上記のうち GoogleMapsAPI で使えるのは `.geojson` という拡張子になっている JSON ファイルである。
地域によってはめちゃくちゃでかいので、IDEなどで開くと読み込みに時間がかかるかも。
CotEditor で開こうとしたら警告がでました。

### データを間引く
都道府県ごとのデータなので、必要に応じてデータを削除する。
全てを読み込ませようとすると爆死する可能性あり。
`geojson` という拡張子になってるけど、中身はただの json なので `features` というところの項目から不要そうな市区町村をガンガン削除する。

## ブラウザのGoogleMap上に表示してみる

### コーディング
GoogleMapを表示させる。
何らかの方法で json をロードさせる (ajaxなり、サンプルでは変数としてjsonを配置している)。
そして、以下のコードを追加する。

```js
map.data.addGeoJson(geojson);
```

### 完成
[GEO JSON サンプルページ](https://shimon.biz/sample/maps/geojson.html)
[Reactに組み込んだサンプル](https://shimon.biz/apps/maps/geojson)
【C++】同じ文字列が出てくる回数を数える

# 内容
　mapで文字列と出現回数を保持する辞書を作成して同じ文字列が入力されるとその回数を数えるというもの。自分用の備忘録として置いておきます。for文の使い方がちょっと特殊で最初見た時は困惑しました。多分こんな面倒なことしなくてもSTLとかに便利なライブラリやら関数やらがありそうです。環境はVisual Studio 2019です。

動作：
　文字列入力→出現回数出力→文字列入力→出現回数出力→...


▽サンプルコード▽

```c++:sample.cpp
#include <iostream>
#include <map>
#include <string>

using namespace std; // std::map~, std::cout~とかを省略する為

int main() {
	map<string, int> dict; // 文字列と出現回数の辞書作成

	int n; cin >> n; // 下for文のループ回数
	for (string x; n--; dict[x]++) { // 辞書内の文字列xに対応する出現回数を+1する
		cin >> x; // 文字列 x 入力
		cout << "入力文字列: " << x << ", 出現回数: " << dict[x] + 1 << "回" << endl;
	}
}
```

▽入力例▽

```c++:Input
10
orange
orange
apple
apple
grape
grape
apple
apple
orange
orange
grape
```

▽出力例▽

```c++:Output
10
orange
入力文字列: orange, 出現回数: 1回
orange
入力文字列: orange, 出現回数: 2回
apple
入力文字列: apple, 出現回数: 1回
apple
入力文字列: apple, 出現回数: 2回
grape
入力文字列: grape, 出現回数: 1回
grape
入力文字列: grape, 出現回数: 2回
apple
入力文字列: apple, 出現回数: 3回
apple
入力文字列: apple, 出現回数: 4回
orange
入力文字列: orange, 出現回数: 3回
orange
入力文字列: orange, 出現回数: 4回
```

orangeは4回、appleは4回、grapeは3回入力していてうまく機能しています。色々応用できそう。
[Ruby]ゲッターとセッターという方法

#ゲッター・セッターとは
「ゲッター」とはインスタンス変数をクラス内から参照、「セッター」とはインスタンス変数をクラス内から更新するメソッドです。

#セッターを使わないインスタンス変数の更新

今回、ユーザーが入力した金額を1.08倍に更新という手続きを行いましたが、セッターの概念を知らずにこのようなコードをつくりました。

```ruby:モデル
class Product < ApplicationRecord

  def add_tax(price)
   price * 1.08
  end
  
end
```
```ruby:コントローラ
...

def create
    @product = Product.new(product_params)
    @product.price = @product.add_tax(@product.price)

...
```

 無理やり更新しています。

#メソッドをセッターにする

クラス内で更新できるようにします。

```ruby:モデル
class Product < ApplicationRecord
  def add_tax
    self.price = price * 1.08
  end
end
```
```ruby:コントローラ
...

def create
    @product = Product.new(product_params)
    @product.add_tax

...
```

コードがスッキリしました。
ちなみにセッターのときはselfは省略できないようです。

#おまけ
ゲッター・セッターを意識すると、そういえばRailsでattr_asseccorとか記述していないな、と思いました。

これは、ActiveRecord::Baseを継承したクラスは、データベースにアクセスしてクラス名にもとづくテーブル構造を読み取り、自動で属性のゲッター・セッターを作成してくれていたためでした。
SSMSを使わずにデータベースのバックアップと復元を行う

SSMSを使ってウィザードを開き、ポチポチとしてバックアップを取ったり復元したりするのが面倒なので、クエリを書いてバックアップと復元を行う。

今回は、SQL Server 2016での動作です。

## データベースをバックアップ

```SQL

USE master
GO

BACKUP DATABASE データベース名
    TO DISK = 'バックアップする場所\名前.bak'
  WITH INIT
     , COMPRESSION

```
タイムスタンプも付けてもう少し楽に流せるようにする。

```sql
DECLARE
      @WK_NOW     datetime
	, @WK_PATH    varchar(max)
	, @WK_NAME    varchar(max)

BEGIN
    
	SET @WK_NOW  = GETDATE()
	SET @WK_NAME = 'データベース名'
	SET @WK_PATH = 'D:\BACKUP\' + @WK_NAME + '_' + CONVERT(varchar, @WK_NOW, 112) + REPLACE(CONVERT(varchar, @WK_NOW, 114), ':', '') + '.BAK' 

    BACKUP DATABASE データベース名
        TO DISK = @WK_PATH
      WITH INIT
         , COMPRESSION
    
END
```

## 論理名（LogicalName）の確認

```SQL

RESTORE FILELISTONLY
FROM DISK='場所/名前.bak'
GO

```

## データベースの復元

```SQL

RESTORE DATABASE データベース名
FROM DISK = '場所\名前.bak'
WITH MOVE 'MDFの論理名' TO '場所/名前.MDF'
	,MOVE 'LDFの論理名' TO '場所/名前.LDF'

```


論理名（LogicalName）を間違えると

```

メッセージ 3234、レベル 16、状態 2、行 16
論理ファイル '△△△' はデータベース '○○○○' の一部ではありません。RESTORE FILELISTONLY を使用して、論理ファイル名を表示してください。
メッセージ 3013、レベル 16、状態 1、行 16
RESTORE DATABASE が異常終了しています。

```
上記のようなエラーがでます。
[puppeteer]input type=dateへの入力

puppeteerを使った自動テストを導入しているんですが、その中で困ったのが日付の入力。`<input id="inputdate" type="date">`へのタイプです。

# 最近のtype="date"

最近のブラウザは便利で、dateを指定するとカレンダーでの入力ができたり、年月日を区別して入力できたりします。

こういったUI、人間にはとても便利なんですが、puppeteerはご機嫌を損ねます。普通にtypeで入力すると…

![error.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/a596d8e7-65cc-53fc-79b3-3a763da686c5.gif)

__2019-05-06とtypeしたのですが…とんでもない未来にタイプスリップしてしまいました。__


puppeteerのコードはこんな感じ。

```node

await page.type(cssid, "2019-05-06");

```

# puppeteerでdateのinputに入力する方法

今回使ったトリックは「右矢印で月、日の欄に移動」というものです。

```node
const cssid = "input#testdate";

const y = "2019";
const m = "05";
const d = "06";

// まず年をtypeして…
await page.type(cssid, y);
// ここがキモ。右矢印押すことで、月の欄に移動します。
await page.keyboard.press('ArrowRight');
// 次は月
await page.type(cssid, m);
// 日の欄に移動します。
await page.keyboard.press('ArrowRight');
// 最後に日
await page.type(cssid, d);

```

こうすることでいい感じに入力できます。
![success.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23715/5b80f049-5ad2-6768-2d8d-a448d1047029.gif)
【PowerShell】物理メモリ容量を出力する方法

個人メモに非常に近いですが……
ページングファイルの設定をされているマシンからPowerShellで物理メモリの容量を確認、計算し出力するものです。


# メモ
メモ1
→対象のマシンによって絞り込みが変化する？
メモ2
→HWの構成で内容が変わるかもしれない？

- 通常のマシン

```ruby:通常
PS> Get-WmiObject -Class Win32_PhysicalMemory | % { $_.DeviceLocator }
ChannelA-DIMM1
ChannelB-DIMM1
```

- オンボードマシン

(MBに埋め込まれている状態)

```ruby:オンボード

PS> Get-WmiObject -Class Win32_PhysicalMemory | % { $_.DeviceLocator }
Onboard
Onboard
Flash ROM
```

- 仮想マシン



# コマンドレット

```ruby:コマンドレット
Get-WmiObject -Class Win32_PhysicalMemory | Where-Object { $_.devicelocator -ne "Fl
ash ROM"} |%{ $_.Capacity}| Measure-Object -Sum

```

※ページングファイルの情報そのもの除外している


このまま実行すれば下記の通りの画面になります。
出力結果(メモリ8GBの場合)

```ruby:出力結果
Count    : 2
Average  : 
Sum      : 8589934592
Maximum  : 
Minimum  : 
Property : 

```

---

GB計算し、出力する場合は下記コマンドレットを利用する。

```ruby:GBに変換する場合
Get-WmiObject -Class Win32_PhysicalMemory | Where-Object { $_.devicelocator -eq "Onboard"} |%{ $_.Capacity}| Measure-Object -Sum | %{ ($_.sum /1024/1024/1024).toString()+"GB"}
```
51歳からのプログラミング　備忘　passwordが取得できない makeVisible

DBテーブルから情報が取得できない
--
モデルUserを使ってﾛｸﾞｲﾝ認証しようと試み、DBのusersテーブルからpasswordを取得して正誤確認をしようとしたが、passwordが取得できない、という現象に嵌った。

terataileで質問してご教授いただきました内容を、備忘としてこっちに記載。

結論的
--
モデルに、オブジェクトを配列に変換する時に、配列に含まれないようにする設定がありました。eloquentやDBクエリで、テーブル情報をオブジェクトとして取得して、それを配列に変換する時に、配列から省く、という設定です。

設定は、モデルUserの protected \$hidden[ ]で行われてます。
この配列($hidden)で指定されたものは、配列の要素から省かれます。
一時的に配列に含めるようにするメソッドは、makeVisible。

コード
--
```php
$user=User::all();
$user=$user->makeVisible('password')->toArray();
```

これで$userの配列に、passwordが入った。
Chainerでオリジナルのsnapshotを作る

# はじめに

[このteratail](https://teratail.com/questions/124967)にあるような現象が発生したため、`chainer.serializers.save_npz`を使いtrainerを保存するように変更したという話です。

# 問題事項

※実行環境はChainer v5.4でした。 現在のバージョンでは解決されているかもしれません


以下のように`extensions.snapshot`を呼び出してtrainerを保存すると、なぜか`chainer.serializers.load_npz`で保存したtrainerをロードできないときがありました。

```python
trainer.extend(extensions.snapshot(filename='snapshot_latest'), trigger=(args.snapshot_interval, 'iteration'))
```

毎回ロードできないのならまだ分かるのですが、場合によって呼び出せたり呼び出せなかったりするという現象が起きました。

で、原因は`extensions.snapshot`かもしれないとのことだったので、解決策になるかどうかはわかりませんが、自前で`chainer.serializers.save_npz`を呼び出してtrainerのsnapshotをとることにしました。


# 実装

ポイントは`trainer`が各epochやiterationに合わせた様々値を持っている点でしょうか。
せっかくなので呼び出して有効活用してみます。

```python

import chainer

class SnapshotTrainer(chainer.training.Extension):
    def __init__(self, out, fo_name='snapshot', save_type='latest_only'):
        self.out = out.rstrip('/') + '/' + fo_name
        self.save_type = save_type

    def __call__(self, trainer):
        if self.save_type == 'epoch':
            fo = '{}_epoch_{}'.format(self.out, trainer.updater.epoch)
        elif self.save_type == 'iteration':
            fo = '{}_iter_{}'.format(self.out, trainer.updater.iteration)
        else:
            fo = '{}_latest'.format(self.out)

        chainer.serializers.save_npz(fo, trainer)
```

↑のクラスをtrainer.extendで呼び出します。

```python

# Take a snapshot (original)
snapshot_type = 'epoch' if args.snapshot_dvide else 'latest'
trainer.extend(SnapshotTrainer(out=args.out,  fo_name='snapshot', save_type=snapshot_type), trigger=(args.snapshot_interval, 'iteration'))
```

これで解決できている・・・のかなぁ？（今のところ問題なしですが、果たして・・・

# まとめ

今回はsnapshotを`chainer.serializers.save_npz`で保存するExtensionを作りました。

これならsnapshot以外にも色々なExtensionを作れそうです。

# 参考

- [chainerでfine tuningした際にsnapshotが読み込めない](https://teratail.com/questions/124967)
Git ブランチ名変更 Local & Remote

# 1. Local Branch Rename
- 変更したいブランチで

```
git branch -m [新ブランチ名]
```
- 他のブランチで

```
git branch -m [旧ブランチ名] [新ブランチ名]
```
# 2. Delete Old Remote Branch and Push New Branch
```
git push origin :[旧ブランチ名] [新ブランチ名]
```
# 3. Reset Upstream for Local Branch
```
git push origin -u [新ブランチ名]
```
Debian10へNVIDIAドライバをインストール

###1. non-free contrib の追加

```sh:/etc/apt/sources.list

deb http://ftp.jp.debian.org/debian/ buster main non-free contrib 
```

###2. nvidia-detect をインストール/実行してドライバのdeb名を得る。

```
Detected NVIDIA GPUs:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GF108GLM [Quadro 1000M] [10de:0dfa] (rev a1)

Checking card:  NVIDIA Corporation GF108GLM [Quadro 1000M] (rev a1)
Your card is only supported up to the 390 legacy drivers series.
It is recommended to install the
    nvidia-legacy-390xx-driver
package.
```

###3. ドライバのインストール
```
apt install nvidia-legacy-390xx-driver
```

**再起動する**


## トラブル

####Resolutionが勝手に設定され、文字が大きくなりすぎる
 手持ちのHPのノート(解像度1920x1080)では、NVIDIAのドライバにより
DPIが自動的に139x144に設定されてしまう。

NVIDIAのコントロールパネルから"X Server Display Configuration"を選択し、
"Save X Configuration"ボタンで、
/usr/share/X11/xorg.conf.d/90-nvidia.conf として保存し、以下の行を追加する。

```
Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    ....

    Option "UseEditDpi" "FALSE"
    Option  "DPI"   "96x96"
EndSection

```

UseEditDpiとDPIを追加すれば手動で設定できる。
ショートカットの内容を取得する

# やりたいこと
ショートカットのリンク先情報などをコマンドで取得したい！

# 実現方法
Windows PowerShell使います。

## フィルタを作成する

```
filter Get-Shortcut()
{
    $shell  = new-object -comobject WScript.Shell
    return $shell.CreateShortcut($_)
}
```

## コマンド実行

### ショートカット名とリンク先のフルパスを取得

```
dir -r -include "*.lnk" | Get-Shortcut | Select-Object -property Fullname,TargetPath
```

### 引数を取得

```
dir -r -include "*.lnk" | Get-Shortcut | Select-Object -property Fullname,Arguments
```
【Vue.js】開発時のURLから/#/を削除する

### 本記事について
Vue.jsの初心者向けTipsです。

### 目次
・解決したい問題
・解決方法

### 解決したい問題
開発している時にTOPページを見たいと思ったら

localhost:8080/#/
にアクセスするのですが、できれば

localhost:8080
にアクセスしたら表示されるようにしたいなと思ったので、それを解決する方法を調べました。

### 解決方法
```javascript:folder_name/src/router/index.js
export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'Name',
      component: Name
    }
  ]
})
```
として、
**mode: 'history',**を追加するとちゃんとlocalhost:8080でTOPページを表示してくれました。

参考：[Vue.js公式ドキュメント](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)
Maya で deformer を bake し glTF にエクスポートするためのメモ

## 背景

* glTF や,(リアルタイム)レンダリングエンジン側で deformer に対応していない
* rig のモデル自体は Maya で deformer を使って構築されているので, deformer 情報を消す(bake する)必要がある

## Bake deformer tool 

Maya には 2017 Update 3 から Bake deformer tool の機能がつきました.

https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2018/ENU/Maya-CharacterAnimation/files/GUID-DD430C9B-95E7-4EBB-8D2B-A566018B4AC4-htm.html

http://help.autodesk.com/cloudhelp/2017/JPN/Maya-Tech-Docs/CommandsPython/bakeDeformer.html

### 試す

bake deformer tool では, mesh + skelton を入力としているため,  deformer を joint と parenting してみます. 

* CUBE + joint 2 個.
* cluster deformer を作成し, 先端の joint と parent して, joint を動かすと cluster deformer が動くようにする.

![ezgif.com-video-to-gif-setup.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/6750f51e-9361-ac27-8409-52e1455d04e8.gif)

ここから, cube と joint を duplicate して bake 用 mesh + joint を作ります.　 
target は同じ個数の skelton である必要があります.

bake deformer tool に mesh/skelton のペアを記述して, apply します.

![ezgif.com-video-to-gif-baked.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/33b2975a-c98e-90ec-2beb-a792ffcf6ec5.gif)

これで bake 先は, cluster deformer に依存せず, joint を動かすと cluster deformer の効果も出るようになります. 実態は skinCluster(smooth vertex skinning)なので, これをあとは glTF にエクスポートするだけになります.


## 問題点

* bake では, parent した joint のみの対応のようなので, たとえば screenvideo のように, root joint を動かすと, 元メッシュでは cluster deformer の影響があるが, bake したほうは影響は消えてしまう.

* どれくらいの精度で deform 効果を bake してくれるかが不明.

## TODO

* joint の階層でうまく deform 効果 が bake される方法を探す.

* joint に deformer を parenting するのがよい方法なのだろうか?(deformer をどう扱うか推奨方法はドキュメントなどに記載は無い)

* 自前 bake tool の作成を検討してみる. たとえば Sampling-based Rig Conversion into Non-rigid Helper Bones https://mukai-lab.org/publications/i3d2018/ を実装してみるなど.

* 簡単な deformer であればレンダリングエンジン側で対応してみる.

* direct delta mush skinning 対応してみたい Direct Delta Mush Skinning and Variants http://binh.graphics/papers/2019s-DDM/
CentOS使いのubuntu16.04セットアップメモ 

# 備忘録
## キーボードレイアウト

```vim
sudo dpkg-reconfigure keyboard-configuration
setxkbmap -print -verbose 10
setxkbmap jp
```
上記を実行し日本語キーボードにしても再起動するとusキーボード元に戻ったりする。
同事象のバグがあるらしく、システム>キーボードからusキーボードをremoveで解決

## キーバインド

方向キーでのカーソル入力ががうまくいかない
参考：[set nocompatibleはもういらない](https://qiita.com/yu_suke1994/items/e0a19574994a57c8fe17)

```vim
$ touch ~/.vimrc
$ vi ~/.vimrc
set backspace=indent,eol,start
```

## ipv6の無効化
```vim
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
```

## proxy設定
/etc/apt/apt.confに

```vim

Acquire::http::Proxy "http://proxy.xxxx:8080";
```

## 自前でwebサーバーを立ち上げる時Firefoxの設定

about:configでNetwork.security.ports.banned.overrideを追加後
開けたいポート番号を入力する。
Microsoft Remote Desktopで左クリックができない

Microsoft Remote Desktop 10で困ったのでメモしておきます。

リモートでMacOSXからWindowsに接続すると右クリックしかできない症状にあいました。解決方法としてDesktop編集からメニューにある `Swap mouse buttons` のチェックを外すことで解決できました。

<img width="474" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12108/18475c9a-efc5-ec9c-c967-ac22c98fd503.png">

そもそもなぜこんなオプションがあるのかというと、Windowsには左利きの人向けに左右クリックを入れ替えるというオプションがあるためリモート先でその設定がある場合に反転させるためのようです。
商品一括登録、エラー時の挙動について整理

商品CSV登録失敗時の挙動について、
少し複雑なので整理しておこうと思います。
<b>※PostgreSQL, MySQLで挙動が異なる場合があるため、環境を確認の上各自ご判断ください。
（Sequence と Auto Incrementの違いによるそう）</b>

# 結論
10商品同時にアップロードした際に、1件でもエラーがあった場合、
すべての商品が登録されない。
※正常に登録予定だった商品IDは、使用済になる。
（その後、商品登録を行うと、商品CSV登録実行時の件数分が欠番になる。

```
例）
# 前提
- 既に商品ID：1,2,3がある状態
# 実施内容
- CSVにて3件登録(1件不正なデータ）を実施
　→エラーが発生し商品が登録されない
- CSVにて3件登録(正常なデータ)を実施
　→3商品登録される
- 登録されたデータ
商品ID：6,7,8  （※7,8,9ではない　
```


# 実施環境
<a href="https://www.ec-cube.co" target="blank">ec-cube.co</a>サービス環境下で確認しております。

```
EC-CUBE：4.0.2
DBサーバー：PostgreSQL 10.6
WEBサーバー：Apache
PHP：7.2.19 (Core, date, libxml, openssl, pcre, sqlite3, zlib, ctype, curl, dom, fileinfo, filter, ftp, hash, iconv, json, mbstring, SPL, PDO, session, posix, Reflection, standard, SimpleXML, pdo_sqlite, Phar, tokenizer, xml, xmlreader, xmlwriter, mysqlnd, apache2handler, intl, memcached, pdo_pgsql, sodium, zip, Zend OPcache)
```
Desktop : OpenCV FaceDetector By WebCam

<h5>Goal</h5>
Test OpenCV FaceDetector By WebCam.

```OpenCV_FaceDetectorByWebCam.java
import javax.swing.JFrame;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

public class OpenCV_FaceDetectorByWebCam {

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
    public static void main(String arg[]) {
        VideoCapture capture = new VideoCapture();
        capture.open(0);
        JFrame frame1 = new JFrame("show image");
        frame1.setTitle("¤HÁyÀË´ú");
        frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame1.setSize(640, 480);
        frame1.setBounds(0, 0, frame1.getWidth(), frame1.getHeight());
        Panel panel1 = new Panel();
        frame1.setContentPane(panel1);
        frame1.setVisible(true);


        if (!capture.isOpened()) {
            System.out.println("Error");
        } else {
            Mat webcam_image = new Mat();
            capture.read(webcam_image);
            frame1.setSize(webcam_image.width() + 10,webcam_image.height() + 20);

            CascadeClassifier faceDetector = new CascadeClassifier("D:\\projects\\Java\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml");
            MatOfRect faceDetections = new MatOfRect();



            while (true) {
                capture.read(webcam_image);
                if( !webcam_image.empty() ){
                    faceDetector.detectMultiScale(webcam_image, faceDetections);
                    for (Rect rect : faceDetections.toArray()) {
                        Imgproc.rectangle(webcam_image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                                new Scalar(0, 255, 0),3);
                    }

                    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

                    panel1.setimagewithMat(webcam_image);
                    frame1.repaint();



                }else{
                    capture.release();
                    break;
                }
            }
        }
    }

}

```
<h5>Result</h5>
![OpenCV_FaceDetectorByWebCam.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/2353f139-bb65-617a-d255-ff950fdf6604.jpeg)
kubeflow  on Rancher で Pod has unbound PersistentVolumeClaims  エラー

kubeflowをRancher(v2.2.3)でデプロイした際にはまった点のメモ。

#事象

前提として、以下の様にAWS EC2上にRancherでk8sクラスタを構築し、カタログから「kubeflow」を選択して実行

https://qiita.com/suzukihi724/items/00b167c6f5f2ddeca718

<img width="1035" alt="スクリーンショット 2019-05-28 15.16.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/cda6895b-cf94-8f2b-f258-5025251346b4.png">

すると、一見デプロイは成功した様に見え、kubeflowダッシュボードにもアクセスできる。

<img width="724" alt="スクリーンショット 2019-05-28 15.17.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/9cb85a7a-bf37-516e-c8a8-223bb442cb73.png">

次に「Jupyterhub」を起動すると、下記の「Spawning Server」の状態から進まず、結果エラーとなる。

<img width="922" alt="スクリーンショット 2019-05-28 12.31.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/e6e9f06b-c768-2614-1d62-f7a115d853b4.png">

ログを確認すると以下のエラー。

```
Pod has unbound PersistentVolumeClaims
```

#原因と対処

原因はエラーログの通り、Persistent Volume（永続ストレージ）が正しく設定できていないため。
kubeflowのコンポーネント「vizier-db」が永続ストレージを必須とするらしい。

対処は、GitHub issuesの「oganhz commented on 9 Oct 2018」のレスが参考になった。

https://github.com/rancher/rancher/issues/13442

カタログから、「nfs-provisioner」を作成した後に、kubeflowをデプロイすることで、エラーは解消。
これが永続ストレージをケアしてくれる。

<img width="293" alt="スクリーンショット 2019-05-28 15.25.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/75a55311-6bdd-146b-2f1f-0b036a990010.png">

とりあえず設定はすべてデフォルトで起動すると、Storage Classが生成される。

<img width="865" alt="スクリーンショット 2019-05-28 15.27.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/6498cc80-83ea-a319-2f4d-559beace0d31.png">

その後、kubeflowを起動すると、PersistentVolumeマウントが必要なコンポーネントがよしなに設定され、エラーなく起動できた。

<img width="868" alt="スクリーンショット 2019-05-28 15.34.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/967d7000-83d0-b590-b46a-30cb91037397.png">

<img width="807" alt="スクリーンショット 2019-05-28 15.35.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/02e6fd27-22d9-328a-f8b9-f296640c2198.png">


#参考

https://qiita.com/ysakashita/items/8b411943f7e25dc4c5b0

https://qiita.com/cyberblack28/items/4b94e4272d908322ed74

https://speakerdeck.com/fufuhu/kubernetesfalseyong-sok-hua-sutoreziji-chu

https://cstoku.dev/posts/2018/k8sdojo-12/
【iOS】レシート風 CardViewの作成（WIP）

# はじめに
レシート風のCardViewを一緒に作ってみよう！

# 実装
大まかな流れは，
1. Main.storyboardにレシートの土台となるViewをおく
2. レシートViewの細かい設定
3. 他の部品を置いてよりレシートっぽく
4. labelデータの反映（後日記載）
となっています．また，今回の記事は以下の動画を参考にしております．
参考：[Card View in iOS (Xcode8 , Swift3)](https://www.youtube.com/watch?v=y-Tk7biMlOM)

## 1. storyboardの準備

まずは，Main.storyboardにViewをおきます．
<img width="1440" alt="スクリーンショット 2019-05-28 16.45.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/83126336-5d52-b3c1-a9dd-4e22df7cfeb5.png">

ここで，AutoLayoutの設定もしておきましょう．画面全体に表示したいので，今回は上下左右全て10pxだけ余白をとります．ぽちぽち．
<img width="1440" alt="スクリーンショット 2019-05-28 16.54.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/ce955998-c5b8-69e7-44d9-3c60be20b23e.png">


AutoLayoutについて詳しく知りたい人はこちらをオススメします．
→ [怖くない！AutoLayout 〜多画面対応 with Storyboard〜](https://qiita.com/_ha1f/items/5c292bb6a4617da60d4f)



## 2.レシートViewの設定
続いて，Viewに影をつけていく設定をしていきましょう！
UIViewファイルを追加しましょう．ここでは`ReceiptView`と名付けます．
<img width="1440" alt="スクリーンショット 2019-05-28 17.00.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/0926db8d-0a4c-1e0f-70f3-b1a823acee54.png">

作れたら，中身を書いていきましょう．
レシートの影の色や大きさ，不透明度，またViewの角を丸くしたい時もここに書いていきます．

```ReceiptView.swift
import UIKit

@IBDesignable class ReceiptView: UIView {

    //影の設定
    @IBInspectable var shadowOffSetWidth : CGFloat = 0  //影の横幅
    @IBInspectable var shadowOffSetHeight : CGFloat = 5  //影の縦幅
    @IBInspectable var shadowColor : UIColor = UIColor.black  //影の色
    @IBInspectable var shadowOpacity : CGFloat = 0.5  //影の不透明度
    
    override func layoutSubviews() {
        layer.shadowColor = shadowColor.cgColor
        layer.shadowOffset = CGSize(width: shadowOffSetWidth, height: shadowOffSetHeight)
        layer.shadowOpacity = Float(shadowOpacity)
    }
        
}
```

`@IBDesignable` と `@IBInspectable`は簡単に言うと，デフォルトでいじれない設定をいじれるようにしたり，storyboard上でリアルタイムで見た目を変えてくれるための呪文みたいなもの．
詳しくはこちらの記事を参考に！
参考：[【決定版】IBDesignable, IBInspectable](https://qiita.com/son_s/items/7ca2acf690d10f9fd1b7)

さぁ，ここまできたらMain.storyboardで作成したUIViewファイルを紐付けましょう！
<img width="1145" alt="スクリーンショット 2019-05-28 16.06.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/a4753054-7c12-0b85-b7f7-7eaafe610707.png">

1で置いたViewを選択し，Classに先ほど作成したUIViewファイル名（今回は`ReceiptView`）を手打ち．自動的に読み込みがスタートし，影がついたら成功！何も動かない場合は`⌘+B`でビルドしてみましょう．
ここまできたら，一度Runしてみましょう！以下のようになりましたか？
<img width="277" alt="スクリーンショット 2019-05-28 16.13.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/dbe044c1-389a-029f-c1d3-1875c86e8b20.png">

背景を暗くしても◎

```ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.gray
    }
```
<img width="270" alt="スクリーンショット 2019-05-28 16.16.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/5a4da321-7d94-c84b-a99c-479fb9b8d8cd.png">


## 3.他の部品を置いてよりレシートっぽく
タイトルや日付，セットリストなど自分の好きなデザインに必要なlabelや画像を配置していきましょう．
ここからはあなた次第！
<img width="272" alt="スクリーンショット 2019-05-28 16.34.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/ca691c42-e171-d48f-d41a-09d3ea26d5e7.png">
SPSS Modelerでフォルダ内のCSVを一括で読み込む（Modelerスクリプト版）

SPSS Modelerでフォルダ内のCSVを一括で読みたいことがあります。
これをModelerスクリプトをつかって実現しました。

■テスト環境
Modeler 18.2.1 および18.4


# 1.フォルダ内にcsvを配置する

以下のように一つのフォルダに同じ列を持つcsvを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/964fb546-ac53-bd44-3465-c47ce41ad954.png)

# 2.空のキャンパスを開き、スクリプトを入力する
「ツール」＿「ストリームのプロパティ」＿「実行」でスクリプトの入力画面を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/50eb16ed-df70-8e71-bb6f-aa3e9ebecdb5.png)

実行モードが「デフォルト」で、スクリプトが「Python」であることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4ccfba42-e6e0-9a94-3d5a-7086e70908ee.png)

# 3. 以下のスクリプトを入力し、実行します。

```Python
stream = modeler.script.stream()
import os
TargetPath = 'C:/data/test'
files = os.listdir(TargetPath)

append = stream.create("append","append")
append.setXYPosition(200, 10)
for i, file in enumerate(files):
    input = stream.create("variablefile","varnd")
    input.setPropertyValue("full_filename", TargetPath+'/'+file.decode('utf-8'))
    input.setXYPosition(50, 10+i*100)
    stream.link(input,append)
```
TargetPathが一括処理をするCSVが入ったフォルダになります。

このスクリプトを実行ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/42c8b40e-7e39-f6bb-f154-e9cd9a859320.png)

以下のようにCSVファイルを読み込んでレコード追加でまとめてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1fce5fb6-242e-70dc-256c-52109f9a6731.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cb388101-862d-9a70-ebda-decb7c9c47f0.png)


# 参考

IBM 特定のフォルダにある全てのcsvファイルを可変長ノードから読み込む方法
https://www-01.ibm.com/support/docview.wss?uid=swg22011818
この記事のPythonスクリプトがベースになっています。
Pythonのargparseを使っているメソッドをシェルではなくPythonの別ファイルから呼び出す

```python:file1.py
import argparse


parser = argparse.ArgumentParser(description='')
parser.add_argument('--hoge')
parser.add_argument('--fuga')

def run(env, *_args):
  args = parser.parse_args(_args)
  hoge = args.hoge
  fuga = args.fuga
```

この場合の `run` メソッドをシェルではなく、別のPythonのファイル内から呼び出したいとき。

`*_args` は可変長引数なので、そのまま↓のような感じでOK。

```python:file2.py
from file1 import run


run(env, '--hoge', 'hoge', '--fuga', 'fuga')
```

型が指定されている場合は、正しく渡してあげてください。

`TypeError` とか出てきてデバッグがちょっと辛かった...
Desktop : OpenCV FaceDetector

<h5>Goal</h5>
Test OpenCV face detector.

```OpenCV_FaceDetector.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

public class OpenCV_FaceDetector {
    public static void main(String[] args) {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("\nRunning FaceDetector");
        CascadeClassifier faceDetector = new CascadeClassifier("D:\\projects\\Java\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml");
        Mat image = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");

        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image, faceDetections);

        System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        for (Rect rect : faceDetections.toArray()) {
            Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                    new Scalar(0, 255, 0),3);
        }

        String filename = "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena-FaceDetector.jpg";
        System.out.println(String.format("Writing %s", filename));
        Imgcodecs.imwrite(filename, image);
    }
}

```
<h5>Result</h5>
![lena-FaceDetector.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/b3dc24da-b4cf-2dfc-569b-7f46ca8dd30e.jpeg)
データベース設計であえて正規化を行わないとき

たいていリレーショナルデータベース（RDB）で論理設計を行う際におそらく第三正規化までは行うかと思います。
しかし、条件反射で常に正規化をしようとするとうまく設計できないこともあります。

#ユーザーの注文履歴について考える
ECサイトを作るにあたり、注文履歴を管理するとしましょう。例えば以下のようなテーブルがあるとします。

**ユーザーの注文履歴情報**

|    ID    |    ユーザー名    |    購入日     |    商品名    |    金額    |    販売者    |    配送先    |
|:--------:|:---------------:|:------------:|:-----------: |:----------:|:-----------:|:-----------:|
|        1 | ヒロロ開発部長    |  2019/01/01 |  iPhone6s    |   39,800   |     D社     |東京都新宿区西新宿1-1-1|

**ユーザー情報**

|    ID    |    ユーザー名    |    配送先    |
|:--------:|:---------------:|:------------------:|
|        1 | ヒロロ開発部長    |東京都新宿区西新宿1-1-1|

**商品マスター**

|    ID    |    商品名    |    金額    |  販売者  |
|:--------:|:-----------:|:----------:|:--------:|
|     1    |  iPhone6s   |   42,800   |  A社     |
|     2    |  iPhone6s   |   39,800   |  D社     |
|     3    |  iPhone7    |   48,800   |  D社     |

この時、「おっ、ユーザーの注文情報にユーザーIDと商品マスターIDを外部キーとしてもたせられるな」と思い、ユーザーの注文情報テーブルを以下のようにします。

**ユーザーの注文履歴情報’**

|    ID    |    ユーザーID    |    商品マスターID    |    購入日     |
|:--------:|:---------------:|:------------:|:-----------: |
|        1 |    1            |  2 |  2019/01/01 |

こうすれば問い合わせるときにユーザーIDと商品マスターIDをもとにテーブル結合すればユーザーの注文情報を取得することができます。
しかし、これではあってはならない問題が発生します。

## マスター情報を変更すると注文履歴の情報が変わってしまう
例えば、2019/5/28にユーザーが配送先を変更した場合、ユーザー情報のテーブルは以下のようになります。

**ユーザー情報'**

|    ID    |    ユーザー名    |    配送先    |
|:--------:|:---------------:|:------------------:|
|        1 | ヒロロ開発部長    |東京都江東区木場1-1-1|

その場合、注文履歴情報はテーブル結合することを前提としているため、結果的に2019/01/01に購入したときの配送先が変わってしまうことになります。

また、同様に販売者が2019/01/01以降に商品価格を変更した場合、同様に実際に購入したときの金額が変更後の価格に塗り替えられてしまいます。
「商品名だけだと同名のものが多く混在しそうだから商品IDで管理したほうがいいだろう」と考えて安易にこのようにしてしまう可能性があります。十分に検討しないとシステムが甚大な不具合を発生させる危険があります。

どういうものにするかにもよりますが、**履歴のようにデータの変更が発生しないものを管理する際は無理に正規化をしないほうがいいです**。ただし、購入予定リスト（Amazonでいう「カートにいれているもの」）とかはマスターの変更に伴い、価格なども反映される必要があるので正規化するべきでしょう。


# まとめ
このような思考にたどり着くまでに正規化するのはいいですが、それで終わってしまってはいけません。
ちゃんと設計できる人はこのようなことは当たり前に思われるかもしれませんが、常に正規化をするのではなく、**アプリケーションの目的をしっかり踏まえて考える**ようにしましょう。
CentOS7におけるCUIでのSSHポート変更。

# 概略
ウェブサーバーにしようと、CentOS7.6を余っていたデスクトップマシンにクリーンインストールしたので、それの色々な設定について備忘録を記す。今回は、sshの設定をアレコレした奮闘の記録である。

# マシン概要
CPU：AMD A8-7600
RAM: Corsair DIMM DDR3 1333 MHz 4GiB (２枚)
SSD: TS64GSSD340 64GB
HDD: Toshiba THNSNJ12 128GB
Wireless interface: Intel wireless 7260

# SSH接続の設定変更
よりセキュアなウェブサーバーにするために、設定を変更したほうが良いみたいなのでする。
変更項目は、
１）ssh接続ポートを22から2200にする。
２）ファイアウォールに、2200への接続を許可させる。
３）SELinuxに、2200への接続を許可させる。

### まずは、ssh接続ポートを22から2200へ
これはとても簡単。
<pre>sudo nano /etc/ssh/sshd_config</pre>
で、
<pre>Port 22</pre>
を
<pre>Port 2200</pre>
に書き換えた。
ついでに、
<pre>PermitRootLogin no</pre>
にした。
*　PasswordAuthenticationは、yes。

以下の項目も追加した。
<pre>AllowUsers MyUser</pre>
* MyUserは、自分のユーザーアカウント名

### 続いて、ファイアウォールの設定。
sshへの接続ポート許可は、以下のファイルをイジって変更できる。
<pre>sudo nano /usr/lib/firewalld/services/ssh.xml</pre>
port="22"となっている部分をport="2200"に書き換える。
以上。

### 最後にSELinuxの設定。
まずは、sshへの設定を確認。
<pre>sudo semanage port -l | grep ssh</pre>
ところが、semanageがデフォルトでは、インストールされていなかったので、まずはインストール。
<pre>sudo yum -y install policycoreutils-python</pre>
気を取り直して、
<pre>sudo semanage port -l | grep ssh</pre>
すると以下の通りに表示された。
<pre>ssh_port_t tcp 22</pre>
これを2200も許可させる。
<pre>sudo semanage port -a -t ssh_port_t -p tcp 2200</pre>
これで設定完了。
外部からsshアクセスするには、
<pre>ssh MyUser@ip -p 2200</pre>
これで、ssh経由でガンガンサーバーのセットアップができる！
【CSS】フッターをコンテンツに依存せず、最下部に固定する

## こんなときに
* フッターをページ最下部に固定したい。
* コンテンツが短かったり、長かったりする場合がある。

## コード
### Pug
```pug
.wrap
  .header ヘッダー
  .contents コンテンツ
  .footer フッター
```

## SCSS
```css
.wrap {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.footer {
  margin-top: auto;
}
```


## 解説
### ポイント
* 縦向きのflexboxを使う。
* flexboxの、並んだ要素を外の要素内に押し込めてしまう性質を利用する。
* フッターには` margin-top:auto`を用いて、自動で寄ってもらう。

### 外側
```scss
.wrap {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
```

ページの全てを囲うdivに ` display: flex;`を使い、向きを縦にする。
ページ全体の高さを、ページの高さ`100vh`で指定しておく。
ページのコンテンツが画面に収まらない量の場合は、その量に応じた高さにするため、`height`ではなく`min-height`を使う。

### フッター
```scss
.footer {
  margin-top: auto;
}
```

フッター側では、上のマージンを`auto`にするだけ。
外側のFlexboxがページ分の高さを確保しているため、コンテンツが少ない場合、自動で最下部に寄る。


## 実装デモ
[footer-fixed-page-bottom](https://codepen.io/dorara_css/pen/EzpjzP)


## 参考
[footerを常に最下部に固定する方法(簡単) - Qiita](https://qiita.com/nozomi716/items/2b09d5bce3d08d1c41f9)
[CSSフッタを最下部に表示する5つのテクニック-コンテンツ量が少ない時は最下部に、多い時は成り行きに | コリス](https://coliss.com/articles/build-websites/operation/css/css-sticky-footer.html)
[CSS Flexbox の各プロパティの使い方を詳しく解説 | コリス](https://coliss.com/articles/build-websites/operation/css/css3-flexbox-properties-by-scotch.html)
Liferayのキャッシュファイルのクリア

Liferay7.0からはOSGiフレームワークを採用しました。

４箇所を削除するとOSGi、Tomcatの一時ファイルを完全クリアできます。

{LIFERAY_HOME}:Liferay本体のパス。例：C:\liferay-dxp-7.1.10.1-sp1
{TOMCAT_HOME}:Liferay本体にあるTomcatのパス。例：C:\liferay-dxp-7.1.10.1-sp1\tomcat-9.0.6

①、Tomcatを停止

②、下記フォルダーの中身を削除
・{LIFERAY_HOME}\osgi\state
・{LIFERAY_HOME}\work
・{TOMCAT_HOME}\temp
・{TOMCAT_HOME}\work\Catalina\localhost

③、Tomcatを起動


以上
PostgreSQL 「image not found!!」が出たらやってみる方法!!

# PostgreSQL 「image not found!!」が出たらやってみる方法

```sh:Error-Message...
dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib
  Referenced from: /usr/local/bin/psql
  Reason: image not found
Abort trap: 6

```

解決方法。

```sh:ターミナル
$ ls /usr/local/opt/readline/lib/

libhistory.8.0.dylib	libhistory.dylib	libreadline.a
libhistory.8.dylib	libreadline.8.0.dylib	libreadline.dylib
libhistory.a		libreadline.8.dylib	pkgconfig

$ ln -s /usr/local/opt/readline/lib/libreadline.8.dylib /usr/local/opt/readline/lib/libreadline.7.dylib
```


[参照先: Mac psql/readline - Library not loaded][so1]


とりあえず、上記の参照先で解決!
アップデートやらアップグレードやら紹介してるサイトばかりだったが、
困った時の"シンボリックリンク"で解決したw

<!-- Link's -->
[so1]:https://stackoverflow.com/questions/42356309/mac-psql-readline-library-not-loaded/42377043
なぜ、当たり前のことが難しいか。仮説(78)

保守性の高いコードを書くためにはどうしたらよいか
https://qiita.com/syguer/items/f5d9d02d8405d63d30a4
>自分で書いていても当たり前のことだなぁと思うものの、当たり前のことを続けることは意外と難しいものです。

なぜ、当たり前のことが難しいかを、いくつかの事例を頭に思い浮かべながら整理してみる。

# テストコードを書く
自分の知る範囲で、９割くらいの学校で、設計と試験を同時に書くことを習慣づけていない。

数少ない試験を書くことを教えている学校では、OS、言語、通信規約の設計を教えていない。

どういう設計の時は、いつ、何のためにテストコードを書くかを教えていない。

テストコードを書く場合でも、最終納品試験のテストコードは書けても、二つの設計の候補を評価するためのコードは書けないとか。

テストコードを書くのが難しいのは、設計と試験と仕様が三位一体で同時に考えないとよい設計、よい仕様になることが確かめられないことを経験していないからかも。

# 静的解析ツールを使う
無料のツールでは痒いところに手がとどかない場合があるかもしれない。
しかし、有料のツールを買ってもらえない場合があるかもしれない。

無料のツールであっても、かければ価値があるかもしれない。

dockerで用意しておくといいかも。

# ライブラリのコードを使う。
どれだけライブラリがあるか知らない。
知らないコードは使えない。

# コードを読む
ライブラリに限らず、オープンソースのコードを読んでいると、世の中のコード品質の動向がわかる。

自分のコードが時代遅れかどうかなど。

出荷するコード以外のコードを読む時間がないのかもしれない。

デンソークリエイトという会社には、仕事時間の１割を、次のプロジェクトでつかうかもしれない技術の勉強にあてていいという制度がある。

http://www.denso-create.jp/recruit/voice/
>技術的なことは仕事のなかで十分学んでいけますし、当社には月に16時間を自己啓発や新技術の勉強のために自由に使える「3C（Change・Challenge・Charge）活動」や、さまざまな年代の技術者が集まって自主的にテーマを掲げ活動する「アトリエ」もあります。

ソフトウェアの会社に、こういうあたりまえのことができるようにする制度がないと無理かも。

よい制度があっても、仕事が忙しくて有効活用できていなかったり、現状で満足していたり、社内一なら安心してしまう風土があると、うまく機能しないかもしれない。

# まとめ
架空の話では、あたりまえのようなことでも、実際に、特定の組織の特定の個人にあてはめると、
無理なことばかりのことがある。

どこを突破口にするとよいかは、本人次第かも。

p.s.
最後の１行は逃げ口上です。

それでは無責任そうに見える。あたりまえのことを、当たり前にやるにあたり、ツールの導入、内部の勉強会の企画など、提案、協力などは随時しています。組織上の制約で、半分以上の仕事時間を名古屋市内の企業または個人のために費やす必要があります。名古屋市内以外の方には、お待ちいただくことがあります。ごめんなさい。

# 文書履歴(document history)
ver. 0.01 初稿 20190528 午後
ver. 0.02 p.s.追記 20190528 夜
ver. 0.03 URL、引用追記 20190529
ver. 0.04 標題追記 20190530

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
RSpecのsubjectを有効活用できるようなコード例

# TL;DR

入力値を出力値にマッピングするようなメソッドのテストには`subject`をガンガン使っていいと思う。

# コード例

```ruby
RSpec.describe Person, type: :model do
  describe '#adult?' do
    subject { person.adult? }

    context 'when age is under 20' do
      let(:person) { Person.new(age: 19) }
      it { is_expected.to be false }
    end

    context 'when age is over 20' do
      let(:person) { Person.new(age: 20) }
      it { is_expected.to be true }
    end
  end
end
```

# コード例（その2）

```ruby
RSpec.describe Product do
  describe '#purchasable_by?' do
    subject { product.purchasable_by?(user) }

    context 'when product is sake' do
      let(:product) { create(:product, type: 'sake') }
      context 'when user is an adult' do
        let(:user) { create(:user, :adult) }
        it { is_expected.to be true }
      end

      context 'when user is not an adult' do
        let(:user) { create(:user, :non_adult) }
        it { is_expected.to be false }
      end
    end

    context 'when product is not sake' do
      let(:product) { create(:product) }
      let(:user) { create(:user, :non_adult) }

      # あえてワンライナーで書かないで可読性を上げる
      it 'always returns true even when user is not an adult' do
        is_expected.to eq true
      end
    end
  end
end
```
Desktop : OpenCV StereoSGBM

<h5>Goal</h5>
Test OpenCV StereoSGBM.

```OpenCV_StereoSGBM.java
import org.opencv.calib3d.StereoBM;
import org.opencv.calib3d.StereoSGBM;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

public class OpenCV_StereoSGBM {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    //SGBM(Semi-global block matching), BM(Block matching)
    public static void main(String[] args) {
        Mat imgLeft = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\scene_l.bmp",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
        Mat imgRight = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\scene_r.bmp",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);


        //創建我們修正的差距圖片
        Mat imgDisparity16S = new Mat( imgLeft.rows(), imgLeft.cols(), CvType.CV_16S );
        Mat imgDisparity8U = new Mat( imgLeft.rows(), imgLeft.cols(), CvType.CV_8UC1 );


        //準備StereoBM建構子所需參數
        int ndisparities = 16*5;   // 視差範圍
        int SADWindowSize = 21; // block window區塊視窗之大小,須奇數

        // 計算視差影像
        StereoSGBM sgbm = StereoSGBM.create( 0,32,10);
        //StereoSGBM sgbm = StereoSGBM.create( 0,16,3);
        sgbm.compute( imgLeft, imgRight, imgDisparity16S );

        //檢查極端值
        Core.MinMaxLocResult minMaxVal=new Core.MinMaxLocResult();
        double minVal; double maxVal;


        minMaxVal=Core.minMaxLoc( imgDisparity16S);
        minVal= minMaxVal.minVal;
        maxVal=minMaxVal.maxVal;

        System.out.println("Min value="+minVal+", Max value="+maxVal);

        //使用 CV_8UC1格式之影像
        imgDisparity16S.convertTo( imgDisparity8U, CvType.CV_8UC1, 255/(maxVal - minVal));

        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\SGBM_sample.png", imgDisparity16S);
    }
}
```
<h5>Result</h5>
![SGBM_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/f89c10e1-f5f9-8b64-6a34-ad993f4e3789.png)
Desktop : OpenCV StereoBM

<h5>Goal</h5>
Test OpenCV StereoBM.

```OpenCV_StereoBM.java
import org.opencv.calib3d.StereoBM;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;


public class OpenCV_StereoBM {

    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) {
        Mat imgLeft = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\scene_l.bmp",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
        Mat imgRight = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\scene_r.bmp",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);


        //創建我們修正的差距圖片
        Mat imgDisparity16S = new Mat( imgLeft.rows(), imgLeft.cols(), CvType.CV_16S );
        Mat imgDisparity8U = new Mat( imgLeft.rows(), imgLeft.cols(), CvType.CV_8UC1 );


        //準備StereoBM建構子所需參數
        int RangeOfDisparity  = 16*5;   // 視差範圍
        int BlockWindowSize = 21; // block window區塊視窗之大小,須奇數

        // 計算視差影像
        StereoBM sbm = StereoBM.create( RangeOfDisparity, BlockWindowSize );
        sbm.compute( imgLeft, imgRight, imgDisparity16S );

        //檢查極端值
        Core.MinMaxLocResult minMaxVal=new Core.MinMaxLocResult();
        double minVal; double maxVal;


        minMaxVal=Core.minMaxLoc( imgDisparity16S);
        minVal= minMaxVal.minVal;
        maxVal=minMaxVal.maxVal;

        System.out.println("Min value="+minVal+", Max value="+maxVal);

        //使用 CV_8UC1格式之影像
        imgDisparity16S.convertTo( imgDisparity8U, CvType.CV_8UC1, 255/(maxVal - minVal));

        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\SBM_sample.png", imgDisparity16S);
    }
}

```
<h5>Result</h5>
![SBM_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/5688a23e-23a9-cab7-ece3-4b3e60664c6f.png)
SPSS Modelerの機能拡張ロードマップと新機能リクエスト

# 1.SPSS Modelerの機能拡張ロードマップ
SPSS Modelerの今後の機能拡張については、Webで公開されています。

以下のサイトではIBMのAnalyticsソフトウェアの今後のロードマップが公開されています。
https://ibm-analytics-roadmaps.mybluemix.net/

この中からSPSS Modelerを選ぶとSPSS Modelerの機能拡張ロードマップを調べることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/5815da25-33cd-32aa-5c61-031df7ec234e.png)

一番最後のページに機能レベルの拡張予定が掲載されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6f6a817e-b62f-3590-b3eb-43ba95c8528f.png)


ただし、ここに書かれている機能が必ず予定通りにでることは保証されてはいません。あくまで参考情報という位置づけです。

#2. 新機能リクエスト
以下のサイトでは新機能のリクエストもすることができます。
https://ibmanalytics.ideas.aha.io/?project=MDLR


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/83faa2bd-c29c-2a95-6214-a828b497ed4e.png)


「Add a new idea」ボタンで誰でもリクエストを上げることができます。
また、他の人があげているリクエストの「Vote」のボタンで投票することもできます。
各リクエストには「Planned」や「Future Consideration」などのステータスも表示されています。
InfluxDB Measurement間データコピー



```
SELECT * INTO "DATABASE"."RETENTION POLICY"."MEASUREMENT-TO"
  FROM "DATABASE"."RETENTION POLICY"."MEASUREMENT-FROM"
 GROUP BY *;
```

ポイントは、```GROUP BY *```。これを指定しないと集約されてしまう（ことがある？）。

もちろん、WHERE句で、コピー元を絞り込み可能

```
SELECT * INTO "DATABASE"."RETENTION POLICY"."MEASUREMENT-TO"
  FROM "DATABASE"."RETENTION POLICY"."MEASUREMENT-FROM"
 GROUP BY *
 WHERE now() - 10m < time;
```

なお、インスタンス間のデータコピーの場合は、influx CLIにImportなるものがあるが、Exportの方法が分からないので試してない。

https://docs.influxdata.com/influxdb/v1.7/tools/shell/#import
作業用Dockerコンテナ起動コマンドのメモ

１行メモ。

```bash
$ docker run -it --rm --name console --user `id -u`:`id -g` --volume `pwd`:`pwd` --workdir `pwd` <image> bash
```

改行入れると、こんな感じ。

```bash
docker run \
  -it \
  --rm \
  --name console \
  --user `id -u`:`id -g` \
  --volume `pwd`:`pwd` \
  --workdir `pwd` \
  <image> bash
```

## 補足説明

- ```-it``` で、 ```--interactive``` と ```--tty```の略。要は対話型コンソールで起動するオプション
- ```--rm```で、コンテナ終了時、自動削除。
- ```--name``` は、コンテナの名前。お好きな名前でどうぞ。
- ```--user `id -u`:`id``` で、今現在のUser IDでコンテナに入る。同一ユーザでファイル操作できるように。
- ```--volume `pwd`:`pwd````で、今現在のディレクトリをそのままマウントする。コンテナ内でファイル修正しても、そのままホスト側に残せます。
- ```--workdir `pwd````で、作業用ディレクトリ（コンテナ内）を指定。コンテナ起動直後のカレントディレクトリとなる。
- ```<image>```は、お好きなイメージIDをどうぞ。ex) node, python, java...
- ```bash```がNGの場合は、```sh```で起動してみて。

## その他

さらに、```--network host```とか追加しても良いかも。コンテナ内で、Webサーバ起動して、外部からアクセスも可能になる。
プログラマが熱中症にならないようにできる５つのこと

プログラマは、夜遅くまで仕事をして、睡眠時間が少なく、不健康な印象を持つ方がいる。

プログラマは健康であるという印象を持ってもらうためにも、今年はプログラマが熱中症にならないようにいくつか考える。

# 飲み放題(free drinking)
仕事場がフリドリだといいですね。

水、お茶、スポーツ飲料のいずれかがあればよい。

仮説・検証(12)プログラマが能力を発揮できる１６の条件

https://qiita.com/kaizen_nagoya/items/94538999a4edfe1332ef

 <この項は書きかけです。順次追記します。>

# 飲料推奨

昔は、計算機室などでは、飲食厳禁だったことがある。
最近では、冬はインフルエンザ対策、夏は熱中症対策で、「蓋のついた容器から水分を補給するように」という、許可ではなく、推奨するようになってきた。

まだ、水分補給が禁止されている区画のある仕事場があれば、ぜひ、お知らせください。

# 水分補給組合

火事であれば、消防署の査察が可能だが、水分では保健所とかに査察の権限はないかも。
もし、官庁に権限がないのであれれば、水分補給組合かなにかを作って、水分補給が適切にできるように、事業者が指導しているかどうかを査察するのもいいかもしれない。

# 空調
熱中症は、温度だけでなく、湿度が関係することもあるらしい。
現在いる人たちの体調が、どの範囲の温度、どの範囲の湿度がよいか、面談や質問票で確かめて、空調の設定をするとよい。個々人の特質にあうことが大事で、一律どうするということだけでは十分ではない。

妊婦の方には、意見は倍の手間をかけてください。本人のそれまでの体調と、今の体調とは同じとは限りません。
面談や質問票は、二人分という感じで。

#　屋根・傘
男性も日傘を持ちましょうという広報が増えている。

日焼けをする目的で特定の時間、日にあたることは、日照時間の少ない地方では健康増進に役立つことがある。

そうであれば、１０月から４月くらいまでの涼しい間に日にあたればよい。

暑くなってからは、熱中症対策に専念しましょう。

以前は、ベランダで、日に当たりながらプログラム組んでいたことがある。

気温が３０度以上になった日には、辞めるようにした。

屋根のあるところで仕事をしましょう。
「あたりまえだって？」「ごめんなさい」

# 参考資料
Mac mini 21台常備試験・研修室
https://qiita.com/kaizen_nagoya/items/3fc572d06eafe15a4c35

仮説・検証(77) 組織的なことと個人的なこと
https://qiita.com/kaizen_nagoya/items/ba34d076112b3ac694e3

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
 
# 文書履歴(document history)
ver. 0.01 初稿 20190528
ver. 0.02 ありがとう追記　　20230729

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
JavaScriptで動的に追加した要素（テーブルとか）でクリックイベントが反応しない

#JavaScriptで要素（テーブル）を動的に追加した時、テーブルセルのクリック時にクリックイベントが反応しない件

いやーまいった。
悩むこと1時間。いやもっとか。
備忘録として記入


------------
変更前のソース

```js
$(function(){
    $(".hogehoge_table td").click(function(){
        $tag_td = $(this)[0];
        $tag_tr = $(this).parent()[0];
        console.log($tag_tr.rowIndex);  // クリック時の行番号確認用
    });
});
```

これじゃ、だめらしい。
-------------
変更後

```js
$(function(){
    $(document).on('click', '.hogehoge_table td',function(){
        $tag_td = $(this)[0];
        $tag_tr = $(this).parent()[0];
        console.log($tag_tr.rowIndex);// クリック時の行番号確認用
    });
});
```

clickではなく、onを使って解決。
iPhone の Chrome だと 新しいウィンドウで https://maps.apple.com が開けない

StackOverflowでも取り上げられていますが、iPhone の Chrome だと 新しいウィンドウで https://maps.apple.com が開けないようです。

https://stackoverflow.com/questions/55603010/how-to-get-chrome-browser-on-ios-to-open-map-link

以下のようなタグで開くケースです。

```
<a href="https://maps.apple.com/maps?q=%E6%9D%B1%E4%BA%AC%E9%83%BD%E6%B8%8B%E8%B0%B7%E5%8C%BA%E6%B8%8B%E8%B0%B71%E4%B8%81%E7%9B%AE " target="_blank">東京都渋谷区渋谷1丁目 </a>
```

ためしにリンクのURLを直接新しいタブで開くと「このページは別のアプリケーションで開かれます。」というダイアログが表示されます。「開く」を選択するとMapsで開きます。

# 原因

一度新しいタブを開くような動きをした後に閉じる？ような動作をしていそうでした。



# 解決策

今のところ見つかっていません。
なおSafariでは、問題なく開くことができます。
target="_blank"で通常のウェブページを開くことは可能なので、「このページは別のアプリケーションで開かれます。」のタイプだとだめかも知れません。

https://havelog.ayumusato.com/develop/others/e519-maps_link_misc.html

にあるように

> http://maps.apple.comでURLつくっておけば「iOSではMapsアプリが開けるし、Androidでもよしなにできるよ」という何ともアップル様状態なようです。

な感じかと思いますが、Chromeだと https://community.filemaker.com/jp/s/question/0D50H00006h97VxSAI/url-ios 
にあるように

maps://maps.apple.com/?address=

じゃないと反応しないのかもしれません。。。