OmniAICreator/Qiita-1.07M huggingface dataset:
nestjsでroute一覧を取得する

routeを一覧で見たいな思ったので調べたら便利なものがあった。
https://www.npmjs.com/package/express-list-endpoints

# npm install

```
npm i express-list-endpoints
npm i -D @types/express-list-endpoints
```

# 取得する方法

よくあるmain.tsに変更を加える

```typescript:main.ts(変更前)
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
  });
  await app.listen(3000);
}
```

```typescript:main.ts(変更後)
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import * as listEndpoints from "express-list-endpoints";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
  });
  await app.listen(3000);

  const server = app.getHttpServer();
  const router = server._events.request._router;
  console.log(listEndpoints(router));
}
```

routingの設定をしているController

```typescript:app.controller.ts
import { Controller, Get } from "@nestjs/common";

@Controller()
export class AppController {
  @Get("hoge")
  async getHoge(): Promise<string> {
    return "HOGE";
  }

  @Get("hogehoge")
  async getHogehoge(): Promise<string> {
    return "HOGEHOGE";
  }
}
```

# 出力してみる

npm run startするとコンソールに出力されているのが確認出来る

```
...
中略
...
[Nest] 30321   - 01/09/2020, 3:25:29 PM   [RouterExplorer] Mapped {/hoge, GET} route +1ms
[Nest] 30321   - 01/09/2020, 3:25:29 PM   [RouterExplorer] Mapped {/hogehoge, GET} route +0ms
[Nest] 30321   - 01/09/2020, 3:25:29 PM   [NestApplication] Nest application successfully started +11ms
[ { path: '/hoge', methods: [ 'GET' ] },
  { path: '/hogehoge', methods: [ 'GET' ] } ]
```

# 感想

一覧を取得出来る様になったので、整形してdumpする事によってドキュメント制作の時に活かせる様にしていきたい。

# シンプルなやつ

```typescript:main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import * as listEndpoints from "express-list-endpoints";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
  });
  await app.listen(3000);

  const server = app.getHttpServer();
  const router = server._events.request._router;
  const endpoints = listEndpoints(router);
  endpoints.forEach(endpoint => {
    console.log(
      `${endpoint.methods.filter((v, i, a) => a.indexOf(v) === i)} ${
        endpoint.path
      }`
    );
  });
}
```

出力結果

```
GET /hoge
GET /hogehoge
```
EditText.addTextChangedListenerに便利な拡張関数が追加されていました

環境

```build.gradle
implementation 'androidx.core:core-ktx:1.1.0'
```

EditTextの入力中文字列を取得する時に使うTextWatcherは3つのコールバック関数をもつインターフェースです。

```kotlin
editText.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    }

    override fun afterTextChanged(s: Editable?) {
    }
})
```

|  コールバック          |  説明                                                |
| ------------------- | --------------------------------------------------- |
|  beforeTextChanged  | テキストが編集される前に発生するイベント                      |
|  onTextChanged      | テキストが変更された直後(日本語IMEの変換候補が出ている間も含む) |
|  afterTextChanged   | テキストが変更された直後(入力が確定された後)                 |

なのでほとんどのケースにおいてonTextChangedのみで良いです。しかし3つのコールバックがあるとKotlinではSAMが効かないので毎回冗長なコールバックを書かなければなりません。

core-ktxに各コールバックを単体でリッスンできる拡張関数が追加されました。

```kotlin
editText.doOnTextChanged { text, start, count, after -> 
}
```

非常に楽になりました🎉

そのほかの拡張関数と従来のaddTextChangedListenerをラムダ式で書ける拡張関数はこちらです。

```kotlin
editText.doBeforeTextChanged { text, start, count, after -> 
}

editText.doAfterTextChanged { text ->
}

editText.addTextChangedListener(
    beforeTextChanged = { text, start, count, after ->
    },
    onTextChanged = { text, start, count, after ->
    },
    afterTextChanged = { text ->
    }
)
```
matlabのfigureをコマンドで表示する

*自分の備忘録です
matlabでfigureを作ったときに手動で開くのが面倒だったので，その対策

- 画像の表示

`openfig('figureのあるディレクトリ.fig')`
シングルクオーテーションで囲むことが必要．
同じディレクトリにある場合は，hoge.figを直接指定することもおそらく可能．
もしfigureが複数の規則性のあるディレクトリに格納されていると，
例えば

```
for i = 1:10
openfig(['hogehoge\hoge\',num2str(i),'hoge.fig'])
end
```
とすることで変数に合わせて読み取ってくれるようにできる．
matlabでは文字列の連結は[]でカンマ区切りでできる．
キャストはnum2str()など（そういえばDelfiもこんなんだった）

- 時間を止める

```
pause(4)
```
かっこの中の単位はsecond

- 画像をしまう

```
close all
```
Github actionsを触ってみる

# 本記事について
Github actionsを触ってみたので、ひとまず導入部分をまとめる。
今回はRustのドキュメントにある[minigrep](https://doc.rust-jp.rs/book/second-edition/ch12-00-an-io-project.html)のビルドとテストを行うこととする。

# Github actions導入
Githubのリポジトリのページから`Actions`をクリックする。すると以下のような画面に遷移する。
![コメント 2020-01-09 131432.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/3d828338-40af-5c6e-976f-6cd2da6c8bf4.png)
テンプレートがいくつか選べるようだが、今回はRustのテンプレートを選択してみる。
すると、このような画面に遷移する。
![コメント 2020-01-09 134107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/0ca99e87-30fa-8fba-9e89-d5a143c0126c.png)
ひとまず、このままの状態で、`Start Commit`を押し、コミットする。
すると、`.github/workflows/rust.yml`というファイルができる。中身は以下の通り。

```yaml:rust.yml
name: Rust

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Build
      run: cargo build --verbose
    - name: Run tests
      run: cargo test --verbose
```
これまで、`gitlab-ci.yml`をゴリゴリ書いていた身からすれば実に簡単であるが、基本設定は以上である。
では、動作確認をしてみる。
再びリポジトリの`Actions`をクリックすると以下のような画面に遷移する。
![コメント 2020-01-09 135010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/7c53156f-87d1-061e-aaa8-89e06c356e27.png)
ここからワークフローを選択すると、実行ログを見ることができる。
![コメント 2020-01-09 135655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/bc5b8276-b8f4-fda4-c0c1-b5b880650728.png)
ビルドとテストは通ったようだ。

# 成果物をアップロードしてみる
これだけでは少々物足りないので、ビルド成果物をgithub上からダウンロードできるようにしてみる。
[こちら](https://github.com/actions/upload-artifact)を参考に、`.github/workflows/rust.yml`に追記する。

```yaml:rust.yml
name: Rust

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Build
      run: cargo build --verbose
    - uses: actions/upload-artifact@v1 
      with:
         name: minigrep
         path: target/debug/minigrep
    - name: Run tests
      run: cargo test --verbose
```
この状態でコミットとプッシュを行うと、ワークフローが走り、以下のように成果物をダウンロードできるようになる。
![コメント 2020-01-09 143806.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/91c8e4ee-714e-3f57-7cae-fae327b5fdab.png)

#最後に
今回はお試し導入程度であったが、今後はMacやWindows環境を使った開発、Webアプリのデプロイなども行ってみたい。
[公式リファレンス](https://help.github.com/ja/actions)に詳細な説明が記載されているため、そちらも確認していただきたい。
OMC Log Analyticsの設定方法と使い方 - Windows編 -

Oracle Management CloudのLog Analyticsは、OSやMiddleware,Databaseなどの様々なログを集約して横断的に分析することができるサービスです。
ここでは、実際にWindowsのイベントログの取得するための設定手順、基本的な分析手法について紹介します。

- 左上のメニューアイコンからログアナリティクス-> ログ管理 -> エンティティを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/f06d237f-a11e-def7-feb0-2314b346d1a5.png)

- 新規アソシエーションをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/266b56e4-bd4a-6d56-ee6b-7c790953dfde.png)

- エンティティタイプをHost(Windows)に選択してエンティティの追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/18b74aec-8528-9250-55b4-cf0e100e66dc.png)

