OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでPower BI Desktopを自動更新する

PowerBI便利ですよね。

一回作っておけば毎月の分析が自動でされる気持ちよさ。
自由にグラフ配置できて、求めるデータが一目で理解できる明確さ。
マウス操作だけで自分なりに分析を深めていけるフィルタやヒント機能。
直感的につなげられるテーブル間のリレーション。
様々なデータソースとの連携。
何しろこれで無料というんだからびっくりです。

自分も、数億件規模のデータを分析するのに使っています。
ヒント機能使って、その時間に何が起きていたか表示するの楽しいですよね。
ただ、一つ問題が。

更新がめんどくさい！！
データの前処理しているとはいえ、データ読み込んでくるの数十分はかかります。
ぱっと出したいときなんかはストレスです。PC重くなるし。
それに、スペック低いPCで更新しようものなら、メモリ不足で落ちます。
Power BI Desktopじゃなくて、無印のPower BIなら自動更新もできるそうですけど、有料になっちゃうし、アカウント管理とか大変。

ということで、今回PowerBI DeskTopを自動化するプログラムをPythonでつくりました。

# 環境・構成
Windows 10 Proのタスクスケジューラを使って、Pythonのプログラムを定期実行しています。
Pywinautoを使ってGUIでpbixファイルを開いて、「更新」ボタンをクリックしてから保存しています。
ちなみに、データソースはサーバー上のMySQLとつないで取得してきています。

# コード
``` auto_pbi.py
import os
import sys
import time

from pywinauto import Desktop, Application, keyboard

def main(workbook):
    exe = 'PBIDesktop.exe'

    # ファイルを開く
    os.system('start "" "{0}"'.format(workbook))
    app = Application(backend='uia').connect(path=exe)
    time.sleep(60)
    try:
        # Windowを指定
        win = app.window(title_re = '.*Power BI Desktop')
        win.set_focus()
        # ホーム＞更新をクリック
        win.ホーム.wait("visible")
        win.ホーム.click_input()
        win.更新.wait("visible")
        win.更新.click_input()
        win.キャンセル.wait_not("visible",timeout=6000)
        # 保存
        keyboard.send_keys("^s")
        time.sleep(120)
    except Exception as e:
        print(e)
    finally:
        app.kill()


if __name__ == '__main__':
    try:
        file_path = sys.argv[1]
    except (IndexError):
        print('ファイルを指定してください。')
        sys.exit()

    main(file_path)
```
上記のコードをauto_pbi.batで指定してタスクスケジューラで走らせています。

``` auto_pbi.bat
cd 指定フォルダ
python.exe auto_pbi.py レポート.pbix
exit
```
Pythonや.pyファイル、pbixファイルについては、絶対パスで書いておくことをお勧めします。
自分はフォルダ内にレポートとpyファイル入れてしまっているので、最初の行でフォルダ移動しています。


# 注意点
## タスクスケジューラの実行
自分はリモートPCでこのプログラムを実行しようとしましたが、うまくいきませんでした。
タスクスケジューラを自分で「実行」するとうまくいきますが、リモート接続を切ってトリガーで実行させようとするとうまくいかなくなります。
これは、リモートPCの場合、リモートデスクトップの接続が切れたときに、デスクトップ画面がロックされてしまうからです。
以下のようなエラーが出ます。

```
there is no active desktop required for moving mouse cursor!
```
この対策をするためには、リモートデスクトップを切った時にデスクトップ画面がロックアウトしないように設定する必要があります。
https://pywinauto.readthedocs.io/en/latest/remote_execution.html

自分は、リモートデスクトップを切るときに以下のコマンドを使うという方法をとりました。
\#80となっているところは環境に合わせて変えてください。
リモート先のPCでタスクマネージャー＞ユーザーと開き、各カラムの見出し部分を右クリックして「セッション」にチェックをつけると、リモートセッションIDが表示されます。
リモートデスクトップのセッションを切るときに以下のコマンドをコマンドプロンプトから入力してください。

```
TSCON RDP-Tcp#80 /dest:console
```

## スリープ処理
pbiを立ち上げてから少し待たないと、Windowが立ち上がってこないためエラーが出ました。
あと、意外と注意しないとなと思ったのは、Ctrl+Sで保存したあとのスリープ処理。
30秒くらいで保存処理完了できるかと思いましたが、できませんでした。
思っているより長めにとっておいたほうがよいかと思います。

## その他
更新したらファイルコピーして送るとか、エラー出たらメールはいるようにしておくとか、これをベースにしていただければ、毎日のビッグデータ更新みたいな面倒な処理が省けて、快適なPowerBIライフを送っていただけるんじゃないかと思います！
PythonのSQLiteで外部キー(Foreign Key)[備忘録]

#### PythonのSQLiteで外部キーを使っていきます
まずPersonテーブルを作ります。

```Python
db = "./exsample.db"
con = sqlite3.connect(db)
cur = con.cursor()
table = "Person" # テーブル名
sql = f"""create table {table}(
    id integer primary key autoincrement,
    name text,
    age integer,
)"""
cur.execute(sql) # SQL実行
self.con.commit() # 保存
```
`id`は`primary key`で主キーにし、`autoincrement`で自動で振り分けるようにしています。

外部テーブルを作ります。

```Python
table = "Memo" # テーブル名
sql = f"""create table {table}(
    id integer primary key autoincrement,
    title text,
    content text,
    writer_id integer,
    foreign key(writer_id) references Person(id)
)"""
cur.execute(sql) # SQL実行
self.con.commit() # 保存
```
`foreign key(writer_id) references Person(id)`に注目です。
ここで、`writer_id integer`でいったん`integer`の項目をつくり、その下で
`foreign key(<項目名>) references <繋ぐテーブル名>(<繋ぐテーブルの項目名>)、`とします。
【PHP】CSVを作成し、ZIPに圧縮してダウンロード