- エンティティ登録したHostが選択可能になっているのでチェックして選択をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/4686cc0e-37c3-60e4-2dcd-c580c3282182.png)

- 続行を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/f924ee96-33c2-a861-899f-8cca021fb780.png)

- Windows Application Events, Windows Security Events, Windows System Eventsを選択して一番下の続行ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/6f73b720-71d1-51de-bd14-f284842a12a8.png)

- エンティティの関連付けをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/8ea4a8cc-99af-9b37-1548-eddd9c5fc8d4.png)

- これでCloud AgentがWindowsの3つのイベントログを収集する設定が完了 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/1e44e7f1-0b0e-f302-03ec-8b9379015217.png)

- Log Analyticsの画面にWindowsのイベントログが表示されたら設定はOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/4d446f86-fd85-3eb1-f1e1-2824d8a574f8.png)

- 使用例
Event IDのフィールドをグループ化基準にドラッグ&ドロップ。右側の円グラフがEvent IDでグループ化される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b4fc9ea2-430b-2415-1230-a9a90221271a.png)

- ビジュアライゼーションからヒストグラム付きレコード選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/1256622d-881f-67d9-dd42-8c7bfa824e5f.png)

- 時系列でのログの出力状況
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/13140ca5-9cb7-32b4-a59c-28d882cbee33.png)

- ビジュアライゼーションからクラスタを選択するとログがクラスタリング(分類化)される。
 潜在的に問題のあるレコードやまれにしか発生しないレコードなど対象レコードの特定が簡単になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/f4f65289-261b-9e8b-3d80-dfc6cadad98c.png)

Cloud Agentは定期的に更新分のログレコードをOMCに送信し、ログデータは常に最新に近しい状態になります。今回はWindowsのイベントログを取り込む設定をしましたが、これ以外にもLog Analyticsには予め用意されたログ・パーサーが準備されています。

対応可能な[ログパーサーの一覧](https://docs.oracle.com/cd/E83857_01/paas/management-cloud/logcs/box-log-sources.html)


ここにない独自のログフォーマットの場合は、カスタムパーサーを自分で作成することで同様にログを取り込んで分析可能です。下記に、手動でのログ取り込みの方法やカスタムパーサーについて紹介しています。

Oracle Management Cloud関連の情報は[こちら](https://qiita.com/western24/items/1e44bfcaa77f3251a263)
[Ktor]multipart/form-dataでファイルを取得

## やりたかったこと
サーバサイドkotlinでKtorを使ってmultipart/form-data形式のファイルを取得したい。
画像でもtxtでもjsonでもdatでも。


## 実装

※動作確認したいだけならResourceとServiceに分ける必要はないです

``` hogeResource.kt
fun.Route.hoge(hogeService: HogeService) {
   route("hoge") {
       post("/") {
           val multiPartData = call.receiveMultiPart() 
           val res = hogeService.addHoge(multiPartData)
           call.respond(HttpStatusCode.OK, res)
       }
   }
}
```

``` hogeService.kt
    suspend fun addHoge(multipartData: MultiPartData) : Hoge {
        val file = makeFile(multipartData) ?: throw Exception()

        // この辺は今回関係ないので中略。
        // ファイルからデータを取得してExposedを使いDBに登録してます。

        return getHoge(hoge.id)
    }

    private fun makeFile(multipartData: MultiPartData) : File? {
        // ファイル生成（別にTempFileである必要はないので好みで)
        val file = File.createTempFile("tmp_", ".json")
        val part = multipartData.readPart() ?: return null
        if (part !is PartData.FileItem) return null 
        // ファイル内容の書き込み
        part.streamProvider().use { inputStream ->
            file.outputStream().buffered().use {
                inputStream.copyTo(it)
            }
        }
        return file
   }
```
・ファイル名
元ファイルから変えないならPartData.FileItem.originalFileNameを使えばよいと思います。

・FileItemの取得
ktorの公式サンプルだとmultipart.forEachPartを使っていますが
ファイルしか受信しないのであればmultipartData.readPart()で短く書けます。
（但し、FileItemだという型チェックはしてあげないといけません）

multipart/form-dataにファイル以外の別のパラメータも含んでいる場合はこんな感じ。

``` hogeService.kt
var hogeID = 0
var hogeName = ""
multiPartData.forEachPart { part ->
    when (part) {
        is PartData.FormItem -> {
           when (it.name) {
               "hogeID"   -> hogeID   = it.value.toInt()
               "hogeName" -> hogeName = it.value
           }
        }
        is PartData.FileItem -> {
           //(略）
        }
    }
}
```

いちいちJsonファイルをパースしてDBに登録、なんてことは滅多にやることではないので、
画像か、datで受け取って復号化みたいな用途が本来の使い方ですかね。
あとは、AmazonS3に突っ込むとか。

## 参考
Client Multipart
https://ktor.io/samples/other/client-multipart.html

PartData
https://api.ktor.io/1.3.0-rc2/io.ktor.http.content/-part-data/index.html
【C++】QtでGifアニメーションを表示する方法

# ■環境
　- PC : Windows10
　- C++
　- Qt 5.12.6（ソースコードからビルド）

※WindowsでQtを使えるようになるまでの話は下記記事に書いています
【Windows 10にQtをインストール】
https://qiita.com/tomtum/items/15c8b6485dc80921ff72
# ■コード
Gifアニメーションを、
　・枠なしウィンドウ
　・等倍
　・3秒間
で表示する事を目標にします

```c++:main.cpp
#include <iostream>
#include <string>
#include "QtWidgets/QApplication"
#include "QtGui/QMovie"
#include "QtWidgets/QLabel"
#include "QtCore/QTimer"
#include "QtCore/Qt"

//Gifファイルを表示するための自作クラス
class MyQtClass : private QMovie, private QLabel {

public:

	MyQtClass(const std::string f, int w, int h) {
		Initialize(f, w, h);
	}

	~MyQtClass() {
		StopMovie();
		QLabel::clear();
	}

	void ShowGifImage() {
		QMovie::start();
		QLabel::show();
	}

private:

	void Initialize(const std::string f, const int w, const int h) {
		QMovie::setFileName(f.c_str());
		QLabel::resize(w, h);
		QLabel::setMovie(this);
		QLabel::setWindowFlags(Qt::FramelessWindowHint);
	}

	void StopMovie() {
		QMovie::stop();
	}
};

int main(int argc, char**argv) {

	QApplication app(argc, argv);

	//描画の準備
	std::string gifname = "animation.gif";
	MyQtClass mqc2(gifname, 800, 480); //入力画像の横×縦を指定

	//描画
	mqc2.ShowGifImage();
	QTimer::singleShot(3000, &app, SLOT(quit()));

	return app.exec();
}

```
RTX1200 から CLI（コマンド）で、Wake On Lan する

mac から wakeonlanコマンドで起動させたかったけど、RTX経由でVPN接続してからwakeonlan叩くと

```bash
send : Can't assign requested address at /usr/local/bin/wakeonlan line 83.
```
と怒られて無理やった。

同じセグメント内に常時起動しているマシンが無いからRTXから実行することにした。

以下手順。


## 1.telnet 接続する
RTXはデフォルトだとSSH許可されてないはずなので、telnetで接続する。
macの場合、telnetクライアントがインストールされてない場合があるので

```bash

brew install telnet
```

などでインストールしてから接続する。

## 2.特権ユーザに昇格する
RTXにログインできたら



```
> admin
```

する。

## 3.WakeOnLan実行する

```
wol send lan1 まっくあどれす
```


以上。
【Java】ファイル内容のバイト列からData URIを生成する【Kotlin】

# やること
画像ファイルから取得したバイト列から、フロントで読める`Data URI`を生成します。

# やり方
サンプルコードは以下の通りです。

```kotlin
import java.util.Base64

val bytes: ByteArray = // ファイルから取得したバイト列
val base64Bytes: ByteArray = Base64.getEncoder().encode(bytes) // Base64エンコード
val base64Utf8String = String(base64Bytes, Charsets.UTF_8) // UTF-8への変換

val mimeType: String = // 何らかの方法で取得したMIME Type

// Data URIの生成
val dataUri: String = "data:${mimeType};base64,${base64Utf8String}"
```

## 解説
### Base64へのエンコード
`Base64`へのエンコードは、`Java8`以降では`java.util.Base64`に定義されたエンコーダーを用いることでライブラリを導入せずに行えます。

ここにはベーシック、`URL`、`MIME`の3種類のエンコーダーが定義されていますが、サンプルの通りベーシックエンコーダーを用いなければフロントで適切に解釈できません。

### 文字列への変換
エンコード結果はバイト列なので、適切に文字列にしなければ`Data URI`として扱えません。

### MIME Typeの取得
サンプルコードでは`MIME Type`の取得方法を記載していませんが、特に考慮することが無ければ拡張子から推測するのがいいと思います。

[`Apache Tika`を用いる](https://qiita.com/wrongwrong/items/f21c738afb3dca92818e)ことで厳密に`MIME Type`を判定することも可能です。
Next.jsでclassNameが見つからなくなるバグの対処方

# はじめに
`Next.js` + `styled-component` でホットリロードあり(`npm run dev`)で開発を行っているとスタイルを修正した際に下記のエラーが発生した。

```
index.js:1 Warning: Prop `className` did not match. Server: "文字列" Client: "文字列"
```

## 原因
スタイルを修正した際にローカルサーバー側では新しいCSSが作られるが(この時点でclass名が変わってしまう)、
クライアント側のHTMLが指定しているclassは変更前にビルドされた物なのでclass名が異なってしまいエラーが発生する。

## 解決方法
Ref: https://github.com/zeit/next.js/issues/7423

プロジェクトのrootディレクトリに `.babelrc` を作成し下記を記述したら解決した。
(すでに`.babelrc`が存在する場合は下記の内容を追記)

```
{
  "presets": ["next/babel"],
  "plugins": [
    [
      "styled-components",
      { "ssr": true, "displayName": true, "preprocess": false }
    ]
  ]
}
```

## 最後に
間違いや動かない等があれば、コメントください。
nodebrewのNODE_PATHを設定する奴

# 概要

[nodebrew](https://github.com/hokaccha/nodebrew)をインストールするとパスを通せと言われる
その通りに操作すると環境変数PATHに対してのパスが通ってNode.jsは使用可能になる。

しかしそれでは不十分で、
[NODE_PATH](https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders)への設定周りは記載されていないがとても重要である。
これに関してPCのセットアップの度にあちこち探す事になっているので備忘録として残す。

## まずはnodebrew越しに普通にインストール

```bash
$ curl -L git.io/nodebrew | perl - setup
# (意訳)下記を~/.bashrc等に貼り付けてパスを通してね！
export PATH=$HOME/.nodebrew/current/bin:$PATH

$ vim ~/.bashrc

$ cat ~/.bashrc
# ~~中略~~
export PATH=$HOME/.nodebrew/current/bin:$PATH

$ nodebrew install-binary latest

$ nodebrew use latest

$ node -v
# バージョン10なんとかみたいな数字が表示

$ npm -v
# バージョン6なんとかみたいな数字が表示
```

ここまでは問題なし、問題はここから

## インストールされたNode.jsを利用する

コアなNode.jsユーザーでなければ気が付かないと思うが、
nodebrew越しにインストールすると`-g`オプションで導入したパッケージが使えない。

```bash
$ echo $NODE_PATH

$ npm install -g lodash

$ node
> var _ = require('lodash')
Uncaught Error: Cannot find module 'lodash'
Require stack:
- <repl>
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
    at Function.Module._load (internal/modules/cjs/loader.js:898:27)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '<repl>' ]
}
```

Node.jsの`require`は`node_modules`というディレクトリ名を探すという事を行いながらライブラリを探す。
カレントディレクトリに存在しなければ1階層上で探すという事を繰り返すのだがそれでもパッケージが存在しなければ、グローバルの領域も探しにいく。

このルールに関しては下記の公式ドキュメント参照
[Loading from the global folders](https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders)
その時に重要になるのが[NODE_PATH](https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders)という環境変数だ。
Node.js用の`PATH`環境変数のように動作し、ライブラリが存在しない場合、最後の駆け込み寺的な存在となる。

Node.jsを実行ファイルでインストールすると、
グローバル指定でインストールしたnpmパッケージのPATHは通っているが、
nodebrew越しにインストールするとグローバル指定でインストールしたパッケージが使えない。

NODE_PATHの説明をサボっているnodebrewのせい

# 設定方法
## Bash

.bashrcの末尾にNODE_PATHの環境変数も設定してあげると解決

```bash
export PATH=$HOME/.nodebrew/current/bin:$PATH
export NODE_PATH=$HOME/.nodebrew/current/lib/node_modules
```

nodebrewの挙動として`~/.nodebrew/current`にシンボリックリンクを張る。
これは`nodebrew use vx.y.z`で指定したバージョンになる。
その実体は`~/nodebrew/node/vx.y.z/`であり、
npmで追加されたライブラリは`~/nodebrew/node/vx.y.z/lib/node_modules`配下である。

まぁ`~/.nodebrew`の中に入って探せばそれらしいものがすぐ見つかるはず

## 確認方法

REPLを立ち上げて`global.module.paths`を実行して値を確認する。
参考記事: [Node.js グローバルインストールでハマった](https://qiita.com/shintarogit/items/70f193829f4360dca771)

```bash
$ node
Welcome to Node.js v13.6.0.
Type ".help" for more information.

> global.module.paths
[
  '/home/miyabi/repl/node_modules',
  '/home/miyabi/node_modules',
  '/home/node_modules',
  '/node_modules',
  '/home/miyabi/.nodebrew/current/lib/node_modules', # <- 設定した内容だ！！
  '/home/miyabi/.node_modules',
  '/home/miyabi/.node_libraries',
  '/home/miyabi/.nodebrew/node/v13.6.0/lib/node'
]
```

---

# 【おまけ】 nodebrewから乗り換えました

こんな大変な事しなくても[Volta](https://volta.sh/)で良くね？

Voltaは2020年12月にバージョン1がリリースされた
かなり注目されているパッケージ管理ツール
実際に使ってみたところNODE_PATHもよしなにやってくれて良い感じだった

これからnodebrewでバージョン管理しようと思っている人は検討してみると良いかもしれない

参考記事: [Node.js のバージョン管理ツール Volta を使ってみる | DevelopersIO](https://dev.classmethod.jp/articles/node-version-volta/)
Amazon Linux2 で NewRelic Agent からデータが送信されない

PrivateTmp が有効になっていると NewRelic Agent が以下のエラーを吐いてしまいます。

```
warning: daemon connect(fd=6 uds=/tmp/.newrelic.sock) returned -1 errno=ENOENT. Failed to connect to the newrelic-daemon. Please make sure that there is a properly configured newrelic-daemon running. For additional assistance, please see: https://newrelic.com/docs/php/newrelic-daemon-startup-modes
```

PrivateTmp を無効にするしか対処方法が無いみたい...

```
# /usr/bin/mkdir -p /etc/systemd/system/php-fpm.service.d/
# echo "[Service]" > /etc/systemd/system/php-fpm.service.d/privatetmp.conf
# echo "PrivateTmp=false" >> /etc/systemd/system/php-fpm.service.d/privatetmp.conf
# /usr/bin/systemctl daemon-reload
# /usr/bin/systemctl restart php-fpm.service
# /usr/bin/systemctl status php-fpm.service
```

参考: [Rlicでサーバが表示されない](https://newrelic-support.nissho-ele.co.jp/hc/ja/community/posts/360003145571-Rlic%E3%81%A7%E3%82%B5%E3%83%BC%E3%83%90%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84)
[Perl]データベースのデータとファイルのデータを付き合わせて差分を表示してみた

# はじめに
運営しているサイトで
**「毎月送られてくるファイルデータとデータベースに保存してある先月分のデータを付き合わせて差分を同期する」**
という運用作業が必要になったので差分を表示するスクリプトを作ってみた。

# 環境情報
- AWS(Amazon Linux AMI 2018.03.0 (HVM))
- Perl (v5.16.3)

# 開発
昔から運用業務用のスクリプトはシェルスクリプトかPerlと相場は決まっていて
今回はDB接続が必要だったのでPerlで作成した。
仕様要件としては、

- ファイル内のIDとデータベース内のIDの差分を調べることができる
- 引数でファイルを指定できる
- 差分を標準出力で表示できる
- 想定される差分はファイル側への追加のパターンのみ

と言うことでチャチャッと作っていく。

### 引数からファイル名を取得する
```perl
# 引数を取得
my $file = shift;

# 引数がないときは、使用方法を示して終了
unless ($file) {
  die "Usage: $0 file";
}
```

### ファイルデータを読み込む
```perl
# ファイルを読み込む
open(my $fh, "<", $file)
  or die "Cannot open $file for read: $!";

# ファイルデータを格納
my $files = [];
while (my $line = <$fh>) {
  # 改行を取り除く
  chomp $line;
  push @$files, $line;
}
close $fh;
```

### データベースデータを読み込む
```perl
# データベース接続準備
my $dsn = "dbi:mysql:database=xxxxxxxxxx;host=localhost;port=3306";
my $user = "root";
my $password = "";

# データベースハンドルを作成
my $dbh = DBI->connect( $dsn, $user, $password, {
    AutoCommit => 0,
    PrintError => 0,
    RaiseError => 1,
    ShowErrorStatement => 1,
    AutoInactiveDestroy => 1
})|| die $DBI::errstr;

# データを取得
my $sth = $dbh->prepare("SELECT columns_name FROM table_name;");
$sth->execute();

# 取得したデータを格納
my $dbs = [];
while (my $ary_ref = $sth->fetchrow_arrayref) {
  push @$dbs, $ary_ref->[0];
}

# 後始末
$sth->finish;
$dbh->disconnect;
```

### データを突き合わせる
```perl
my $is_registered;
for my $data ( @$files ) {
  $is_registered = 0;
  for my $tmp ( @$dbs ) {
    # データが存在したらフラグを立てて離脱
    if ( $data eq $tmp ) {
        $is_registered = 1;
        last;
    }
  }
  # 対象を出力
  print "$data\n" if $is_registered eq 0;
}
```

はい、終了。お疲れ様でした。
あとは毎回エクセルファイルで渡してくるのをcsv形式にしてもらうよう調整してデータ登録もこのスクリプトでできるようにしなきゃ。

以下、全文。

```perl:diff_data.pl
#!/usr/bin/perl
use strict;
use warnings;
use DBI;

# 引数の処理
my $file = shift;

# 引数がないときは、使用方法を示して終了
unless ($file) {
  die "Usage: $0 file";
}

# ファイルを読み込む
open(my $fh, "<", $file)
  or die "Cannot open $file for read: $!";

# ファイルデータを格納
my $files = [];
while (my $line = <$fh>) {
  # 改行を取り除く
  chomp $line;
  push @$files, $line;
}
close $fh;

# データベース接続準備
my $dsn = "dbi:mysql:database=xxxxxxxxxx;host=localhost;port=3306";
my $user = "root";
my $password = "";

# データベースハンドルを作成
my $dbh = DBI->connect( $dsn, $user, $password, {
    AutoCommit => 0,
    PrintError => 0,
    RaiseError => 1,
    ShowErrorStatement => 1,
    AutoInactiveDestroy => 1
})|| die $DBI::errstr;

# データを取得
my $sth = $dbh->prepare("SELECT columns_name FROM table_name;");
$sth->execute();

# 取得したデータを格納
my $dbs = [];
while (my $ary_ref = $sth->fetchrow_arrayref) {
  push @$dbs, $ary_ref->[0];
}

# 後始末
$sth->finish;
$dbh->disconnect;

my $is_registered;
for my $data ( @$files ) {
  $is_registered = 0;
  for my $tmp ( @$dbs ) {
    if ( $data eq $tmp ) {
        # データが存在したらフラグを立てて離脱
        $is_registered = 1;
        last;
    }
  }
  # 対象を出力
  print "$data\n" if $is_registered eq 0;
}
```
MCプロトコルの電文を生成するWEBアプリケーション

## はじめに

本記事は、
MCプロトコルという
三菱電機㈱製 PLC と通信するためのプロトコルで使用する電文を作成するWEBアプリケーションを作成しましたので、その紹介記事です。

IoTの普及により、IT系のエンジニアがシーケンサを操作するケースも増えていると思います。

完成度は低いですが、本ツールがIoT系のエンジニアの助けになれば幸いです。

---

## ツールの紹介

以下のURLから利用できます。

入力フォームに必要実行を入力して、電文生成を実行すると電文が作成されます。

~~http://tech.ohina.work:8000/request/~~
http://ohina.work:8000/request/

![request_generator.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441666/9c357b8d-1b34-b575-c45d-06b49dcd5b91.jpeg)

## 注意事項

* 対応しているのはMelsec Q/Lシリーズになります
* ランダム読出しは非対応です

---

## 参考サイト

* https://zubu.jp

* https://qiita.com/Tatsuya-8888/items/5c09f6004d0db59322f1
https://plc-memo.com/maketool3/

* http://seigyochikarazoe.blog.fc2.com/?tag=Melsec&page=5

* http://www.takach.net/pc/melsec_socket.html
* 
https://qiita.com/hidehito108/items/e8eca75a46ee7d59feed

* https://www.keyence.co.jp/ss/products/controls/network/basics/standard.jsp
NumpyとOpenCVを使ってマリオを1機作る

##傍から見たら仕事しろ！と怒られるデータフレーム
しかし、ちゃんと目的があります。
OpenCVはNumpyのndarray配列を使って、データを取り扱っています。

ってことは、グレーなら1次元、カラーなら3次元の配列をそのまま投げれば再現できんじゃん！
と、作法もルールも全く無視した変態チャレンジングをやってその度砕けました。
この度、作業が無事に終了しましたので
世の中の何の役にも立たないコードをアップします。

12×12の配列で配管工おじさんを描きました。

```mario.py

import cv2
import numpy as np

val = 0
#空のリストを作成(12*12で全要素を0)
rchannel = [[val] * 12 for i in range(12)]
rchannel = np.array(rchannel)
gchannel = [[val] * 12 for i in range(12)]
gchannel = np.array(gchannel)
bchannel = [[val] * 12 for i in range(12)]
bchannel = np.array(bchannel)

#地獄の手打ちゾーン
rchannel[3,3:8] = 255
rchannel[4,2:11] = 255
rchannel[5,2:5] = 146
gchannel[5,2:5] = 41
bchannel[5,2:5] = 6
rchannel[5,5:7] = 248
gchannel[5,5:7] = 178
bchannel[5,5:7] = 108
rchannel[5,7] = 146
gchannel[5,7] = 41
bchannel[5,7] = 6
rchannel[5,8] = 248
gchannel[5,8] = 178
bchannel[5,8] = 108
rchannel[6,1] = 146
gchannel[6,1] = 41
bchannel[6,1] = 6
rchannel[6,2] = 248
gchannel[6,2] = 178
bchannel[6,2] = 108
rchannel[6,3] = 146
gchannel[6,3] = 41
bchannel[6,3] = 6
rchannel[6,4:7] = 248
gchannel[6,4:7] = 178
bchannel[6,4:7] = 108
rchannel[6,7] = 146
gchannel[6,7] = 41
bchannel[6,7] = 6
rchannel[6,8:11] = 248
gchannel[6,8:11] = 178
bchannel[6,8:11] = 108
rchannel[7,1] = 146
gchannel[7,1] = 41
bchannel[7,1] = 6
rchannel[7,2] = 248
gchannel[7,2] = 178
bchannel[7,2] = 108
rchannel[7,3:5] = 146
gchannel[7,3:5] = 41
bchannel[7,3:5] = 6
rchannel[7,5:8] = 248
gchannel[7,5:8] = 178
bchannel[7,5:8] = 108
rchannel[7,8] = 146
gchannel[7,8] = 41
bchannel[7,8] = 6
rchannel[7,9:11] = 248
gchannel[7,9:11] = 178
bchannel[7,9:11] = 108
rchannel[7,11] = 146
gchannel[7,11] = 41
bchannel[7,11] = 6
rchannel[8,1:3] = 146
gchannel[8,1:3] = 41
bchannel[8,1:3] = 6
rchannel[8,3:7] = 248
gchannel[8,3:7] = 178
bchannel[8,3:7] = 108
rchannel[8,7:11] = 146
gchannel[8,7:11] = 41
bchannel[8,7:11] = 6
rchannel[9,3:10] = 248
gchannel[9,3:10] = 178
bchannel[9,3:10] = 108
rchannel[10,2:4] = 255
bchannel[10,4] = 255
rchannel[10,5:9] = 255
rchannel[11,1:4] = 255
bchannel[11,4] = 255
rchannel[11,5:11] = 255

#チャンネルを結合
data_map = np.stack((bchannel,gchannel,rchannel),-1)
#データタイプを変更→これでOpenCVで扱える
data_map = np.array(data_map, dtype="uint8")
#可視化しやすいように拡大
data_map = cv2.resize(data_map, (400, 400),interpolation=cv2.INTER_NEAREST)

#表示
cv2.imshow("show",data_map)
cv2.waitKey(0)
cv2.destroyAllWindows()

```

![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203445/6a7dce2c-6cf7-fb58-570e-279bfb35b204.jpeg)


2020年もよい1年になりますように。
Bootstrapでスライダー(カルーセル)の作成方法

Bootstrapを使えば、スライダーを簡単に実装することができます。

ちょっとしたカスタマイズ方法を共有します。

(注)Bootstrapではスライダーのことをカルーセル（Carousel）と呼びますが、この記事では「スライダー」に統一して説明します。
<h2>Bootstrapのスライダーのカスタマイズ</h2>
<h3>インディケーターの色を変更する（基本色）</h3>
<pre>
<code>
.carousel-indicators li {
    background: #D5D5D5（通常時）;
}
</code>
</pre>
<h3>インディケーターの色を変更する（表示されている時）</h3>
表示されているときは、自動的に<code>.active</code>が付与されています。

<pre>
<code>
.carousel-indicators .active {
    background: red(表示されているときの色);
}
</code>
</pre>
<h3>インディケーターを丸くする</h3>
インディケーターの形はデフォルトでは平べったい四角形です。
<pre>
<code>
.carousel-indicators li {
    border-radius: 50%;
    width: 12px;
    height: 12px;
    margin: 0;
    border :10px;
}
</code>
</pre>


公式ドキュメント：https://getbootstrap.com/docs/4.1/components/carousel/(英語)
自分のブログ：https://akihiko-s.com/
[WordPress] サイトヘルスで「サイトでループバックリクエストが完了できませんでした」と表示される

WordPress 管理画面のURL ( `/wp-admin/*` ) に IP 制限をかけている場合に、[サイトヘルス機能](https://make.wordpress.org/core/2019/04/25/site-health-check-in-5-2/)で「サイトでループバックリクエストが完了できませんでした」というエラーが発生します。

![スクリーンショット 2020-01-09 14.06.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/de80bcba-1462-eb63-6819-1c4f33d7903b.png)

`wp-admin/site-health.php` のみ IP 制限を解除するようにすれば解決します。

[SiteGuard WP Plugin](https://ja.wordpress.org/plugins/siteguard/) を利用している場合は、「管理ページアクセス制限」の設定画面を開
き、「除外パス」の欄に `site-health.php` を追加すればOK。
参考: [サイトヘルスでエラー &#124; WordPress.org](https://wordpress.org/support/topic/%E3%82%B5%E3%82%A4%E3%83%88%E3%83%98%E3%83%AB%E3%82%B9%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC/)
Office2016 VBエディタの不具合で設定ができない？

### 背景
Windows7、Office2010のサポートが2020年2月？に切れるので、Office2016にUPDATEしました。


### 問題発生
純正の設定ではコードが読みづらいので、「エディタの設定」をしようとしたところ、
アプリが落ちてしまうではないか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/dfa71a5b-c8ff-3b41-f00a-ae0dcb797236.png)


### 対応方法
**レジストリをいじる**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/1062d1e0-1f48-9ebc-08ec-8d3b88b60a32.png)

コンピューター\HKEY_CURRENT_USER\Software\Microsoft\VBA\7.1\Commonへアクセスする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/719d81c9-dfb3-cab1-1dcf-df727785abfd.png)

「FontFace」を開いて、値を好きなフォントにする。
※使えるフォントは**C:\Windows\Fonts**で確かめておくことをおススメします。

登録したら、Office系を再起動する。で、VBエディタを開くと。。。通常通り動きました。

---
### 参考記事
仕事で毎日VBAを書くので、すごく助かった。
[参考記事](http://blog.higty.xyz/post/vbe-setting-error/)
dispatchでnetty4.0由来のエラーに遭遇した

## dispatchでnetty4.0由来のエラーに遭遇した

該当バージョン
dispatch-core_2.12 0.13.4

```
java.lang.IllegalStateException: failed to create a child event loop
```

nettyの依存
1. dispatch
2. Asynchronous Http Client(以降AHC)
3. netty

nettyのissue探してみる
https://github.com/netty/netty/issues/7243

4.1のアップデートで解消されているらしい


maven見てみるとわかるんですが、AHC2.1系からnetty4.1系にアップデートされている
https://mvnrepository.com/artifact/org.asynchttpclient/async-http-client

dispatchはというと、、、

githubはアップデートちゃんとしてある
https://github.com/dispatch/reboot/commit/135e90de1f7186b94f6db4be5c5f55c1afa96cef#diff-10e6c0c6d9998a5d5b6e19e45f1485ab

~~mavenにはAHC2.1系に対応した物は上がっていない。
しばらくアップデートされていない。~~
(OSS活動やりたいけどチキンなのでごめんなさい
無知なのは僕だった

[Change organization and URL](https://github.com/dispatch/reboot/pull/175)
https://github.com/dispatch/reboot/commit/f2660f1b3e0b27011bbe211ed35b99af83a0f386
[Merge pull request #175 from dispatch/org-change](https://github.com/dispatch/reboot/commit/f2660f1b3e0b27011bbe211ed35b99af83a0f386)

途中からorganizationが変わっていた

こっちから貰えばすべて解決
https://mvnrepository.com/artifact/org.dispatchhttp/dispatch-core_2.13/1.1.0


~~とりあえず下記でAHCの依存を明示することで動作した(軽い利用なのでがっつりテストはしてない~~

```
libraryDependencies += "org.asynchttpclient" % "async-http-client" % "2.10.4"
```



setAcceptAnyCertificateを利用している方は一工夫必要
dispatchでオレオレ証明書とか使ってる場合

```
javax.net.ssl.SSLPeerUnverifiedException
```

https://github.com/AsyncHttpClient/async-http-client/issues/1460

> setAcceptAnyCertificate is a poor name for what it actually does: setting an insecure TrustManager

AHC2.1で廃止された模様。


> AHC 2.1 drops setAcceptAnyCertificate and introduces separate
setDisableHttpsEndpointIdentificationAlgorithm and setUseInsecureTrustManager options.

setAcceptAnyCertificateはこう書き換えるとオレオレ証明書回避できる

```
dispatch.Http.withConfiguration(config => config.setAcceptAnyCertificate(true))
```

↓↓↓↓↓↓↓↓↓↓↓

```
dispatch.Http.withConfiguration(config => config.setDisableHttpsEndpointIdentificationAlgorithm(true).setUseInsecureTrustManager(true))
```

やらなくて済むならやらない方が良いです。
僕は証明書入れます。

別のissueでも質問があってドキュメント残してた。
https://github.com/AsyncHttpClient/async-http-client/blob/master/CHANGES.md
ELBタイムアウトとApacheのKeepAliveTimeoutに適正な値を設定する

# はじめに
ELBと配下のApache間で502エラーが稀に発生するため、調査したところ、ELBタイムアウト値よりApacheのKeepAliveTimeout値が低い事が原因だった。
ApacheのKeepAliveTimeout値をELBのタイムアウトより大きい値に設定する事で回避できるため、その設定方法を記載する。

# ELBの設定確認

EC2コンソール画面から、「ロードバランサー」＞「対象のロードバランサーを選択」＞「説明タブ」の
「属性：アイドルタイムアウト」の値が60秒であることを確認する。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273157/7fb0144d-1f99-170a-6198-57ae2bdfe92c.png)

# Apacheの設定
ELBタイムアウト値より大きい値を設定する必要がある。今回は、Timeout およびKeepAliveTimeout の値を120秒に設定する。

```
Timeout 120
KeepAliveTimeout 120
```
tfswitchをlinuxにインストールする

mac版も書きました。
使い方はこちらの記事の方が参考になるかと思います。
[tfswitchをmacにインストールする](https://qiita.com/horit/items/9970726ad51eccd38b65)

# tfswitchとは
https://warrensbox.github.io/terraform-switcher/
terraformのバージョンを簡単に切り替えられるツール。
最新へのバージョンアップもtfswitchコマンド叩いて選ぶだけ！便利！！

# インストール手順
## 環境

```
$ cat /etc/system-release
Amazon Linux 2
```

## 手順
公式にある手順を実行。

```
$ sudo su -
# curl -L https://raw.githubusercontent.com/warrensbox/terraform-switcher/release/install.sh | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  9159  100  9159    0     0   9159      0  0:00:01 --:--:--  0:00:01 88922
warrensbox/terraform-switcher info checking GitHub for latest tag
warrensbox/terraform-switcher info found version: 0.7.737 for 0.7.737/linux/amd64
warrensbox/terraform-switcher info installed /usr/local/bin/tfswitch
```

# 使い方
コマンド叩いて、使いたいバージョン選ぶだけ。

```
$ terraform --version
Terraform v0.12.18
[gitlab-runner@prod-gitlab-runner terraform]$ tfswitch
Use the arrow keys to navigate: ↓ ↑ → ← 
? Select Terraform version: 
  ▸ 0.12.19 ←選ぶ
    0.12.18
    0.12.17
    0.12.16
↓   0.12.15
✔ 0.12.19
Switched terraform to version "0.12.19" 
$ terraform --version
Terraform v0.12.19
```

# トラブルシューティング
インストール直後にコマンド実行すると権限のエラーが出ました。

```
$ tfswitch
2020/01/09 04:13:50 Creating directory for terraform: /home/ec2-user/.terraform.versions/
✔ 0.12.19
Downloading https://releases.hashicorp.com/terraform/0.12.19/terraform_0.12.19_linux_amd64.zip to terraform_0.12.19_linux_amd64.zip
Downloading ...
16530635 bytes downloaded.
2020/01/09 04:13:52 
                Unable to create new symlink.
                Maybe symlink already exist. Try removing existing symlink manually.
                Try running "unlink /usr/local/bin/terraform" to remove existing symlink.
                If error persist, you may not have the permission to create a symlink at /usr/local/bin/terraform.
                Error: symlink /home/ec2-user/.terraform.versions/terraform_0.12.19 /usr/local/bin/terraform: permission denied
```
セキュリティ的に問題ありそうですが、下記コマンドで動くようになりました。

```
$ sudo chmod 777 /usr/local/bin
```
サクラエディタで任意の文字を最後に追記するマクロ

# 内容
サクラエディタで30行ほどに同じ文字列を行末に入れることが時々ある。
Shift + F6 の短形選択で入れれるものはいいが文字数が違うものがあると入れづらい。
そのため1行1行入力しているためケアレスミスや時間が少しかかる。
マクロで行末に任意の文字を入れることができたらいいなと思った。
# 方法
サクラエディタにはマクロ機能があり
jsを使用することができるので
jsにて行末に文字列をを入力する。
# ■以下ソースコード
```js
//変数定義
var lines = [];
var str = "";

var AddWord = InputBox("入力したい文言を記入してください","",20);

// 行数を取得
var cnt = GetLineCount(0);


//もし行が選択されていない場合、全選択
if(Editor.IsTextSelected() == 0)
{
	Editor.SelectAll();
}



//文字を取得
var text = Editor.GetSelectedString(0);

//配列に分解
var lines = text.split(/\r\n|\r|\n/);

//文字列追加
for (var i = 0; i < lines.length; i++) {
	str = str + lines[i] + AddWord + "\r\n";
}


//置換実行
Editor.InsText(str);
Editor.ReDraw(0);
```
# 作成後
使用頻度的にはショートカットキーに登録するほどではないが、
あれば便利程度だと思った。
matplotlibでグラフを大量生成する際、画面にはグラフを表示させたくない（ jupyter環境）

結論としては `plt.close()` で解決です。

# はじめに

 jupyter（Google Colab.）環境で、matplotlibを利用して、大量のグラフを生成して画像ファイルとして保存したい場合、ノートブックの**実行結果セル（画面上）にはグラフを表示させたくない場合**があります。

特に、20枚を超えるグラフを表示させようとすると、次のような警告もでてきます。

> /usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:8: 
> RuntimeWarning: More than 20 figures have been opened. 
> Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory.
> (To control this warning, see the rcParam `figure.max_open_warning`).
 
この問題の回避についてのメモです。

# 現状

次のコードは「平均50、標準偏差10に従う40個の正規乱数を生成して、そのヒストグラムを描いてpngファイルとして保存するもの」です。

50セットを試行したときの各セットの分布をみるために、50回のループをまわしています。

```py:実行結果セルに大量のグラフが出力されてしまう
import numpy as np
import matplotlib.pyplot as plt

# 50枚の画像ファイルを生成
for i in range(50) : 
  dat = (np.random.normal(50,10,size=40)).astype(np.int64)
  plt.figure()
  plt.hist(dat,bins=10,range=(0,100))
  plt.yticks(range(0,31,10))
  plt.xlim(0,100)
  plt.ylim(0,30)
  plt.savefig(f'fig{i}.png') # 画像ファイルとして保存
```

上記コードを実行すると**冒頭の警告が表示され**、また実行結果セルに大量のグラフが並んでノートブックが見づらくなってしまいます。同時に、ノートブック（`xxxx.ipynb`）には実行結果の画像も内包されるので、そのファイルサイズも大きくなってしまいます。

※ ノートブック環境では、`plt.show()` を明示しなくてもグラフが自動で画面出力されます。

# 解決

グラフをファイル出力 `plt.savefig(...)` した後に、`plt.close()` を入れることで解決されます。

```py:実行結果セルにグラフを出力しない
import numpy as np
import matplotlib.pyplot as plt

for i in range(50) : 
  dat = (np.random.normal(50,10,size=40)).astype(np.int64)
  plt.figure()
  plt.hist(dat,bins=10,range=(0,100))
  plt.yticks(range(0,31,10))
  plt.xlim(0,100)
  plt.ylim(0,30)
  plt.savefig(f'fig{i}.png')
  plt.close() # ■■■ 追加 ■■■
```

上記コードを実行すると、実行結果セルには何も出力されません。無論、ファイル出力は問題なく行なわれます。
WordPressにオリジナルデータをデータベースに入力する方法


【このページは未完成です】


WordPressは記事としてデータ入力をしていますが、ショップデータのような場合データ入力したい場合があると思います。

ショップ名：**********
住所：***************
電話番号：*************
ホームページ：***************
価格:*************
特徴：****************

いわゆるデータベースとして保存することです。
こうやって保存することで、可能性や作業効率が一気にアップします。

WordPressにオリジナルデータを入力したいと考えたときに２つの方法があります。


**１つ目は「カスタム投稿タイプ+カスタムフィールド」を使って入力する方法**
こちらの方法は、初心者におススメです。

プラグインを組み合わせることで比較的に利用が可能になります。
有名なのが「カスタム投稿タイプ：Custom Post Type UI」と「カスタムフィールド：Advanced Custom Fields」です。



**2つ目は「自作のテーブルをデータベース（通常はMYSQL）に作成する方法**

自作プラグイン：https://www.webopixel.net/wordpress/637.html

管理画面にオリジナル設定ページを追加：https://h2ham.net/wordpress-creating-options-pages

##Wordpressの管理画面からfuncitons.phpを開く

外観-テーマエディタ-funcitons.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/accdc2fe-8cb0-d1bf-e8c9-979111e4c629.png)


##funcitons.phpに投稿タイプを追加する

```functions.php
register_post_type('goods',array(
   'label' => '商品',
   'public' => true,
   'show_ui' => true,
));

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/b2619aa9-ccb6-c037-927b-d267957a1f54.png)

##タクソノミー（分類）の追加

```functions.php
register_taxonomy('goods_category','goods',array(
   'label' => 'カテゴリー',
   'show_ui' => true,
   'hierarchical'=> 'true',
));

```

https://ssit.jp/blog-020/

https://yuuchika.com/shortcode_method/
Ignoring gemfile名 because its extensions are not built. Try: gem pristine gemfile名 --version 

Rails new もしくは Rails sした際に表題のエラーが多数出た。



解決方法
実際にターミナルで表示されている
Try:以降の部分をターミナルに打ち込めば解決します。
`gem pristine gemfile名 --version `


このエラーが何で起きているのか自分なりの解釈で解説

Ignoring　訳:無視する
because its extensions are not built 訳:拡張機能が構築されていない為
pristine　訳:gemの隠し場所にあるファイルからインストールしたgemを初期状態へ戻す

拡張機能ここでいうGemファイルが構築されてないんで無視します。Try以降の部分を実行し初期状態に戻してくださいと言っている
MacでIntelliJが起動しなくなったときに見るところ


IntelliJがクソ重くて使えなかったので、VMOptionいじったら動かなくなりました・・・
修復したので忘れないように、メモレベルで残します。

## ターミナルからの直接起動

```sh:console
/Applications/IntelliJ\ IDEA.app/Contents/MacOS/idea 
2020-01-09 13:20:00.633 idea[24470:651890] allVms required 1.8*,1.8+
2020-01-09 13:20:00.636 idea[24470:651896] Value of IDEA_VM_OPTIONS is (null)
2020-01-09 13:20:00.636 idea[24470:651896] Processing VMOptions file at /Users/hisayuki/Library/Preferences/IntelliJIdea2019.3/idea.vmoptions
2020-01-09 13:20:00.636 idea[24470:651896] Done
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
Error occurred during initialization of VM
Multiple garbage collectors selected
```

エラーの場合ははVMのメモリ設定の可能性が高い
このときは`-XX:+UseG1GC`と`-XX:-UseParNewGC`というオプションをつけてたのが間違いでした。

## VMOptionの修正

```sh:console
vi /Users/<MACのユーザー>/Library/Preferences/IntelliJIdea2019.3/idea.vmoptions
```

### 修正前
```
-Xms2G
-Xmx4G
-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none

-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof

-XX:+UseG1GC
-XX:-UseParNewGC
```

### 修正後
```
-Xms2G
-Xmx4G
-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none

-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof

```


## （参考）デフォルト値の確認方法

わかんないときはとりあえずデフォルト値に戻すのもありなので、参照方法です。

```
$ cat /Applications/IntelliJ\ IDEA.app/Contents/bin/idea.vmoptions 
-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-XX:CICompilerCount=2
-Dsun.io.useCanonPrefixCache=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Djdk.attach.allowAttachSelf=true
-Dkotlinx.coroutines.debug=off
-Djdk.module.illegalAccess.silent=true
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
```
AIツール作成に大量のデータからコードテスト用データ分離

#前書き
今はやりのAI（機械学習やディープラーニング）のためツール作成するとき、よくある苦労の一つはコードテストである。その原因は、モデルの精度確認のため大量のデータ（以下、「全体データ」と呼ぶ）が用意されているからである。
AI用ツール作成において、コードテスティングの必要性が出てくる場面を考えると、例えば、新規ハイパーパラメータの導入、ネットワーク構成変更、転移学習における新規タイプの学習済みネットワークの導入うなどは勿論、その他にも、例えば、ロス関数のカスタム化、学習データのサンプリング、一部ラベルの除外または合体、Ensemble（複数のモデルの合同適用）など、様々なケースがある。ただし、どれにしても、コードを書いた後、そのテスティングのみの時は、特に学習精度ではなく、むしろ、変更したコードに何らかのバグや漏れがあるか、非対応性が発生しているかなどを確認したいだけが一般的な目標になる。その時、単体やシステムテストでいちいち全体データを回すより、そのほんの一部のみを回して動作確認することが時間節約のために望ましい。
そのために、例えば、全体データの数万枚画像より数百枚だけをコードテスト（学習や検証ではありません）のためにピックアップし、「コードテスト用データ」を作ればいいですが、全体データの画像にも定期的なアップデートや変更が発生するのがよくあることであり、そのアップデートや変更に伴い、コードテスト用データに使う数百枚の画像もアップデートしておくことが必要となる。例えば、全体データに新しいラベルに該当するデータが加わった場合、そのラベルに関係するコードのテストのために、コードテスト用データにその新規ラベルに該当する画像も数枚入れておく必要性が出てくる。
このように数百万枚の画像から数百枚画像をラベルごとのバランスよくピックアップすること、また、定期的にその更新を行うことのため、簡単なルーチンがあれば生活が楽になることは言うまでもない。
本投稿では、MATLABを使って簡単にそのようなUtilityの作り方を紹介する。
※ここでは画像の代わりにデータファイルも同じ考え方で使える。

#環境
MATLABのR2019bバージョン
Windows10
MATLAB Toolbox: Image Processing Toolbox

#プログラムのワークフロー
全体データよりコピー対象画像を選択し、コードテスト用データとしてそれを別の場所にコピーするのみの非常に簡単なワークフローになる。
１．ユーザーによる入力
全体画像データの場所やコードテスト用データの保存先（例えば、フォルダーの絶対パス）、何割（例えば、1%）をテストに使うかなどのパラメータを指定。

``` MATLAB
%元データのフォルダー
orgFldr = uigetdir('','元データのフォルダー：');
%保存先フォルダー
dstFldr = uigetdir('','保存先フォルダー：');
%何割をピックアップするかを指定 (例えば、この例では、2%)
perc = 2;

```

２．コピー対象画像選択
MATLABの場合、ImageDatastore関数で楽にできるようになっているため、助かる。
各々のラベルのバランスを保ちながら一定割合の画像（またはデータ）ファイルを選択できる。

``` MATLAB
%Image datastoreの作成（すべてのファイル名が入ります）
imds = imageDatastore(orgFldr,...
    'IncludeSubfolders',    true,...
    'LabelSource',          'foldernames');
% 指定したパーセントに合わせてランダムにファイル選択
N   = numel(imds.Files); %全体画像データの数
SN  = round(N*perc/100); %コードテスト用データの数 
sInd= randperm(N,SN);%ランダムにSN個分のインデックスを取得
orgFile = imds.Files(sInd);%コピー対象データの元ファイルパス
dstLabl = imds.Labels(sInd);%コードテスト用データのラベル
lblStrs = unique(dstLabl);%カテゴリー

```

３．ファイルのコピー
文字列処理で、各々の画像ファイル名などを変えず直上のフォルダーパスのみを変えて、画像をコピーする。このフォルダーのパスを変更するため文字列処理とセルデータ型に一発で適用できるcellfun()関数を効率用句活用できる。

``` MATLAB
% まずは、それぞれのカテゴリーのフォルダー作成
for k = 1 : numel(lblStrs)
    thisFldr= fullfile(dstFldr,string(lblStrs(k)));
    if ~exist(thisFldr,'dir')
        mkdir(thisFldr);%既にフォルダーがない場合のみ新規作成
    end
end

%ファイルのコピー（MATLABのcellfun関数を利用して簡単に実装）
dstFile = cellfun(@(x) strrep(x,orgFldr,dstFldr), orgFile,...
    'UniformOutput',false);%コピー対象データの保存先へのファイルパス
%ファイルを一括コピー
cellfun(@copyfile,orgFile,dstFile)
```

#活用方法
ここで紹介したコードを関数またはスクリプトにまとめておき、必要に応じて実行すれば、すぐコードテスト用のデータ群を活用できる。
nvm, npm, Node.js 覚書

#概略
**Node.js**については言わずもがな。
**nvm**と**npm**については、NodeのバージョンやNode用のパッケージのバージョンの管理を助けてくれるアプリケーションである。
各バージョンを固定したり入れ替えたりを行う。
フォルダごとに使用するバージョンを切り替えることも？出来るはず？出来るはず。**←TODO:後で調べる。**

## インストール
**はじめに**、npmとNode.jsはnvmでインストールするので、まずは**nvmをインストール**しましょう！

**nvm**インストール
[GitHub　nvm](https://)
インストール方法
アンインストール方法

**npm**インストール

* グローバルインストール
    * ```npm install --global ＜パッケージ名＞```
* ローカルインストール
    * ```npm install ＜パッケージ名＞```
    * オプション：パッケージ.jsonへ記載
        * --save
        * --save-dev 開発版として
Pythonでqiitaにログインしてみる

webスクレイピング入門としてqiitaへログインしてみました。
ログインボタンをクリックすると[https://qiita.com/login](https://qiita.com/login)に対して以下のデータを送信しているようです。

- utf-8：✓で固定
- authenticity_token：セッションを張った際に発行されると思われる：
- identity：メールアドレスかユーザID
- password：パスワード

ということでコード内で取得する必要があるのはauthenticity_tokenだけですね。覚えたてのBeautifulSoupを使って取得してみました。

```Python
def get_authenticity_token(session, login_url):
    response = session.get(login_url)
    response.encoding = response.apparent_encoding
    bs = BeautifulSoup(response.text, 'html.parser')
    authenticity_token = str(bs.find(attrs={'name':'authenticity_token'}).get('value'))
    return authenticity_token
```

実際にログインまで行うと以下のようになります。

```Python
import requests
import os
from bs4 import BeautifulSoup


user_name = 'user_name'
user_password = 'user_password'
login_url = 'https://qiita.com/login'


login_form = {
    'utf-8':'✓',
    'authenticity_token':'token',
    'identity':user_name,
    'password':user_password
}
    

def get_authenticity_token(session, login_url):
    response = session.get(login_url)
    response.encoding = response.apparent_encoding
    bs = BeautifulSoup(response.text, 'html.parser')
    authenticity_token = str(bs.find(attrs={'name':'authenticity_token'}).get('value'))
    return authenticity_token


if __name__ == '__main__':
    session = requests.Session()
    authenticity_token = get_authenticity_token(session, login_url)
    login_form['authenticity_token'] = authenticity_token
    session.post(login_url, login_form)
```
#PowerAutomate を使って iOS の 画像独自方式 HEIC を ノーコードで jpeg形式に変換する！

TLにこんなツイートがありました！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">iPhone で撮影した写真を OneDrive モバイルアプリでアップロードすると .heic で保存される仕様に変更になってから、PCで扱いづらくてホント困る。フリーソフト的なものはあまり入れたくない。</p>&mdash; TAICHI (@artbreak_taichi) <a href="https://twitter.com/artbreak_taichi/status/1215041892301164545?ref_src=twsrc%5Etfw">January 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# HEIC形式とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/026585c9-be55-2bb2-f79d-dc057771a64c.png)
[転載元：東京経済大学情報システム課：HEIC形式の画像ファイルをJPGに変換する方法](https://web.tku.ac.jp/iss/guide/classroom/tipspc/othersoft/heicjpg.html)

# 変換するにはどうすれば・・・

OneDriveのAPIに変換する機能があるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/42fe85b2-f762-4c58-5ef7-38ed7ebdf49a.png)

[OneDrive Developer:別の形式でファイルをダウンロードする](https://docs.microsoft.com/ja-jp/onedrive/developer/rest-api/api/driveitem_get_content_format?view=odsp-graph-online)

## ってことは Power Automateに・・・

やっぱりあったーーー！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e80baf6d-8ae0-73f7-b4b3-ff59b3984b87.png)

しかもJPG変換できるやーん！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/f781f897-98ef-5677-6de8-7f2b59197826.png)

これならノーコードで変換いけるね！！

# Power Automate フロー全体図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/fc5f0672-5a62-8119-f778-054bd59656d9.png)

## 条件判定について

OneDrive for Businessトリガーのファイルが作成されたときには
動的コンテンツとして、「ファイルパス」というのがあるんだが
どうもこれが、Base64でエンコードされた値が返ってくるようで、正しく判定してくれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/bc2d0dce-434c-e2ca-8451-a51e086cc930.png)

### 関数を使用してBase64を文字列に変換する

変換関数の「Base64ToString」を使用することで、引数に指定された動的コンテンツを
文字列に変換してくれるので、この関数を使おう！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/936ae665-245b-fa9f-9f41-038b6de2951d.png)


# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e4d2ff59-ebc0-c8a2-c832-8b0d2921de24.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e29b2ba6-08c0-44c8-a77c-710c3943743b.png)

正しく Heic形式をJpeg形式に ノーコードで変換することができました！！
【python】import文

#import文
pythonのライブライはオープンソースとなっており、世界各地でライブラリの開発が行われている。
ライブラリを使用することで様々なことがプログラミングで容易に実現することが出来る。

#宣言方法

**import ライブラリ名**
でライブラリをインポートすることが出来る。

多くの場合、あるプログラムを動かすのに必要なライブラリはコードの**先頭でまとめて**宣言される。
今回は例として、numpyとpandasをインポートしてみる。

```python:import.py
import pandas
import numpy
```

上の宣言をすることで、numpyおよびpandasで定義されている関数やオブジェクトを使用できるようになる。
このように複数のライブラリをインポートしたい場合は、複数のimport文が必要になる。

#pandasを使って内積計算
次にimportしたpandasのオブジェクトやメソッドを使うことを考える。
内積はnumpyのdot関数で定義されている。このdot関数はarray型変数を引数にとる。

```python:import.py
import numpy
a=numpy.array([1,2,3])
b=numpy.array([3,2,1])
c=numpy.dot(a,b)
print(c)
>>>10
```
仮に、上のコードでnumpyの箇所を全てpandasに変更して実行してみる。（エラーが出る）

```python:import.py
import pandas
a=pandas.array([1,2,3])
b=pandas.array([3,2,1])
c=pandas.dot(a,b)
print(c)
>>> AttributeError: module 'pandas' has no attribute 'dot'
```

このように'dot'に対して'not attribute'と警告のメッセージがでる。
これは'dot'という関数が、pandas上では定義されておらず、
numpy上で定義されていることを意味する。

この例からも使いたいメソッドや関数が定義されているライブラリを
インポートすることが大切であることがうかがえると思う。

#ライブラリのコード中での簡略化
**as**を使うことで、コード中でライブラリ名を簡略化することが出来る。
**import ライブラリ名 as 簡略化名**で宣言することが出来る。

よく使われるライブラリに対しては、簡略化名も統一される傾向にあり、
pandas→pd、numpy→np、scipy→spなどの省略を目にすることが多い。

```python:import.py
import numpy as np
a=np.array([1,2,3])
b=np.array([3,2,1])
c=np.dot(a,b)
print(c)
>>>10
```