#はじめに
前回の記事[【PHP】Excelで文字化けしないCSVファイル作成](https://qiita.com/Tommy0221/items/83478c0bb2b97b21a913)の続き？というより最終的にやりたかったことを備忘録として記事にします。

**非同期通信で、DBからテーブルごとのCSVを作成し、ZIPに圧縮してダウンロードさせる！！！**

やっていきましょう！

#コード

```javascript:クライアント側　JS
var request = new XMLHttpRequest();
request.open('GET', '/getZip', true);
request.responseType = "blob";
request.onload = function (oEvent) {
    var blob = request.response;
    var objectURL = window.URL.createObjectURL(blob);
    // リンクを作成し、JavaScriptからクリック
    var link = document.createElement("a");
    document.body.appendChild(link);
    link.href = objectURL;
    link.download = 'ZIPファイル名';
    link.click();
    document.body.removeChild(link);
};
request.send(null);
```


```PHP:サーバ側　PHP
// ZipArchiveクラス初期化
$zip = new ZipArchive();
// Zipファイルパス
$zipFileNm = 'ZIPファイル名（拡張子付）';
$zipFilepath = 'ZIPファイルパス'.$zipFileNm;
// Zipファイルオープン
$result = $zip->open($zipFilepath, ZIPARCHIVE::CREATE);
if($result !== true){
  //ZIPファイル作成失敗時の処理
}

// CSV作成　前回記事関数
$csvFilePath = createCSV('CSVファイル名', 'データカラム', 'データ本体');
// CSVファイルをZIPに追加
$zip->addFile($csvFilePath, 'CSVファイル名');
// Zipファイルクローズ
$zip->close();

// HTTPヘッダを設定
mb_http_output( "pass" );
header("Pragma: public");
header('Content-Type: application/force-download;');
header('Content-Length: '.filesize($zipFilepath));
header("Content-Disposition: attachment; filename=$zipFileNm");
ob_end_clean();

// ファイル出力（ダウンロードさせる）
readfile($zipFilepath);

// Zipファイル削除
if(!unlink($zipFilepath)){
  //ZIPファイル削除失敗時の処理
}

// CSVファイルの削除
$delFileName = "CSVファイル保存パス/*.csv";
foreach(glob($delFileName) as $val){
  if(!unlink($val)){
    // CSVファイル削除失敗時の処理
  }
}
```
参考
[PHPでCSVダウンロード](https://qiita.com/A-Kira/items/f6f87a6f84da061ca2f9)
[PHPでファイルをZIPファイルに圧縮する方法【初心者向け】](https://techacademy.jp/magazine/19673)

#最後に
だらだら長いコードだと思います。
あと、これで本当に良いのかな～と疑問。処理は動くけども。

こうした方が良い等ありましたら、アドバイスください！！！
Pandas DataFrame に期待する列が存在するかどうかをチェックする

例えば以下のような「DataFrame を加工する関数」があったとする。

``` python
import pandas as pd

def preprocess(df: pd.DataFrame) -> pd.DataFrame:
    df["full_name"] = df["first_name"] + " " + df["last_name"]
    return df
```

この関数の引数の DataFrame には `first_name` と `last_name` という列が含まれることが期待されるが、これを関数のはじめでチェックしたいことがある。

これは set 型 [^set] の演算を使うと簡単に書ける。

[^set]: https://docs.python.org/ja/3/library/stdtypes.html#set

``` python
import pandas as pd

def preprocess(df: pd.DataFrame) -> pd.DataFrame:
    required_columns = {"first_name", "last_name"}
    if not required_columns <= set(df.columns):
        raise ValueError(f"missing columns: {required_columns - set(df.columns)}")
    df["full_name"] = df["first_name"] + " " + df["last_name"]
    return df
```

このように書いておくと、必要な列が抜けていた場合に ValueError を投げてくれる。

``` python
df = pd.DataFrame([{"first_name": "John", "age": 30}])  # 'last_name' 列が抜けている DataFrame
preprocess(df)  #=> ValueError: missing columns: {'last_name'}
```
numpy2次元配列を3次元Onehot表現

## やりたかったこと
* numpy2次元配列を3次元Onehot表現
* (Qiitaに初投稿😀)
* より良い書き方を知りたいです！詳しい方教えて下さい。

## 想定する場面
* 画像セグメンテーションであれば
 * 2次元配列は「正解ラベルの元画像」に相当
 * 3次元配列は「加工済の正解ラベル」に相当

## コード
```
import numpy as np

# クラス数
class_num = 4

# 各要素がクラスに該当する2次元の配列
arr_2d = np.array([[0, 1]
                  ,[2, 1]])

# 各層がクラスに対応する3次元の配列
np.identity(class_num)[arr_2d].transpose(2,0,1)
```

## まだやってないこと
* numpyだけでなくpytorchのTensor配列でも同様のことができそう
* 複数枚の処理
Electronはapplication/wasmが分からない

## 起こった事

Rustで書いたプログラムを`wasm-pack`を用いてビルドし、出力されたファイルをJS側から

```javascript
import wasm from "path/to/wasm/output/app_name_bg.js;
```
として読み込んでいた。

ブラウザ上では動いたがElectronでも同じやり方をすると`application/wasmっていうMIMEタイプは間違っている`とエラーを吐きwasmを読み込めなかった

## 結論

Rustで使用している`wasm-bindgen`と同じバージョンの`wasm-bindgen-cli`をインストールする。

```shell
$ cargo install -f --version 0.2.64 wasm-bindgen-cli  
```
ターゲットに`wasm32-unknown-unknown`を指定してビルド

```shell
$ cargo build --target wasm32-unknown-unknown --release
```
wasm-bindgenコマンドを用いてwasmを任意のディレクトリに出力

```shell
$ wasm-bindgen target/wasm32-unknown-unknown/release/app_name.wasm --out-dir path/to/wasm/output --target web
```

Electronの`index.html`内`header`タグ内に以下のコードを追加

```html
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'self'"/>
```
レンダープロセス側のJSで以下のように書く事でwasmを呼び出せる。

```javascript
import { MyClass, MyFunc, default} from 'path/to/wasm/output/app_name.js';
let my_class; // 他の部分でもクラスを利用したい場合
async function init() {
    await default('path/to/wasm/output/app_name_bg.wasm'); // defaultはRustのコードに関わらず読み込んで呼び出す
    my_class = new MyClass(); // RustでImpl/Structを公開していた場合
    MyFunc(); // Rustで関数を公開していた場合
}
init();
```

これでElectronでwasmを読み込めるようになった。
PDFにパスワードをかける

個人情報満載のPDFが見つかり、パスワードをかけておいた方がいいかなと思いたつ。Adobeのアクロバットを買えばいいのだろうけれど、そしてフリーのソフトもあるのだろうけれど、せっかくだからPyPDF2を使ってかけてみる。

```PDF_pw.py

import PyPDF2

src_pdf = PyPDF2.PdfFileReader('./**パスワードをかけたいPDF**.pdf')
pass_pdf = './**パスワードをかけた後の出力先**.pdf'
password = '**任意のPassword**'

dst_pdf = PyPDF2.PdfFileWriter()
dst_pdf.cloneReaderDocumentRoot(src_pdf)

d = {key: src_pdf.documentInfo[key] for key in src_pdf.documentInfo.keys()}
dst_pdf.addMetadata(d)

dst_pdf.encrypt(password)

with open(pass_pdf, 'wb') as f:
    dst_pdf.write(f)

```
生成までちょっと間がある印象。パスワードをかけたいPDFとパスワードをかけた後の出力先を同一にすると、上書きされる。でも、なんか失敗してPasswordもわかんないみたいな最悪の事態になるのは嫌だから、別にした方がいいと思う。
Linuxに ps の代替ツール procs をインストール(Mac・Windowsでも使える)

メモリやCPU使用率が見やすくなる
https://github.com/dalance/procs

![cap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/2a5732f8-d200-7021-116f-88d6125fb066.png)




## 1. インストール

```
$ sudo rpm -i https://github.com/dalance/procs/releases/download/v0.10.3/procs-0.10.3-1.x86_64.rpm
```


## 2. 設定

リンク先の設定を反映（https://github.com/dalance/procs/blob/master/config/large.toml）

```
$ mkdir -p ~/.config/procs/
$ vi ~/.config/procs/config.toml
```


## 3. 使用例

```
$ procs
$ procs --sortd cpu
$ procs --sortd rss
$ procs --sortd rss nginx
```
AIXによるコマンド実行ログ取得 -マイナーバージョン-

# AIXのコマンドログ取得
## AIX とは
AIXとは、IBMが提供している UNIX オペレーティングシステムです。

## コマンド実行履歴の取得
先程も言ったように、AIXは、UNIXですので、bsh, ksh などのシェルからコマンド実行した場合は、.sh_history に記録されます。個人で過去の実行履歴を再利用する分には、有効ですが、監査ログとして使うには、改ざん防止が出来ないので、そのままでは利用できません。

## 監査機能を使った実行履歴の取得方法
監査目的でコマンド実行履歴を取得するには、AIX の監査機能を使うことが出来ます。
一般的な使い方は、以下のマニュアルを参照ください。

[監査のセットアップ](https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/security/setting_up_auditing.html)


簡単な説明をすると、「PROC_Execute」というイベントを監査対象のユーザーに割り当てることで、ユーザーが実行したコマンドを監査ログとして保管してくれます。

## PROC_Execute イベントの注意点
「PROC_Execute」の名前から想像できる様に、EXEC システムコールが実行されたときに監査ログに記録します。
このため、ユーザーがシェルから実行したコマンドだけでは無く、シェルスクリプトの中で呼び出すコマンドまで記録されます。root ユーザーの PROC_Execute を監査対象にしてしまうと、デーモン（サービス）などもログの取得対象になるため、レコード数が増えてしまいます。
このため、指定するユーザーを制限したり、出力内容をフィルターする必要が出てきます。
また、bsh や ksh の内部コマンドは、EXEC されないため、監査ログには保管されません。

## コマンドの実行履歴の取得 -マイナーバージョン-

以下のマニュアルを見ると、 /etc/security/audit/objects ファイル設定では、ファイルの read/write だけでなく、 execute も設定できると言った記載があります。

[/etc/security/audit/objects ](
https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/filesreference/objects.html)

以下、抜粋
「An audit-event name can be up to 15 bytes long; longer names are rejected. Valid access modes are read (r), write (w), and execute (x) modes. For directories, search mode is substituted for execute mode. 」

しかし、前述のマニュアルの記載例には、execute mode での設定は見当たりません。
そこで、execute を設定する内容を以下に記載します。

Read, Write ときと同じように、/etc/security/audit/objects ファイルに対象となるコマンドファイルを記載します。

```ruby:/etc/security/audit/objects

/usr/bin/ps:
        x = "File_Execute"
```

このとき、mode のところを、r, w の代わりに、x を指定します。
また"File_Write" や、"File_Read" の代わりに "File_Execute" を新規に作成します。
"File_Execute"は、今回作成したものなので、/etc/security/audit/events ファイルにエントリーを追加します。


```ruby:/etc/security/audit/events

*       File Execute
        File_Execute = printf "%s"

```

objectsのエントリーは記録対象とするコマンドの数だけ登録する必要があります。
eventsファイルのエントリーは、一度だけです。

## 注意事項
この方法では、監査対象とするコマンド全てを登録する必要があります。
シェルスクリプトで、リストを生成することも出来ますが、重要度の高いコマンドに絞った方が良いでしょう。
[PHP]strtotime("- 1 month")はアカン[31日はテストが落ちる日]

# これはなに？

PHPでstrtotime("- 1 month")とかstrtotime("+ 1 month")とか書いちゃだめだよって話です。

# 今日は何の日でしょう？

今日は、弊社の自動テストが落ちた日です。
昨日は落ちなかったのに、いったいなぜ今日落ちてしまったのでしょう。

# なぜ落ちた？

それは今日が`31日`だからです。

テストコードに現在時刻を使ったコードがありました。
ただし、現在時刻から+1ヶ月したり-1ヶ月したりして、相対的な日付でテストをしているので、
普段は時刻が変わることによる問題は起こっていませんでした。

しかし、今日初めて問題が発覚しました。
現在時刻から前月の月を取得する計算が31日だけおかしかったのです。

## 前月の計算の仕方(NGケース)

```php
strtotime("- 1 month")
```

一見良さそうです。今から マイナス1ヶ月後の日付が取れそうです。

7/1なら6/1

7/20なら6/20

**7/31なら7/1**

```
(　ﾟдﾟ) ・・・
　
(つд⊂)ｺﾞｼｺﾞｼ
　
(；ﾟдﾟ) ・・・
　
(つд⊂)ｺﾞｼｺﾞｼｺﾞｼ
　　_, ._
（；ﾟ Дﾟ） …！？
```

0ヶ月前やん！



```php
strtotime("+ 1 month")
```
の場合でも問題が起こります。

8/31の1ヶ月後は
10/1になってしまします。
2ヶ月後ですね。

# 正しい書き方

```php
strtotime('first day of previous month');
```
```php
strtotime('first day of next month');
```

# 参考コード
## 間違った例
```php
date('Y-m-d H:i:s', strtotime('+ 1 Month', strtotime('2020/08/31 00:00:01')))
=> "2020-10-01 00:00:01"
```
```php
>>> date('Y-m-d H:i:s', strtotime('- 1 Month', strtotime('2020/07/31 00:00:01')))
=> "2020-07-01 00:00:01"
```

## 正しい例
```php
>>> date('Y-m-d H:i:s', strtotime('first day of previous month', strtotime('2020/07/31 00:00:01')))
=> "2020-06-01 00:00:01"
```
```php
>>>  date('Y-m-d H:i:s', strtotime('first day of next month', strtotime('2020/08/31 00:00:01')))
=> "2020-09-01 00:00:01"
```

# 参考


https://bugs.php.net/bug.php?id=44073
https://stackoverflow.com/questions/19727274/strtotime-bug-when-using-1-month-from-january
【Effective Javaを読む】　第３章　項目８　『equalsをオーバーライドする時は一般契約に従う』

#第３章について
第２章はオブジェクトの生成と消滅についてのエッセンスでした。
第３章は「Object」クラスについてのお話です。

##Objectクラスと一般契約
・Objectは具象クラスであるにもかかわらず主に拡張されるために設計されている
・finalでないメソッド（equals, hashCode, toString, clone, finalize）はすべてオーバーライドされるように設計されているので、明示的な一般契約(general contract)を持っている
・オーバーライドするクラスは一般契約に従わないと適切に動作しなくなる

#equalsをオーバーライドする時は一般契約に従う

##equalsメソッドをオーバーライドしてはならない場合
equalsメソッドをオーバーライドするのは簡単ですが、間違った方法でオーバーライドしてしまう場合が多々あるので、次の条件のどれかに当てはまる場合はオーバーライドしないほうがいい。

・クラスの個々のインスタンスが、本質的に一意である場合

・「論理的等価性(logical equality)」検査を、クラスが提供するかどうか関心がない場合

・スーパークラスが既にequalsをオーバーライドしており、スーパークラスの振る舞いがこのクラスに対して適切である場合

・クラスがprivateあるいはパッケージプライベートであり、そのequalsメソッドが決して呼び出されないことが確かである場合

##一般契約
以下がequalsメソッドの一般契約です。
これを守らないとプログラムが不規則に振る舞ったりクラッシュしたりする。

equalsメソッドの実装は同値関係(equivalence relation)を実装します。すなわち
・反射的(reflexive)：nullでない任意の参照値xに対して、x.equals(x)はtrueを返さなければならない
・対照的(symmetric)：nullでない任意の参照値xとyに対して、y.equals(x)がtrueを返す場合にのみ、x.equals(y)はtrueを返さなければならない
・推移的(transitive)：nullでない任意の参照値x,y,zに対して、もしx.equals(y)とy.equals(z)がtrueを返すならば、x.equals(z)はtrueを返さなければならない
・整合的(consistent)：nullでない任意の参照値xとyに対して、オブジェクトに対するequals比較に使用される情報が変更されなければ、x.equals(y)の複数回呼び出しは、終始一貫してtrueを返すか、終始一貫してfalseを返さなけらばならない

#続く
【Effective Javaを読む】　第３章　項目９　『equalsをオーバーライドする時は、常にhashCodeをオーバーライドする』
https://qiita.com/Natsukii/items/ac195b5542ba3348ed29
windowsでiverilog その60

#概要

windowsでiverilogやってみた。
モジュール間のハンドシェイクを考察してみた。

#モジュール間のハンドシェイクを考察。

##何が問題なのか。

速いモジュールと遅いモジュールでデータの取りこぼしが起きる。
速いモジュールが、１クロックでデータを出力し、遅いモジュールにスタートを掛けるが、次のクロックでデータを取りこぼす。

##対策は。

startとbusyを導入する。速いモジュールは、遅いモジュールのbusyを監視して、startを掛ける。

##具体的には。

速いモジュールはcpu、遅いモジュールはserialでイメージする。

以上。
lwc关联笔记(4)lightning-datatable使用内部类或者重新规整显示多个对象的数据

关于lightning-datatable如何显示复数个object的例子

首先需要明确的是，datatable的做法，无论是aura还是lwc，灵活性都很差。如果不是为了省劲，尽量还是用灵活度较高的table吧。

如何实现跨object的表示呢

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491095/e4390c8e-ae0a-ba3d-7db3-ce28711022fe.png)

~~~
<template>
    <lightning-card title="Showing Reference Fields Data in Lightning Datatable">
        <lightning-datatable columns={columns} 
                            data={data} 
                            key-field="id"
                            hide-checkbox-column="true"
                            show-row-number-column="true"></lightning-datatable>
    </lightning-card>
</template>
~~~




~~~js
import {LightningElement, track, wire} from 'lwc';

// importing Apex Class
import getOppdata from '@salesforce/apex/LWCExampleController.retriveOpportunities';

// Datatable Columns
const columns = [
    {
        label: 'Opportunity Name',
        fieldName: 'Name',
        type: 'text',
    }, {
        label: 'Account Name',
        fieldName: 'AccountName',
        type: 'text'
    }, {
        label: 'Account Owner',
        fieldName: 'AccountOwner',
        type: 'text'
    }, {
//这里使用的也是新data数组里面的属性，只需要两步即可，这是第一
        label: 'Opportunity Owner',
        fieldName: 'OpportunityOwner',
        type: 'text'
    }, {
        label: 'CreatedDate',
        fieldName: 'CreatedDate',
        type: 'date'
    }
];


export default class ReferenceDataInLwcDatatable extends LightningElement {
    @track data = [];
    @track columns = columns;

    @wire(getOppdata)
    opp({error, data}) {
        if(data) {

            let currentData = [];

            //在这里对data进行循环，并且赋给一个新的数组，这是第二步
            data.forEach((row) => {

                /* 
                * Creating the an empty object
                * To reslove "TypeError: 'set' on proxy: trap returned falsish for property"
                */

                let rowData = {};

                rowData.Name = row.Name;
                rowData.CreatedDate = row.CreatedDate;

                // Account related data
                if (row.Account) {
                    rowData.AccountName = row.Account.Name;
                    rowData.AccountOwner = row.Account.Owner.Name;
                }

                // Owner releated data
                if (row.Owner) {
                    rowData.OpportunityOwner = row.Owner.Name;
                }

                currentData.push(rowData);
            });

            this.data = currentData;
        }
        else if(error) {
            window.console.log(error);
        }
    }
}


~~~



~~~
public inherited sharing class LWCExampleController {    
    @AuraEnabled(cacheable=true)
    public static list<Opportunity> retriveOpportunities() {
        return [SELECT Id, Name, Account.Name, Account.owner.name, Owner.Name, CreatedDate FROM Opportunity LIMIT 10];
    }
}
~~~
【Effective Javaを読む】　第２章　項目７　『ファイナライザを避ける』

#ファイナライザを避ける
ファイナライザ(finalizer)は、予測不可能で、たいていは危険であり、一般には必要ない。有効な使用方法は多少あるけれども基本的に使わないほうがいい、というお話。

##用語集
###ファイナライザ
finalize()メソッドのこと。
finalize()メソッドは、Java言語におけるすべてのクラスの継承元であるjava.lang.Object クラスに定義されている。
すなわち、すべてのクラスは finalize()メソッドを持つ。
ガベージコレクタが走ったタイミングで呼ばれるメソッド。

###ネイティブピア(native peer)
通常のオブジェクトがネイティブメソッドを通して委譲を行うネイティブオブジェクト。
通常のオブジェクトではないので、ガベージコレクタは感知せず通常のオブジェクトが回収される時にネイティブピアを回収できない。

###ファイナライザ連鎖(finalizer chaining)
クラスがファイナライザを持ちサブクラスがそれをオーバーライドしているならば、そのサブクラスのファイナライザはスーパークラスのファイナライザを手作業で呼び出さなければならない（例２）

###ファイナライザガーディアン(finalizer guardian)
サブクラスの実装者がスーパークラスのファイナライザをオーバーライドして、スーパークラスのファイナライザを呼び出すのを忘れたとしたら、スーパークラスのファイナライザは決して呼ばれることがない。このような不注意あるいは悪意のあるサブクラスから防御するためにファイナライザガーディアンが有効である（例３）

##サンプルコード
```java:例１

//終了メソッドの実行を保証するtry-finallyブロック
Foo foo = new Foo(...);
try {
    //fooで行わなければならない処理を行う
    ...
} finally {
    foo.terminate(); //明示的終了メソッド
}
```

```java:例２
//手作業によるファイナライザ連鎖
@Override protected void finalize() throws Throwable {
    try {
        ... //サブクラスのファイナライザ処理
    } finally {
        super.finalize();
    }
}
```

```java:例３
//ファイナライザガーディアンのイデオム
public class Foo {
    //このオブジェクトの唯一の目的は、外側のFooオブジェクトのファイナライズを行うこと
    private final Object finalizerGuardian = new Object() {
        @Override protected void finalize() throws Throwable {
            ... //外側のFooオブジェクトをファイナライズする
        }
    };
    ... // 残りは省略
}
```

##ファイナライザの２つの欠点
###１つ目　即座にファイナライザが実行される保証がない
・ファイナライザが実行されるまでの時間はどれだけの長さにもなりえるので、時間的に制約のあることをファイナライザで行うべきではない
・重要な永続性のある状態を更新するのにファイナライザに決して頼るべきではない

###２つ目　ファイナライザの使用には深刻なパフォーマンスのペナルティがある
・ファイナライザを持つオブジェクトの生成と解放は、そうでないオブジェクトと比べて約４３０倍遅い

##ファイナライザを書く代わりにどのような実装をすべきか？
・明示的終了メソッド(explicit termination method)を提供する（例１）
・終了を保証するために明示的終了メソッドはたいていtry-finally構文と一緒に使用される

##ファイナライザが有効な場合
###１つ目　明示的終了メソッドの呼び出しをオブジェクトの所有者が忘れた場合の「安全ネット」として振舞う場合

###２つ目　ネイティブピア(native peer)を回収する場合

#続く
【Effective Javaを読む】　第３章　項目８　『equalsをオーバーライドする時は一般契約に従う』
https://qiita.com/Natsukii/items/bcc5846dbfa69bfda9b0
【Terrafrom】Moduleに変数を渡す際に Error: Unsupported argument が発生する

# はじめに

Terraformを勉強中にハマった箇所があり、調べても中々出てこなかったので共有します。

# 結論
変数を渡そうとしているModuleのディレクトリ(本記事では`base`ディレクトリ)内に、`variables.tf`を作成し、渡そうとしている変数を定義しましょう。

```
# base/variables.tf

variable "vpc_id" {}
variable "region" {}
```

# 状況

発生した状況は以下のような形です。
Moduleを使用しており、ルートモジュールから子モジュールへ変数を渡そうとしています。


```terminal
# ディレクトリ構成

❯ tree .
.
├── base
│   └── vpc.tf
├── main.tf
└── variables.tf

```

```terminal
# main.tf

variable "vpc_id" {}
variable "region" {}

provider "aws" {
  profile = "default"
  region  = var.region
}

module "base" {
  source = "./base"

  vpc_id = var.vpc_id
  region = var.region
}
```

```terminal
# variables.tf

variable "vpc_id" { default = "xxxxxxxxxxxxxx" }
variable "region" { default = "ap-northeast-1" }
```

```terminal
# base/vpc.tf

data "aws_vpc" "selected" {
  id = "${var.vpc_id}"
}

resource "aws_subnet" "example" {
  vpc_id            = "${data.aws_vpc.selected.id}"
  availability_zone = "${var.region}a"
  cidr_block        = "${cidrsubnet(data.aws_vpc.selected.cidr_block, 4, 1)}"
}
```

# エラー内容

この状況で`terraform apply`を実行するとエラーが発生します。

```terminal
❯ terraform apply

Error: Unsupported argument

  on main.tf line 12, in module "base":
  12:   vpc_id = var.vpc_id

An argument named "vpc_id" is not expected here.


Error: Unsupported argument

  on main.tf line 13, in module "base":
  13:   region  = var.region

An argument named "region" is not expected here.
```

# 原因

子モジュール内で変数を定義していないことが原因です。
TerraformのMuduleは、あるディレクトリ内の設定ファイル（`.tf`ファイル）の集合体です。
モジュールで使用する変数は、モジュール毎に定義してあげる必要があります。
そのため、変数を渡そうとしているModuleのディレクトリ内で、変数を定義する必要があります。

個人的には、Moduleブロック内で変数を渡すだけで、子モジュールで使用可能になると勘違いしていました。

[Terraform Modules - 公式ドキュメント](https://learn.hashicorp.com/terraform/modules/modules-overview)

# 最後に

~~公式ドキュメントは一通り読んでいましたが、モジュール毎に変数の定義が必要とは書いていなかったような気が、、、。（見落としていたのかもしれません）~~

>見落としていました！
>@raki さんコメントで教えて頂きありがとうございます！
>[Terraform Creating Modules - 公式ドキュメント](https://www.terraform.io/docs/modules/index.html)

最終的にはStackOverflowの回答からヒントを得て解決しました。
何方かの助けになれば幸いです。
systemctl list-unit-filesのタイプ指定

# systemctl覚書
はい皆さんこんにちは

筆者は今までsystemctlにあまり触っておらず、
言うてserviceｺﾏﾝﾄﾞと同じやろと思っていたおじさんが改心したお話です。


# 前提

まずsystemctlもといsystemdとは何か。
CentOS7またはRHEL7から実装されている自動起動デーモン。

それ以前は何だったかと言うとinitdだったわけです。
/etc/init.d/... に起動停止スクリプトが置かれていました。
~~**この時代に戻りたい**~~
そしてこれを呼び出すｺﾏﾝﾄﾞがserviceなわけです。

systemdは
/usr/lib/systemd/...  に設定ファイルが置かれています。
スクリプトではなくて設定ファイルですね。
そしてこれを呼び出すｺﾏﾝﾄﾞがsystemctlなわけです。


##起
ここまでは何となく知識としてあったのですが、
ある時人の作った設計書のサービス欄を見て不思議な情報が書いてありました。

|UNIT FILE|STATE|
|---|---|---|
|dbus.socket|static|

これは一体なにかと。


##承

早速調べるために次のｺﾏﾝﾄﾞを打ちました。
systemctl list-unit-files -t service --no-pager

しかしこのｺﾏﾝﾄﾞでは結果は含まれませんでした。

**ここで初めてmanを見ました。ええ初めてですよ。**

要点をまとめると、
-tは、 service　以外に　socketが選べる。（これ以外にもmountとか選べます）

**ユニットをリストする時に、引数の１つがユニットタイプである時は、そのユニットタイプだけを表示する。そうでないときは、すべてのユニットタイプを表示する。**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532987/18e64097-1b39-c416-cdc4-f62702c5141d.png" width=50%>

##転
というわけで次のｺﾏﾝﾄﾞの結果を見ると、「dbus.socket」が見れました。
systemctl list-unit-files

この場合は全てのユニットタイプが表示されています。
ちなみにsocketのファイルでは待ち受けポート番号の設定も出来ます。
~~**なんでおじさんはスグにちなんじゃうのか**~~

では何故この情報が設計書に書かれていたのかと言うと、
恐らく「chkconfig --list」の結果表示される、

**systemd サービスを一覧表示する場合は 'systemctl list-unit-files' を使用します。**
をそのまま打ったんじゃないかな。。。という結論になりました。


##結
設計書は修正したのですが、おじさんは一つ賢くなれたなと。
今まで疎遠だったsystemctlと少しだけ仲良くなれた気がします。

まぁ正直自分が設計書を作ったとしても全く同じ道を歩んでいたと思うと
ここで気づけて良かったなと改心しました。





**ありがとうございました。**
nodebrewで入れたnodeが存在するのにno such file or directoryになる問題

**【注意】これを読んでも解決しません**

# 環境
- Raspberry Pi 4
- Ubuntu Mate 64bit
- nodebrew 1.0.1
    - node v12.18.3
  
# 症状
nodeコマンドが実行できない

```shell
$ node -v
-bash: /home/user/.nodebrew/current/bin/node: No such file or directory
```

```shell
$ ls -la /home/user/.nodebrew/current/bin/node
-rwxr-xr-x 1 user user 40769188  7月 31 14:06 /home/user/.nodebrew/current/bin/node
```

あるじゃないか！！！

…存在するファイルの no such file or directory は、どうやら32bitに対応していない64bit OSで32bitのバイナリを実行しようとしたときに出るらしい？

# 諦め
たぶん
「[Can we update the $arch for aarch64 to have capability to choose arm64?](https://github.com/hokaccha/nodebrew/issues/71)」
このissueが原因なのですが、PRも放置されマージされそうにないので、諦めて他の方法で入れようと思います
Jupyter notebookの使い方[超基礎]

#Jupyter notebookの超基礎
Jupyter notebookの基本的な説明になっています。
非常にざっくりとした使い方になっているので、内容は初めて使う方向けです。
したがって、特に高度なことは書いていません。
ご注意ください。

#Jupyter  notebook起動直後の画面

##概観
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/2470273b-9748-6c0b-1d56-90960a220336.png)

1. Upload : 新しいファイルをここに、アップロードできる。
2. New : ファイル（jupyter notebook形式など）やフォルダを作成する。
3. 更新 : このディレクトリ（フォルダ）中を更新する
4. ファイル名 : このファイル名をクリックするとjupyter notebook形式で開ける
5. □ : ☑︎を入れるとファイルを選択できる。削除・複製・編集などが、その後選択できる。
##ファイルの作成
Newを押すと以下のような表示が出るので、Python3をクリックするとJupyter Notebook形式のファイルを作成できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/f5e60ab5-4e3b-7a67-7a60-afbd8d4d32ed.png)

##ファイルの編集・削除など
☑︎を入れるとファイルを選択できる。その後以下のような表示がされて、複製・削除・編集などが出来る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/d8cf7b90-d983-5bf4-f16b-f031eac625e9.png)


#Jupyter notebookでのプログラム実行
##起動直後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/0850296b-f37e-0607-6b43-cd5ac655a1f6.png)
起動直後は、上のような状態になっている。

##セルに入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/1f1f61c6-de14-1dcd-f13c-0be4d0244560.png)
In []:
となっている横の部分（セル）にプログラムを入力することができる。

##プログラムの実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/fb1661bd-4487-b18f-19a3-dccce4be62a7.png)
実行は、上の "Run"をクリックするか、Shift + Enterで実行ができる。
そして、新たなセルが作られる（次のセルがすでにある時は、新たにセルは作られません）


#Jupyter Notebookのツールバー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285972/220bfdec-6eb9-1773-740e-180053b51235.png)


1. 保存：保存を行う。Ctrl + sでも保存可能
2. 新たにセルを追加できる。選択しているセルの下に追加される
3. 選択しているセルを削除する。
4. 選択しているセルをコピーできる
5. コピーしたセルを貼り付ける
6. 選択しているセルを一つ下に移動させる
7. 選択しているセルを一つ上に移動させる
8. セルを実行する。Shift + Enterでも可能。
9. 実行しているセルコードを停止させる
10. セルをリセットさせる。保存されていた変数など全てリセットされる
11. 全てのセルを初めから実行し直す
12. 選択しているセルに対して、コードか、コメントか、などを選択する事が出来る。
13. Jupyter notebookのコマンドを調べられる。便利なものがいくつもあります。

#最後に
このページでは、初歩的な使い方しか説明していないので、もっと便利に使いたい方・インストール方法から知りたい方がいれば、以下のサイトなどを参考にしてください。

おすすめの参考サイト
Jupyter notebook ショートカット解説：
https://qiita.com/forusufia/items/bea3f6fd6160cd2f5843

Python初心者向けぜひ覚えておきたいJupyter Notebookのショートカットキーまとめ：
https://tonari-it.com/python-jupyter-notebook-shortcut-key/

Jupyter Notebookのインストールから解説：
https://techacademy.jp/magazine/17430
Typescriptを勉強しよう①～コンパイルしよう

#Typescriptとは
TypescriptとはMicrosoft社が開発(2012年公開)したJavascriptの進化版言語である。
JavaScriptの欠点を補うために作られた言語で、Webアプリケーション開発、大規模開発での注目が高まっている。
Typescriptで書かれたコードはJavascriptにコンパイル(変換)され、コンパイルされたJavascriptが動作する仕組みである。

#なぜTypescriptを使うのか

- ####  JavaScriptと同じ環境で動かすことが可能
Typescriptはコンパイルし、JavaScriptに変換できるので、JavaScriptが動かせる環境なら、TypeScriptは動かせる。
そのため、開発環境のハードルは低くい。

- #### 型を宣言するためエラーを未然に防げる
Typescriptは静的型システムである。
型が指定できると、変数に違った型のデータが入り、プログラムが動作しないことがある。この変数にはこの型のデータが入ると、その変数に入るデータを予測しやすくなる。
また、Editorによっては型が違うとエラー表示されるため、開発効率が上がる。

- #### TypescriptはES5にコンパイルされる。
Javascriptは毎年アップデートされているため、ES6ではブラウザで認識されず表示されないことがあります。ES5（2009年）では基本的にどのブラウザでも認識される。なので、Typescriptで書いたコードは基本どのブラウザでも表示される。

**＊補足＊**
####静的型システム
Typescriptがコンパイルされる時に、型がチェックされる。変数の値がNumberなのか、Stringなのかそれ以外なのかすべてチェックされる。これが静的型システムがである。
型が違う場合(本来StringではないといけないところがNumberになっている)エラーが出力される。




#開発環境を整えましょう
###手順
1. ターミナルを開く　＊私はWindowsに内蔵されているCMDを使用した
2. Nodeがインストールされているか確認＊node -vを実行すると確認できる
![スクリーンショット (213).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/d0db4ab2-03ae-8818-8741-5acb05d8d1ca.png)
**→インストールされていない場合**　[Nodeダウンロード](https://nodejs.org/ja/download/)

3. ターミナル上で　**npm install -g typescript**　を実行し、Typescriptのインストールする
4. Editarを開く＊Typescriptのサポートが内蔵されている[Vscode]( https://azure.microsoft.com/ja-jp/products/visual-studio-code/)がオススメ
5. ファイルを作製（拡張子はts）
6. Typescriptを記述する。このように**: string**型を指定する
**let greeting: string = 'こんにちは';**
**console.log(greeting);**
7. Typescriptをコンパイルする
Editor内のターミナルを開く、Vscodeならメニューバーのターミナルの新しいターミナルを選択する
8. ターミナル上で　**tsc ファイル名**　を実行

##実行前
実行前のindex.ts
![スクリーンショット (219).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/2d4f7002-99a7-3bc4-d33e-ba3d0bd0d021.png)

##実行後
実行後はindex.jsが生成されました。
![スクリーンショット (222).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/bf9e962f-1a21-6741-4ead-ed8860ac79fd.png)


#問題発生
![スクリーンショット (223).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/39d9dc9a-d735-e036-6ff4-b9ab37846658.png)
**tsc : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\user\AppData\Roaming\npm\tsc.ps1 を読み込むことができません。
詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください**
###原因　 
実行ポリシーが初期値(Restricted)なので、制限を解除する必要がある。

#解決方法
###手順
1. スタートからWindows PowerShellを開く
2. PowerShell上で**PowerShell Get-ExecutionPolicy**を実行すると、現在の設定を確認できる
恐らく、Restrictedとなっているはず...確認出来たら
3. **Set-ExecutionPolicy RemoteSigned**を実行すると、実行ポリシーの変更が表示される
4. 実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
###Yを入力する
5. 再度、PowerShell Get-ExecutionPolicy　で設定を確認すると**RemoteSigned**に変更されています

![スクリーンショット (225).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/78050fc7-4634-d959-845d-900740a9cae1.png)
macOS Catalinaへのアップデート通知・バッジを消す方法

macOS Mojaveが至高だと思っている私
アップデートしたくないけどSystem Preferencesにバッジがつくのもイヤだ．．．というとき

terminalで以下を入力

Catalinaへの更新を無視

```
sudo /usr/sbin/softwareupdate --ignore "macOS Catalina"
```

バッジを消す

```
defaults write com.apple.systempreferences AttentionPrefBundleIDs -dict　com.apple.preferences.softwareupdate 0
```

最後にDockをkillする

```
killall Dock
```

完了．


やっぱmacOS Catalinaにしたいときは，

```
sudo softwareupdate --reset-ignored
```
PostgreSQLを再起動するとシーケンスの値が33増える謎

ある日アプリケーションのDEBUGログを眺めていると、レコードのidカラムの値が実際のレコード数よりも極端に大きくなっていることに気付きました。このカラムの値は、シーケンスを使って採番しているので、1つずつ増えていくことが期待です。「まさかバグか？」と焦りましたが、リソース節約のため毎晩DBを停止していることが原因でした。

### 再現確認

手っ取り早く PostgreSQL 12.3 の [Docker公式イメージ](https://hub.docker.com/_/postgres) を使って検証してみます。

1. PostgreSQL を起動する

    ```shell-session
    $ docker run --name testdb -e POSTGRES_PASSWORD=mysecretpassword -d postgres:12.3
    ```

1. psql で接続する

    ```shell-session
    $ docker exec -it testdb psql -U postgres
    psql (12.3 (Debian 12.3-1.pgdg100+1))
    Type "help" for help.

    postgres=# 
    ```

1. シーケンスを作成して、値を取得する

    ```shell
    postgres=# create sequence myseq;
    CREATE SEQUENCE
    postgres=# select nextval('myseq');
     nextval
    ---------
           1
    (1 row)
    ```

1. DBを再起動する

    ```shell-session
    $ docker restart testdb
    ```

1. シーケンスの値を再び取得する → **2じゃない！** :scream: 

    ```shell
    postgres=# select nextval('myseq');
     nextval
    ---------
          34
    (1 row)
    ```

[Sequence Caching: Oracle vs. PostgreSQL](https://seiler.us/2018-10-02-sequence-caching-oracle-vs-postgresql/) によると、再起動したときに 32（固定サイズ）+ 1（シーケンスのキャッシュサイズ。デフォルト値から変えている場合はさらに大きくなる）だけ番号が進んでしまうようです。


### 補足

参考ページを見てみると「4. DBを再起動する」でDBをきちんと停止していないのがまずそうです。DBを安全に停止する手順でやり直してみます。

3. シーケンスを作成して、値を取得する

    ```shell
    postgres=# create sequence myseq;
    CREATE SEQUENCE
    postgres=# select nextval('myseq');
     nextval
    ---------
           1
    (1 row)
    ```

4. DBを再起動する

    ```shell-session
    $ docker exec -it testdb su postgres -c 'pg_ctl stop -m fast'
    
    waiting for server to shut down....
    $ docker start testdb
    ```

1. シーケンスの値を再び取得する

    ```shell
    postgres=# select nextval('myseq');
     nextval
    ---------
           2
    (1 row)
    ```

今度は期待通り 2 になりました。DBを無理やり停止するなということですね。

### 補足2

なお、今回問題が起きた実際の環境では、PostgreSQL ではなく [Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-cluster-stop-start.html) を使っていて、AWS CLIを使って停止させていました。無理やり停止させているつもりはないのですが、なぜ…

```shell
$ aws rds stop-db-cluster --db-cluster-identifier mydbcluster
```

### まとめ

シーケンスを使ってカラムの値を採番していると、ときどき欠番が発生することがあります。トランザクションがロールバックされた場合に欠番が発生することは理解していましたが、DBを停止した場合にも欠番が（32も！）発生することは知りませんでした。勉強になりました。

ただ、Aurora の挙動については情報源を見つけられず、Aurora を停止したときにもシーケンスが飛ぶのが期待なのかは分からないままでした。

### 参考

* [Sequence Caching: Oracle vs. PostgreSQL](https://seiler.us/2018-10-02-sequence-caching-oracle-vs-postgresql/) 
* [postgresql sequence jump 30 or 33 number with cache equals 1 - Stack Overflow](https://stackoverflow.com/questions/38450394/postgresql-sequence-jump-30-or-33-number-with-cache-equals-1)
NoMethodError: undefined method `paginate' for を解決する (Railsチュートリアル 10章)

#発生しているエラー

Railsチュートリアル10章　10.3.3 ページネーション

```:Gemfile
gem 'will_paginate',           '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'
```

```
$ bundle install
```
そしてチュートリアルの指示通りにコードを追記し、

```
$ rails test
```
を実行すると、

```
Error:
UsersIndexTest#test_index_including_pagination:
NoMethodError: undefined method `paginate' for #<Class:0x00007fb0253e5c60>
    app/controllers/users_controller.rb:6:in `index'
    test/integration/users_index_test.rb:14:in `block in <class:UsersIndexTest>'
```

というエラーが発生する。

#対処法
```
$ spring stop
```
これを実行すると解決する。

参考：[RAILS_ENV=test時のみ、paginateメソッドがundefinedになる
](https://teratail.com/questions/139648)


#springとは

>Spring は Rails アプリケーションの preloader（プリローダー）の gem です。（pre + load = 前もってロードしておく）

>参考：[RailsでSpringを導入して開発効率を上げる](https://easyramble.com/install-spring-into-rails.html)


今回はロードを勝手にしてくれるspringによる影響でエラーが発生していたようですね。
詳しく説明できる方は、コメントで補足していただけると幸いです。

---

役に立ったら是非LGTMボタンをポチッと押していただけると嬉しいです。
一緒に Rails学習 頑張りましょう！:raised_hand_tone1:
macOSのメニューバーとDockのみダークモードにする方法

macOS Sierraでいう「メニューバーとDockだけ暗くする」をmacOS Mojaveでも実現したい．

ライトモードの状態で，

```
defaults write -g NSRequiresAquaSystemAppearance -bool Yes
```
再ログインで完了．

戻すときは，

```
defaults delete -g NSRequiresAquaSystemAppearance
```
Mutagenチートシート

　SSH経由、Dockerホスト/コンテナ間など様々な環境同士でファイルを同期できるツール「[Mutagen](https://mutagen.io/)」の（主に自分用の）チートシートです。
Mutagenの使い方を学びながら、少しずつ足していきます。

## 1. インストール/デーモン

| コマンド | 意味 |
|:---|:---|
| `brew install mutagen-io/mutagen/mutagen` | Homebrew（macOS）でのインストール |
| `mutagen daemon start` | デーモンの起動 |
| `mutagen daemon stop` | デーモンの停止 |

```text
$ mutagen daemon help
Control the lifecycle of the Mutagen daemon

Usage:
  mutagen daemon [flags]
  mutagen daemon [command]

Available Commands:
  start       Start the Mutagen daemon if it's not already running
  stop        Stop the Mutagen daemon if it's running
  register    Register the Mutagen daemon to start automatically on login [Experimental]
  unregister  Unregister automatic Mutagen daemon start-up [Experimental]

Flags:
  -h, --help   Show help information

Use "mutagen daemon [command] --help" for more information about a command.
```

## 2. ファイル同期

| コマンド | 意味 |
|:---|:---|
| `mutagen sync help` | 同期セッションについてのヘルプの表示 |
| `mutagen sync create <同期元> <同期先>` | 同期セッションの作成 |
| `mutagen sync create ~/foo user@host:bar` | 同期セッションの作成（SSH接続の例） |
| `mutagen sync create --name <セッション名> ...` | 同期セッションのセッション名の指定 |
| `mutagen sync list` | 同期セッションの一覧表示 |
| `mutagen sync monitor <セッション名>` | 同期セッションのモニタリング（状況確認） |
| `mutagen sync pause <セッション名>` | 同期セッションの一時停止 |
| `mutagen sync resume <セッション名>` | 同期セッションの再開 |
| `mutagen sync terminate <セッション名>` | 同期セッションの停止と削除 |

```text
$ mutagen sync help
Create and manage synchronization sessions

Usage:
  mutagen sync [flags]
  mutagen sync [command]

Available Commands:
  create      Create and start a new synchronization session
  list        List existing synchronization sessions and their statuses
  monitor     Show a dynamic status display for a single session
  flush       Force a synchronization cycle
  pause       Pause a synchronization session
  resume      Resume a paused or disconnected synchronization session
  reset       Reset synchronization session history
  terminate   Permanently terminate a synchronization session

Flags:
  -h, --help   Show help information

Use "mutagen sync [command] --help" for more information about a command.
```

## 3. その他

| コマンド | 意味 |
|:---|:---|
| `mutagen help` | ヘルプの表示 |
| `mutagen version` | バージョン番号の表示 |

```text
$ mutagen version
0.11.5

$ mutagen help
Mutagen is a remote development tool built on high-performance synchronization

Usage:
  mutagen [flags]
  mutagen [command]

Available Commands:
  sync        Create and manage synchronization sessions
  forward     Create and manage forwarding sessions [Experimental]
  project     Orchestrate sessions for a project [Experimental]
  tunnel      Create and manage tunnels [Experimental]
  login       Log in to mutagen.io
  logout      Log out from mutagen.io
  daemon      Control the lifecycle of the Mutagen daemon
  version     Show version information
  legal       Show legal information
  help        Help about any command

Flags:
  -h, --help   Show help information

Use "mutagen [command] --help" for more information about a command.
```
JavaScript（jQuery）で画像をリサイズする方法(JS以外でも可)

#画像をリサイズするJS以外でも使用可

画像をクリックしたら画像の縦横比を維持した状態で指定のサイズに画像をリサイズする


```js

$('img')on.('click', function(){
  //画像のsrcを取得
  let src = $(this).attr('src');

  let width = 400;//任意の数値
  let height = 400;//任意の数値

  //元の画像サイズ
  let originalWidth = $(this).width();
  let originalHeight = $(this).height();

  //割合計算(小数点が出る場合はコンソールで注意が出る場合も。その場合はMath.ceil()などを使用して切り上げる)
  let rate = originalWidth / originalHeight;
  height = (width / rate);
  if(rate < 1){
    height = width;
    width = width * rate;
  }
  //リサイズした画像をwidth、heightともに追加
  $('body').append(`<div><img src="${src}" width="${width}" height="${height}"></div>`);
  
});

```
ASP.NET CoreでIEを除外する（除外メッセージのページへリダイレクト）

#経緯
　今まで、IEをChromeのように処理させることを考えていたのですが、EdgeもChromiumベースになり使えるようになってきたみたいなので、そろそろIEを除外するシステムもいいかなーと思って除外することにしてみました。
　でも、サクッと処理が検索できなかったので調べてやってみたことを書いておきます。

#実装

##除外メッセージのページを作成
　wwwrootの直下に「NoSuportIE.html」を作成します。
　今回はテキストのみで以下のように作成しました。

```html:NoSuportIE.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    このシステムはIEでは使用できません。<br />
    Edge, Chrome, Firefoxなど他のブラウザをご利用ください。
</body>
</html>
```

##ブラウザを判定して「NoSuportIE.html」にリダイレクトさせる。
　ASP.NET Coreのパイプラインに、ブラウザを判定して「NoSuportIE.html」にリダイレクトさせるミドルウェアを登録します。
　Startup.csの「Configure」メソッドで「app.UseStaticFiles()」の下に処理を追記します。

```C#:Startup.cs
...（省略）

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...（省略）

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            // この部分を追加
            app.Use(async (context, next) =>
            {
                var userAgent = context.Request.Headers["User-Agent"];
                string uaString = Convert.ToString(userAgent[0]);
                if (uaString.Contains("MSIE") || uaString.Contains("Trident/"))
                {
                    context.Response.Redirect("/NoSuportIE.html");
                    return;
                }
                else
                {
                    await next();
                }
            });

            app.UseRouting();

            ...（省略）
        }
```

「app.UseStaticFiles()」から「app.UseEndpoints()」までの間であればどこでも動作します。
　「app.UseStaticFiles()」の前に入れると、静的ページがサポートされていないのでシステムエラーになります。「app.UseEndpoints()」の後だとそもそも処理されません。まあ、ソースのように「app.UseStaticFiles()」の直下が余計な処理もせずに済むのでいいと思います。

　ブラウザの判定は「User-Agent」に「MSIE」か「Trident/」が入っているかで行っています。これで大丈夫だと思いますが、おかしかったらここでブレークして文字列を調べて条件を変えて下さい。

　以上、ちょっと試したので書いておきました。
【Effective Javaを読む】　第２章　項目６　『廃れたオブジェクト参照を取り除く』

#廃れたオブジェクト参照を取り除く
C言語のようにメモリ管理を手動でする言語からすると、ガベージコレクタは魔法のようなものに見えるかもしれない。
しかしそれでもメモリリークを引き起こす原因は存在するから注意しようねって話。

##サンプルコード

```java:例１
//"メモリリーク"を発見できますか？
public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e
    }

    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }

    /**
     * 配列を大きくする必要があるごとに要領をだいたい倍にして、
     * 最低もう一つの要素分の要領を確保する。
     */ 
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Array.copyOf(elements, 2 * size + 1);
    }
}
```

```java:例２
public Object pop() {
    if (size==0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; //廃れた参照を取り除く
    return result;
}
```

##メモリリークを引き起こす３つの原因

###１つ目　廃れた参照

例１は一見問題ないように見えますが廃れた参照を保持しています。
例２のようにいらなくなった参照にはnullを設定してあげることでメモリリークを防ぐことができます。

ですが、全ての使い終わったプログラムに対して過度にnullを設定する必要はありません。
Stackクラスは独自のメモリ管理をしています。
そのようなクラスのどの参照が不要なのか、ガベージコレクタは知ることができません。
nullを手作業で設定することによってガベージコレクタに無効な部分を効果的に教えてあげることができます。

###２つ目　キャッシュ

オブジェクト参照をいったんキャッシュへ入れてしまうと、オブジェクト参照がそこにあることを忘れがちですし、そのオブジェクト参照の意味がなくなったかなり後でもキャッシュに残したままにしがちです。キャッシュの外にあるエントリーのキーへの参照が存在するかぎりそのエントリーに意味があるキャッシュを実装するのであれば、そのキャッシュをWeakHashMapで表現するのが良い。
　WeakHashMap：エントリーが廃れてしまうと自動的に取り除かれる


###３つ目　リスナーやコールバック

明示的に登録を解除しないAPIを実装すると、何らかの処理を行わなければコールバックが蓄積されてしまいます。迅速にコールバックがガベージコレクトされることを保証する最善の方法は、それらに対する弱い参照（weak reference)だけを保存することです。

#続く
【Effective Javaを読む】　第２章　項目７　『ファイナライザを避ける』
https://qiita.com/Natsukii/items/785ae41361cb7324e45b
[やってみた]Ansible Controllerをdockerコンテナで作成

## 背景・目的・目標

コンテナ内でAnsibleを実行し、他PC等へ接続する

## 参考サイト

[AnsibleとDocker Composeの相性問題に気づいた話](https://www.indetail.co.jp/blog/170313/)  
[Ansible Documentation](https://docs.ansible.com/ansible/latest/modules/ping_module.html)  

## 手順

※あらかじめDocker、Docker-composeがインストールされていることを前提としています

### Docker
Docker関連のファイルは以下の構成です。

```
./ansible/
├── docker
│   └── ansible
│       └── Dockerfile
└── docker-compose.yml
```

#### docker-compose.yml

```
version: '2'
services:
  ansible:
    container_name: 'ansible'
    image: ansible/ansible
    build:
      context: ./
      dockerfile: ./docker/ansible/Dockerfile
    tty: true
    volumes:
      - /home/xxxxx/xxxxx/volumes/ansible:/ansible
    environment:
      - sample=hoehoehoe
```

#### docker/ansible/Dockerfile

```
FROM ubuntu:18.04

RUN apt-get update
RUN apt-get install -y ansible
```


### マウントファイル
コンテナにマウントするファイル等は上記Docker関連ファイルとは別の場所で管理。
以下の構成です。

```
./volumes/ansible/
├── inventory
├── main.yml
└── roles
    └── ping
         └── tasks
            └── main.yml
```

#### inventory

```
[srv]
xxx.xxx.xxx.xxx

[srv:vars]
ansible_user=xxxxx
ansible_port=22
```

#### main.yml

```
- hosts: srv
  become: yes
  roles:
    - ping
```

#### roles/ping/tasks/main.yml

```
- ping:
        data: test
```


## 動作確認

```
$ docker-compose up -d

$ docker-compose ps
 Name      Command    State   Ports
-----------------------------------
ansible   /bin/bash   Up

$ docker-compose exec ansible /bin/bash

# cd /ansible

# ansible-playbook -kK -i inventory main.yml
SSH password:
SUDO password[defaults to SSH password]:

PLAY [srv] ****************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
ok: [xxx.xxx.xxx.xxx]

TASK [ping : ping] ********************************************************************************************************
ok: [xxx.xxx.xxx.xxx]

PLAY RECAP ****************************************************************************************************************
xxx.xxx.xxx.xxx                : ok=2    changed=0    unreachable=0    failed=0

```
Spotify APIを使ったヒット予測2.過去データのランキングをもとにざっくり予測

![spotify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/01b3237d-bf34-6f1b-646a-87fa92b409de.png)

日付ごとのランキングデータを元に、spotifyのデータだけを使ってランキング予測をしていきます。

今回はまず取り掛かりの第一回目として、
1.トラックごとのランキング推移をSpotifyの全期間取得
2.sklearnを使って簡易予測データ（学習データと検証データ）を作成
3.グラフで予測データを可視化

##1.トラックごとのランキング推移をSpotifyの全期間取得
Spotifyは2017年からのデータをcsvでダウンロードできますので、そのデータを使っていきます。
2017年1月1日からのデータを一つのcsvにまとめます。

作成したファイル一覧がこちら
![9A28D3E1-8EDA-41E6-B1BF-9BE19AA6E0B5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/12a57e58-5ed1-2aee-3fb2-5795270adf3b.png)


これで日付が入った3年半のデータが取れました。
このcsvを元にまずはとある楽曲１曲を選び、ランキングがどう変化したのかグラフを作っていきます。

前回同様jupyter Notebookを使って作業していきます。
細かい詳細は省きますが、
![83A6F1DD-F666-4D47-B49D-17EE96009423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/244df555-39ab-c0ea-86a2-e27f738926b2.png)


今回はTones And Iの「Dance Monkey」のランキング推移を使い、matplotで可視化しました。

https://www.youtube.com/watch?v=q0hyYWKXF0Q

今回はTones And Iの「Dance Monkey」（ https://www.youtube.com/watch?v=q0hyYWKXF0Q ）のランキング推移を使い、matplotで可視化しました。
初めてランキングにインしたのが2019年7月31日で、そこからどう推移しているかというと・・・
2019年7月31日に最初にランクインし、2020年1月に山を迎え、4月末〜降下しているのがグラフから見てとれます。


##2.sklearnを使って簡易予測データ（学習データと検証データ）を作成

ここからが今回の本番。今後の予測を作っていきます。
が、本来ならSpotifyだけでは予測は難しいため、今回はかなりざっくりとした予測になります。
早速やってみましょー！

今回は統計学の中でも簡易的な株価予測にも用いられる「線形回帰（Linear regression）」という手法を使って機械学習させていきたいと思います。

まずはpandasでデータを整形し、「predict」という列を作り、順位の5日前までのデータを格納します。
![48B5B518-9B0F-4E3A-8DE5-5A995832C3E0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/d1ea9b5d-24f8-b91b-3e34-26e2c9f1e4c4.png)


学習データと検証データを8:2で分け、データの確認
![867D7B04-02CD-4B27-927B-BE9BB400D7FF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/e0a13f4f-fae6-4327-04fe-f784b2068fb4.png)



やはり5日分だと精度としては少し低いですね。。

色々と試した結果、30日程度のバッファを持つと良さげな感じです。

上記スクリーンショットの「label」列のNaN部分のデータの予測がこちら。
![0C7B2D52-4F13-40D2-BBE9-4DE78E456905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/757955a3-9199-8334-2a02-16f45f81c045.png)



なんとなくいいような・・グラフにしてみます。

##3.グラフで予測データを可視化
![4D155DF2-7B59-4772-8802-1AA748E32F64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661171/0a99e54f-8b49-6066-18a1-b92afdbeede0.png)



なるほど、、
他要因がない限り、かなり急激に再生回数が落ちる予測になりました。。

おそらくこのままの予測どおりではなく、別要因も作用してくるはずなので一概にこの予測どおりにいくかは不明ですが、
Spotifyのデータだけでもある程度予測できるのが分かってもらえたかと思います。

次回は他データのAPIも使って同じようにプロットしていきたいと思います。





次回はより高度にランキングデータを取り、ランキング予測をしたいと思います。
ではまた！
全自分に捧ぐショートカットキー一覧

# 画像認識型RPAの環境依存をなくそう
画像認識やマウスの座標を拾って作業をしている人を見ると

(´・ω・)oO(え…動かないかもしれんとか、不安じゃないんかな…)

と内心ハラハラしている。
もしかしたら、昔「デスクトップはカスタマイズするもの」という世界線で生きていたからかもしれない。私のデスクトップは貴方のデスクトップとは全く違う生き物なのだ(何)

そういえば、ついさっき「pyAutoGUI使えばいいんじゃね？」とか答えはしたけど
あー、きっとマウスうねうね操作できるのとか心に響いちゃうんだろうなぁぁぁ…
と気が気ではない。
キーボード操作してやれば基本的に環境変わっても同じに動くんやで…

# ショートカットキーをド忘れした時に見るサイト
さて、前置きが長くなったが本題。
ショートカットキーをド忘れした時にいつもお世話になっているサイトを自分用に一覧にしておいた。

自動化のお供にチートシート程度で開いておく全自分に捧げる一覧だ。

## MicroSoft製品に関するショートカットキー
### Excel,Word,PowerPoint,Outlook
[137個のWindowsショートカットキー一覧表（PDF有）｜Office Hack](https://office-hack.com/windows/windows-shortcutkey-list/)
### MicroSoftTeams
[Microsoft Teams で使用するショートカット キー - Office サポート](https://support.microsoft.com/ja-jp/office/microsoft-teams-%E3%81%A7%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88-%E3%82%AD%E3%83%BC-2e8e2a70-e8d8-4a19-949b-4c36dd5292d2)

## ブラウザに関するショートカットキー
### GoogleChrome
[Chrome のキーボード ショートカット - パソコン - Google Chrome ヘルプ]
(https://support.google.com/chrome/answer/157179?hl=ja)
### Internet Explorer 11
[Internet Explorer 11 のキーボード ショートカット - Windows Help](https://support.microsoft.com/ja-jp/help/15357/windows-internet-explorer-11-keyboard-shortcuts)
### Firefox
[Firefox のキーボードショートカット | Firefox ヘルプ](https://support.mozilla.org/ja/kb/keyboard-shortcuts-perform-firefox-tasks-quickly)
## エディタに関するショートカットキー
### サクラエディタ
[サクラエディタ|キー割り当て一覧](https://sakura-editor.github.io/help/HLP000107.html)
[サクラエディタ|コマンド一覧](https://sakura-editor.github.io/help/HLP000193.html)
### Visual Studio Code
[Visual Studio Code キーボード ショートカット](https://qiita.com/oruponu/items/ae9c720d4522c1606daf)