OmniAICreator/Qiita-1.07M huggingface dataset:
Node-RED(enebular) を heroku で稼働させるときに、heroku を眠らせない(addons 無しで)

- 2019/01/22 タイトルを更新

## 知識材料 
- [enebular](https://www.enebular.com/)
- [Node-RED](https://nodered.org/)
- [heroku](https://www.heroku.com/)

## 前提条件
- enebular を heroku にデプロイしたい
- [enebular - Getting Started](https://docs.enebular.com/ja/GetStarted/) を体験済み
- [heroku Free プラン](https://jp.heroku.com/pricing)を使いたい

## 利用環境
- enebular 
- heroku
- 
## 今回のゴール
heroku 無料プランは

>30 分間何も操作が行われなかった場合はスリープ状態に移行

という制限があります。
世の中には、これを回避する方法が溢れていましたが、heroku にデプロイした Node-Red 自身が、簡単に回避策を実装出来そうなので試しました。

# スリープ検証
heroku にデプロイしたアプリケーションを放置すると、スリープするのかどうかを検証しました。検証には [heroku cli](https://devcenter.heroku.com/articles/heroku-cli) を使用します。

`heroku ps -a [アプリ名]` で、デプロイ済みアプリケーションの状況が確認できます。

アプリケーションが開始した時間と、今までの経過時間が表示されます。また、補助情報として heroku のログも見ておきます。
![実装前起動](https://dl.dropboxusercontent.com/s/4tn1p7ls0f9pnv4/190122-01_01.png)

３０分以上放置した後、再び `heroku ps` で、アプリケーションの状況を確認します。

![実装前スリープ](https://dl.dropboxusercontent.com/s/x7ecwtypivvgygu/190122-01_02.png)

放置後、約３０分でスリープ状態 [idle] になりました。

# 実践
## flow 作成
![AllView](https://dl.dropboxusercontent.com/s/yivrr0azj39ehds/190122-01_06.png)

heroku にデプロイした時にスリープしてほしくないフローの端に、上記赤枠のノードを配置し、接続します。

[inject] -> [http request] -> [(debug) 無くても可]

### [inject] ノード設定
「繰り返しフィールド」を、下記のように設定
- 指定した時間間隔
- 時間間隔 `15分`

![inject-node](https://dl.dropboxusercontent.com/s/tz2rpquut4kmq28/190122-01_07.png)

### [http request] ノード
`URL` フィールドに、heroku にデプロイしたアプリケーションの URL を指定します
![http-request-node](https://dl.dropboxusercontent.com/s/a15g6bq0fhdb4l0/190122-01_08.png)

## 実行と結果
【１】作成した flow を heroku にデプロイします。デプロイ後に `heroku ps` で、アプリケーションの動作状況を確認します。
![実装後起動](https://dl.dropboxusercontent.com/s/62egs2g10z8ul3z/190122-01_03.png)

【２】３０分以上放置した後、再び `heroku ps` で、アプリケーションの状況を確認します。

![実装後スリープ](https://dl.dropboxusercontent.com/s/88b4p8ofyn9xtb6/190122-01_04.png)

【３】３０分以上経過しても、スリープ状態 [idle] に遷移しませんでした。

![実装後スリープ２](https://dl.dropboxusercontent.com/s/8sq1b3t23ab8gvf/190122-01_05.png)

【４】４時間経過までは見届けました。

## まとめ
heroku addons を利用すればどんなアプリでもスリープ回避できますが、node-red だと自前でお手軽にスリープ回避できることを体験できました。ちょっと応用すれば、自前で死活監視もできるかと思います。
Mackerelをつかってみた

#Mackerelって？？
管理してるサーバをZabbixで監視しようと思いつつ面倒だと放っておいたら、「はてなブログ」でお馴染みのはてなさんが提供しているMackerelというサービスをみつけました。
https://mackerel.io


MackerelはSaaS型のサーバ監視サービスで、ホストにエージェントをインストールするだけで監視することができます。

Zabbixではデータの集約のためにZabbixサーバを構築しなければいけませんがMackerelではその必要がありません。
![Mackerel.png](https://qiita-image-store.s3.amazonaws.com/0/240869/51bce805-c896-448c-f1fd-66fe5010b964.png)


#使ってみた
##新規ホストの登録
新規ホストの登録から使っているOSを選びコマンドをコピペします。
エージェントの設定はこれだけで終了です。

![スクリーンショット 2019-01-22 15.52.43.png](https://qiita-image-store.s3.amazonaws.com/0/240869/88c4fd88-b51a-4650-3c81-16fd94853b46.png)

```sudo journalctl -u mackerel-agent.service```でログを確認できます。


```text
-- Logs begin at Sun 2019-01-20 15:49:05 JST, end at Tue 2019-01-22 18:19:43 JST. --
Jan 22 15:52:06 <hostname> systemd[1]: Starting mackerel.io agent...
Jan 22 15:52:06 <hostname> systemd[1]: Started mackerel.io agent.
Jan 22 15:52:06 <hostname> mackerel-agent[18506]: 2019/01/22 15:52:06 INFO <main> Starting mackerel-agent version:0.59.0, rev:d4781f5, apibase:https://api.mackerelio.com
Jan 22 15:52:14 <hostname> mackerel-agent[18506]: 2019/01/22 15:52:14 INFO <command> Start: apibase = https://api.mackerelio.com, hostName = <hostname>, hostID = <hostid>
```

##サービスを作成する
サービスを作成します。
DBサーバやWebサーバなど同じサービスで運用するものをまとめるものです。

##ロールを作成する
ロールを作成します。
要はタグのようなものでDBサーバや、Webサーバなどのタグ付け的なことができます。

##ホストとロールの紐づけ
Hostsタブをクリックして、ホストの```サービス/ロール```をクリックするとホストにロールを設定できます。

#感想
大学の講義が早く終わって少し暇だったのでやってみました。
30分くらいかかると思ったらものの10分くらいでできたのでよかったです。
自宅の仮想マシンにもじゃんじゃん入れてみます。
コマンドライン引数で与えられたファイルの中身をcinのように入力する(C++)

#はじめに
`in.txt`というファイルの中身を標準入力する場合，

```
$ ./a.out < in.txt
```
という風に実行すると思います．
しかし，コーディングテストサイトといったオンライン上の環境では

```
$ ./a.out in.txt
```
と実行方法が決められている事があり，この場合はファイル入力を扱う必要があります．

この実行方法でも，`cin`に近い方法で入力する方法を紹介します．

#コマンドライン引数について
`./a.out`の後ろの引数を扱うには，`args`, `argv`を使う必要があります．
main関数を以下のようにすると，使用できるようになります．

```c++
int main(int args, char *argv[])
```
例えば、以下のコマンドを実行した場合、

```
$ ./a.out 31 8 abc
```
`args`にはコマンドラインにある文字列の数である4、
`argv[0]`に"./a.out"、`argv[1]`に"31"、`argv[2]`に"8"、`argv[3]`に"abc"が入ります。
また，**`argv`の中身はそれぞれ文字列です**．

# 本題
コマンドライン引数(`argv[1]`)にファイル名が与えられるので，その中身を調べます．

```c++
#include <iostream>
#include <fstream>
using namespace std;

int main(int args, char *argv[]) {
    ifstream ifs(argv[1]);
    int x, y;
    ifs >> x >> y;
}
```
ファイル入力ストリームに目的のファイルをセットします．
すると，このように`cin`風の入力ができます．
`ifs`という文字を使っていますが，何でもいいです．

`operator >>`の継承元が同じなので，こんな風に書けます．

#おわりに
元々この記事では，以下の方法で`cin`を変える方法を紹介していました．

```c++
ifstream in(argv[1]);
cin.rdbuf(in.rdbuf());
```
しかし，`ifstream`を直接`cin`のように使用する方法を教えて頂き，
こちらの方が良い方法だと判断したので，記事を大幅に変えました．
（kazatsuyuさんありがとうございます！）

何か指摘等があれば，コメントで教えていただけると幸いです．
Lextm.SharpSnmpLib.Messaging.Messenger で取得する OctetString のEncoding指定

#はじめに
.NET Framework などで SNMP を扱うときに NuGet Packager として公開されている [Lextm.SharpSnmpLib](https://www.nuget.org/packages/Lextm.SharpSnmpLib/) を使用したりしますが、SharpSnmpLib では Walk や Get といったメソッドで取得する文字列値が文字化けしてしまうことがあります。エンコーディングを指定することができるので、その方法を投稿します。

#方法
Lextm.SharpSnmpLib.OctetString.DefaultEncoding （静的プロパティ）に、エンコーディング（[System.Text.Encoding](https://docs.microsoft.com/ja-jp/dotnet/api/system.text.encoding) オブジェクト） を代入します。

```C#:Example.cs
Lextm.SharpSnmpLib.OctetString.DefaultEncoding = System.Text.Encoding.GetEncoding(932); // SHIFT JIS で解釈させたいとき
```
Capybaraメモ

# Capybara メソッド一覧(抜粋)

## locatorとは(前提知識)

Capybaraにおける要素の指定は、「locator文字列」によって操作対象の要素を指定する。locatorにはidやnameやinnerHTML(タグ名)などを指定できる

- **locatorに指定できる値**
  - 対象の要素id属性の値
  - 対象の要素のname属性の値
  - 対象の要素のinnerHTMLの値
  - 対象の要素に対応する`<label>`の値(innerHTML)

**書式**

```ruby
check('locator')
click_link('locator')
find('locator')
first('locator')
```
※locator部分には「locatorに指定できる値」を記述する

**実例**

```ruby
check('#admin') # idがadminのチェックボックスにチェックする
click_link('New User') # New Userというラベルのリンクをクリック
find('div.actions input').click
# class属性actionsを持つ<div>タグ配下の<input>タグをクリック
first('tr td:nth-child(6)').click
# ページ全体で最初の<tr>タグ内の6番目の<td>タグをクリック
```

---

## 要素を操作するメソッド

| メソッド | 動作 |
|-------|-----|
|visit|ページへアクセスする(GETリクエスト)|
|check|チェックボックスをチェックする|
|uncheck|チェックボックスのチェックを外す|
|fill_in|テキストフォームに入力する|
|select|セレクトボックスを選択する|
|choose|ラジオボタンを選択する|
|attach_file|ファイルセレクタにファイルを設定する|
|click|クリックを実行する|
|click_button|ボタンをクリックする|
|click_link|リンクをクリックする|
|click_on|ボタンかリンクをクリックする|
|accept_alert|アラートのボタンをクリックする|

#### 記述例

```ruby
visit 'http://localhost:3000' # http://localhost:3000へアクセス
check('locator')
uncheck('locator')
fill_in('locator', with: 'hogehoge')　#　locatorにhogehogeという文字列を入力する
select('locator')
choose('locator')
attach_file('locator', 'Users/user/Desktop/local.png') # 絶対パスを記述
click('locator')
click_button('locator')
click_link('locator')
click_on('locator')
accept_alert # アラートを補足し、okボタンをクリックする
```

## 要素を検索する

|メソッド|動作|
|----|----|
|find|要素を検索する|
|find_by_id|idを検索する|
|all|要素を検索し、全件取得|
|first|最初に見つけた要素を取得|
|last|最後に見つけた要素を取得|

#### 記述例

```ruby
find('locator')
find_by_id('locator')
all('locator')
first('locator')
last('locator')
```

## 状態を確認する

|メソッド|動作|
|----|----|
|have_content|特定の文字列が表示されているか|
|have_button|特定のボタンを表示されているか|
|have_css|特定の要素があるかどうか|

#### 記述例
 
```ruby
have_content('locator')
have_button('locator')
have_css('selector')
```

## matcher

|メソッド|動作|
|----|----|
|expect()|期待する|
|to|〜であること|
|to_not|〜でないこと|
|not_to|to_notのエイリアス|

#### 記述例

```ruby
expect(page).to have_content 'hogehoge'
# 表示中のページに`hogehoge`という文字列が表示されているか検証

expect(page).to_not have_content 'piyopiyo'
# 表示中のページに`piyopiyo`という文字列が表示されていないか検証する。
```

## OmniAuth-Facebookログインを偽装する

```ruby
Rails.application.env_config['omniauth.auth'] = facebook_mock('tester')
```

Facebook公式へアクセスしなくてもFacebookアカウントでログインしている状態を実現するため、テストの時のみ使用する一時的なアカウントを作成する。
`facebook_mock('tester')`で`tester`という名前のアカウントを作成している。
ofxARKitをPGで扱うときに気を付けたいこと

[ofxARKit](https://github.com/sortofsleepy/ofxARKit) を触ってみた際よくやったこと備忘録

## Deployment Target

PGで作られるプロジェクトのデフォのターゲットはだいぶ古いので11以降にしましょう.

## Camera Privacy の設定

これは本家のREADMEにもPermissionsの項目がありますね.
PGでupdateするとInfo.plistを毎回書き換えてしまうからついつい忘れがち.
ここらへんはPGのレポジトリでkyleも[issue](https://github.com/openframeworks/projectGenerator/issues/149)立ててますがどうなるか.

## Shaders.metal を追加する

PGだと拡張子的に src/lib/Shaders.metal がプロジェクトに追加されないので手動で追加しましょう.
追加し忘れてても動くけど実行時にMetalな辺りで落ちます.
最初起きたときは結構な時間悩みました...
ついでに
* `Target Membership` にチェックが入ってるか
* `Type` が `Metal Shader Source` になってるか
も確認しときましょう.

----

もう少し何かあった気がするけど思い出したら追記します.
S3からのイベント通知をSNSで受け取り、SQSにイベント通知を送る実装をCDKでやったのでメモ

# 背景
あるS3バケットに作成されたというイベント通知を、staging用と本番用のSQSに通知を送りたい。が、S3のイベント通知は単一のSQSしか設定できないので複数SQSへの通知にはSNSをかませる必要がある。そこで、S3 -> SNS -> SQS のCDKでの基本実装についてメモ。

# 方針

### SNS -> SQS のCDKでの実装
- 公式ドキュメントのサンプルみればよき
  - [CDKのSNSのドキュメント](https://awslabs.github.io/aws-cdk/refs/_aws-cdk_aws-sns.html)
- S3 -> SNSへのイベント通知はコンソールで行う
  - [イベント通知設定の方法](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/enable-event-notifications.html)。

# S3 -> SNSへの通知設定で "Unable to validate the following destination configurations"で設定できない
S3 -> SNSへのイベント通知設定をコンソールで行おうとすると、"Unable to validate the following destination configurations"エラーが出て設定できなかった。どうやら、SNSのTopicにポリシー設定をする必要があったようだ。

- [AWS CloudFormation で S3 イベント通知を使用したときに発生するエラー、"Unable to validate the following destination configurations (以下の送信先設定を検証できません)" を避けるにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/unable-validate-destination-s3/)
- [S3 の put event を sns に流そうとした時の Permissions error の解決方法](https://qiita.com/rysk92/items/5e6d284db9152987d152)

## 実装

```ts

// Topic作成
const reportTopic = new sns.Topic(this, 'SomeTopic', {});

// Topicのポリシー作成
reportTopic.addToResourcePolicy(
  new PolicyStatement(PolicyStatementEffect.Allow)
    .addAction('sns:Publish')
    .addPrincipal(new iam.Anyone())
    .addResource(reportTopic.topicArn),
);

// SQS作成
const queue = new sqs.Queue(this, env + 'ReportEventQueue', {
  queueName: 'some-queue'
});

// Topic -> SQSの連携
reportTopic.subscribeQueue(queue);

// SQSのポリシー
new sqs.cloudformation.QueuePolicyResource(this, 'ReportEventQueuePolicy', {
  policyDocument: new iam.PolicyDocument().addStatement(
    new iam.PolicyStatement()
      .addPrincipal(new iam.Anyone())
      .addAction('SQS:SendMessage')
      .addResource(queue.queueArn),
      queues: [queue.queueUrl],
});
```
Serverless Frameworkでstage毎に外部ファイルから環境変数を参照させる

## はじめに

```
$ sls deploy --stage dev
```
と実行したら、dev用の環境変数を外部ファイルから参照させるようにしました。

調べたところいくつか方法はあったのですが、色々省略されていてわかりづらかったり、シンプルでなかったりでやりたいことが出来なかったので書くに至りました。

> 出来るだけ、省略せずに関数をcreateするところから書いてみました

## 環境

* AWS
* Serverless Framework
* Nodejs

## 1. 準備

```
// ディレクトリ作成
$ mkdir lamda-test

// 作業ディレクトリへ移動
$ cd lamda-test

// npm初期化
$ npm init

// serverlessをインストール
$ npm i serverless
```

## 2. Lambda関数を作成

> LambdaでRubyが使用出来るようになったので、Rubyを使用していきます。
以下のコマンドを実行することで、ランタイム（Lamda関数を定義する言語）にRuby、関数のパスを`hoge`として関数を作成出来ます。

```
$ sls create -t aws-ruby -p hoge
```

実行後

```
// 関数のディレクトリへ移動
$ cd hoge

// 作成されたファイルを確認
$ ls
// 結果：　handler.rb serverless.yml
```

`handler.rb`と`serverless.yml`が作成されます。


## 3. 環境変数定義用のディレクトリとファイルを作成する

現状のディレクトリ構成は、以下のようになるかと思います。


```
lambda-test
- hoge/
  - handler.rb
  - serverless.yml
- node_modules/
- package-lock.json
```


ここにさらにディレクトリとファイルを作成していきます。

`lambda-test`ディレクトリの直下に`env`ディレクトリを作成し、以下のような構造にします。

> 開発用を`dev`、本番用を`prod`のようにしてみました

階層は以下

```
lambda-test
- hoge/
  - handler.rb
  - serverless.yml
- node_modules/
- package-lock.json
- env/
  - dev.yml
  - prod.yml
```

`dev.yml`と`prod.yml`を編集します。

それぞれを以下のように編集します。

#### dev.yml

```yml
URL: https://dev.com
```

#### prod.yml

```yml
URL: https://prod.com
```

## 4. serverless.ymlを修正する

```yml
service: hoge

provider:
  name: aws
  runtime: ruby2.5

  stage: ${opt:stage, self:custom.defaultStage}
  region: ap-northeast-1

custom:
  defaultStage: dev
  environment:
    dev: ${file(../env/dev.yml)}
    prod: ${file(../env/prod.yml)}

functions:
  hello:
    handler: handler.hello
    environment: ${self:custom.environment.${self:provider.stage}}
```

要所を説明します。

* `${opt:stage}`とは、`sls deploy --stage　dev`のように`--stage`オプションで設定した値を使用することが出来ます。第二引数には何も設定されていない場合に使用する値を指定できます。

* `self:custom.defaultStage`で、以下の値を取得しています。

```
custom:
  defaultStage: dev # これ
```

* `${file(../env/dev.yml)}`という記述は相対パスでymlファイルを参照させています

## 5. Lambda関数内で環境変数を呼び出す方法

普段Rubyを書く人には慣れたように、以下のようにすれば参照出来ます。

```
ENV['URL']
```

## 6. 動作検証

動作検証のために、`handler.rb`を以下のように編集します。

```rb
require 'json'

def hello(event:, context:)
  #{ statusCode: 200, body: JSON.generate('Go Serverless v1.0! Your function executed successfully!') }
  puts ENV['URL']
end

```

保存し、コマンドを実行していきます。

```
$ sls invoke local -f hello --stage dev
// 結果：　https://dev.com
//      null

$ sls invoke local -f hello --stage prod
// 結果：　https://prod.com
//      null

// --stageオプション無しだと、devが呼ばれるようになっています。
$ sls invoke local -f hello
// 結果：　https://dev.com
//      null
```

と表示されるかと思います。
以上です。
【JavaScript】 個人的にアプリケーション開発で問題となるような言語仕様とlodashによる回避

## はじめに

JavaScriptはその歴史経緯から「それ言語の欠陥だろ！」的な問題が大きい言語だと思います。
個人的にほとんどのアプリケーション開発で問題となるような言語仕様とlodash（簡単だからね！）による回避策をまとめます。

※ 注意
自分の浅い経験のみから導いた記事だったためコメントにて補足していただきました。
JavaScriptはオブジェクト指向言語であるため、そのオブジェクトは参照を通して扱われるのは普通です。

## オブジェクト型が等しいことの判定

### 問題点

オブジェクト型（配列とオブジェクト）の中身が等しいかを判定したいとします。
`===` で判定しようとしてもうまくいきません。

```js
const a = [1, 2, 3]
const b = [1, 2, 3]
console.log(a === b) // false

const c = {name: 'Tom', job: 'Engineer'}
const d = {name: 'Tom', job: 'Engineer'}
console.log(c === d) // false
```

上記の場合、参照するメモリが同じかどうかを比較しているため中身が同じでも参照するメモリが異なる場合はfalseとなります。

### 解決方法

lodashを使うことで解決できます。
自作でも他のプラグインでも問題ないですが個人的には簡単で実績のあるlodashを使ってます。
npmでlodashをインストールした上で、

```js
import _ from lodash

const a = [1, 2, 3]
const b = [1, 2, 3]
console.log(_.isEqual(a, b)) // true

const c = {name: 'Tom', job: 'Engineer'}
const d = {name: 'Tom', job: 'Engineer'}
console.log(_.isEqual(c, d)) // true
```

`isEqual` メソッドを使うことでオブジェクト型の中身の比較をすることが出来ました。

## オブジェクト型のコピー

### 問題点

コピーをしたい時に単純に　`=` を使ってしまうと同じメモリを参照するため、コピー先を変更するとコピー元も更新されてしまう。いわゆる参照渡しの問題がある。
そのため、オブジェクト型をコピーする時は`Object.assign()` を使う。こうすることで値渡しになる。

```js
const defaultValue = {
  value: 'この値は書き換えたくない'
}

const newValue = defaultValue
newValue.value = '新しい値'

console.log(defaultValue) // { "value": "新しい値" }
console.log(newValue) // { "value": "新しい値" }
```

```js
const defaultValue = {
  value: 'この値は書き換えたくない'
}

const newValue = Object.assign({}, defaultValue)
newValue.value = '新しい値'

console.log(defaultValue) // { "value": "この値は書き換えたくない" }
console.log(newValue) // { "value": "新しい値" }
```

ただし、`Object.assign()` を使うとオブジェクトがネストするような場合にネストしたオブジェクトが参照渡しになってしまうという問題がある。個人的にはこれは謎仕様である。

```js
const defaultValue = {
  value: 'この値は書き換えたくない',
  nestValue: {
    value: 'この値は書き換えたくない'
  }
}

const newValue = Object.assign({}, defaultValue)
newValue.nestValue.value = '新しい値'
newValue.value = '新しい値'

console.log(defaultValue) // { "value": "この値は書き換えたくない", "nestValue": { "value": "新しい値" } }
console.log(newValue) // { "value": "新しい値", "nestValue": { "value": "新しい値" } }
```
`Object.assign()`を使ってもコピー元の中のオブジェクトの値が書き換わってしまう。

### 解決方法

この問題もlodashが解決してくれる。
npmでlodashをインストールした上で、

```js
const defaultValue = {
  value: 'この値は書き換えたくない',
  nestValue: {
    value: 'この値は書き換えたくない'
  }
}

const newValue = _.cloneDeep(defaultValue)
newValue.nestValue.value = '新しい値'
newValue.value = '新しい値'

console.log(defaultValue) // { "value": "この値は書き換えたくない", "nestValue": { "value": "この値は書き換えたくない" } }
console.log(newValue) // { "value": "新しい値", "nestValue": { "value": "新しい値" } }
```

`cloneDeep()`を使うことで、コピー元を残したままオブジェクト型のコピーが出来る。

## 結論

lodashを使おう！

[lodash.com](https://lodash.com/)
NGRXの一度のEffect内で複数回Actionを発生させたい

# 例題
`AAction`を拾う`AEffect`内で

- 「`BAction`」
- 「`Service`の`cFunc`を呼び出し及びその結果=`CAction`+エラーハンドラ`ErrorAction`」
- 「`DAction`」

を順番に呼び出したい。

# 解

```typescript
// import等は省略
// ActionTypes等は別途定義済とする

@Injectable()
export class MyEffect {
  constructor(
    private readonly actions$: Actions,
    private readonly service: Service,
  ) {}

  @Effect()
  aEffect$: Observable<Action> = this.actions$.pipe(
    ofType<AAction>(ActionTypes.AAction),
    switchMap(() =>
      concat(
        of(new BAction({})),
        this.service.cFunc().pipe(
          map(({ result }) => new CAction({ result })),
          catchError(error => of(new ErrorAction({ error }))),
        ),
        of(new DAction({})),
      ),
    ),
  );
}
```

[switchMap](https://rxjs-dev.firebaseapp.com/api/operators/switchMap)からの[concat](https://rxjs-dev.firebaseapp.com/api/index/function/concat)で順番保証しつつ、[of](https://rxjs-dev.firebaseapp.com/api/index/function/of)やら[pipe](https://rxjs-dev.firebaseapp.com/api/index/function/pipe)からの[map](https://rxjs-dev.firebaseapp.com/api/operators/map)および[catchError](https://rxjs-dev.firebaseapp.com/api/operators/catchError)で複数回`Action`を呼び出しています。

スマートではないけど、動いていてはいる。

順番にこだわらない場合は[merge](https://rxjs-dev.firebaseapp.com/api/index/function/merge)でもいけると思う。
SVGの図形を拡大した際にストロークまで太くなってしまうのを防ぐ

## 概要

tranfrom属性のscaleを使って図表を拡大した際に、図形のストロークまで太くなってしまうのを防ぐ。

エレメントの「vector-effect」属性に「non-scaling-stroke」を指定する。

### 例

```html
<svg>
  <g transform="scale(3)">
    <circle cx="60" cy="60" r="50" fill="#ffcccc"  stroke="black"></circle>
    <circle cx="180" cy="60" r="50" fill="#ccccff" stroke="black" vector-effect="non-scaling-stroke"></circle>
  </g>
</svg>
```


### 実行結果

<img width="377" alt="Create a new fiddle - JSFiddle 2019-01-22 17-39-28.png" src="https://qiita-image-store.s3.amazonaws.com/0/2832/11690cb0-b942-9b13-ddb4-5d2c2ff52f88.png" style="border:1px solid black">


### 何に使うのか

D3でパン・ズーム実装していると必要になることが多い。
馬鹿の一つ覚え: Pythonでプロセス間通信

# Pythonでプロセス間通信(IPC)を行うサーバ側とクライアント側のプログラム

## サーバ側にアクセスされるたびにインクリメントされた整数値を16進数の文字列として返す

#### サーバ側
```Python
#!/usr/bin/env python

import sys
from socket import socket, AF_INET, SOCK_STREAM

host = 'localhost'    # 同一ホスト間での通信
port = 57923    # サーバ側の受信ポート番号
port_min = 58111    # クライアント側の受信ポート番号の下限
port_max = 58999    # クライアント側の受信ポート番号の上限
max = 1024    # 通信文字列のサイズ
n_thread = 4    # スレッド数
number = 101    # 応答する数値の初期値

if len(sys.argv) > 1:
  number = int(sys.argv[1])    # 第1コマンド引数で数値の初期値を変更可

server_socket = socket(AF_INET, SOCK_STREAM)    # サーバ側受信用
server_socket.bind((host, port))
server_socket.listen(n_thread)
print("Server socket is ready.")

while True:
  try:
    (client_socket, address) = server_socket.accept()    # サーバ側受信
    message = client_socket.recv(max).decode('utf-8')    # 文字列を受信
    client_socket.close()
    print(message)
    port = int(message)    # 文字列がクライアントに返信する際のポート番号
    if port_min <= port <= port_max:
      socket_send = socket(AF_INET, SOCK_STREAM)    # サーバ側送信用
      socket_send.connect((host, port))
      message = '{:06x}'.format(number)    # 6桁の16進整数
      socket_send.send(message.encode('utf-8'))
      socket_send.close()
      number += 1    # 数値をインクリメント
      continue
  except:
    sys.stderr.write("Error 31\n")

server_socket.close()
print('Server socket is closed.')
```

#### クライアント側
```Python
#!/usr/bin/env python

import sys
import random
from socket import socket, AF_INET, SOCK_STREAM

host = 'localhost'    # 同一ホスト間での通信
port = 57923    # サーバ側の受信ポート番号
port_min = 58111    # クライアント側の受信ポート番号の下限
port_max = 58999    # クライアント側の受信ポート番号の上限
max = 1024    # 通信文字列のサイズ
n_thread = 4    # スレッド数

socket_send = socket(AF_INET, SOCK_STREAM)    # クライアント側送信用
socket_send.connect((host, port))
socket_recv = socket(AF_INET, SOCK_STREAM)    # クライアント側受信用
while True:
  port = random.randint(port_min, port_max)    # 受信ポートの番号を作成
  try:
    socket_recv.bind((host, port))
    socket_recv.listen(n_thread)
    break
  except:    # 失敗したらポート番号の作成からやり直す
    sys.stderr.write('Error 41: port ' + port + "\n")
socket_send.send(str(port).encode('utf-8'))	# サーバ側に受信用ポート番号を伝えて採番を依頼
socket_send.close()
while True:
  try:
    (socket_prvd, address) = socket_recv.accept()	# 採番結果
    message = socket_prvd.recv(max).decode('utf-8')	# 文字列で取得
    socket_prvd.close()
    socket_recv.close()
    sys.stderr.write(message + "\n")	# プロセス間通信で取得した文字列を表示
    break
  except:
    sys.stderr.write("Error 42\n")
```
EC2+Docker+Jupyterの初期設定

# はじめに
EC2上にDockerをインストールして、そこでJupyter開発環境を立てます。

# EC2の初期設定
まず新しくEC2インスタンスを作成します。最初にインスタンスを立てると、キーペアが発行されるので、そのpemファイルのあるディレクトリに移動します。
```cd path
```

次に、アクセス権限を設定します。
```chmod 400 [KeyPair名].pem
```

ここで初めて、最初に立てたインスタンスに接続します。
```ssh -i [KeyPair名].pem ec2-user@[PUBLIC DNS NAME]
```
この[PUBLIC DNS NAME]はec2-\*\*-\*\*-\*\*-***.ap-northeast-1.compute.amazonaws.comのような形をしています。また、接続の途中でなにやら質問されますが、"yes"と答えましょう。こうして無事サーバーに入れるはずです。

# EC2インスタンス上でのDockerインストール
立てたEC2インスタンス上でDockerをインストールします。この辺は、なにをやっているかわからなくてもとりあえず実行しておけばいいでしょう。まず、パッケージのアップデートをしておきます。
```sudo yum update -y
```
次にDockerをインストールします。
```sudo yum install -y docker
```
無事Dockerがインストールされたら、以下のコマンドで開始します。
```sudo service docker start
```
いちいち"sudo service"と頭につけるのは面倒なので、[ここ](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-basics.html)を参考に"docker ..."で済むようにしておきましょう。

# EC2上へのDockerイメージをダウンロード
Dockerがインストールできたら既製のイメージをダウンロードします。今回はJupyter notebookの環境構築をするので、それに見合ったイメージをダウンロードします。本格的なのは[datascience-notebook](https://hub.docker.com/r/jupyter/datascience-notebook/)ですが、重いです。手軽なのは[base-notebook](https://hub.docker.com/r/jupyter/base-notebook/)です。何れにせよ、以下のコマンドでダウンロードできます。もちろんこれは、インスタンス上で実行します。
```docker pull base-notebook
```
以下のコマンドで、ちゃんとダウンロードできたか確認できます。
```docker images
```

# EC2上のDockerコンテナへのローカルからのアクセス
その上で、このイメージからコンテナを作成します。
```docker run -it -p [EC2のポート番号]:8888 base-notebook
```
そうするとbashに入るので、そこで以下を実行します。
```jupyter notebook
```
最後にインスタンスのセキュリティグループを設定します。先ほど指定したEC2のポート番号をHTTPか何かで解放しましょう。

ローカルのブラウザから[インスタンスのグローバルIP]:[EC2ポート]に接続できればOKです。インスタンスのグローバルIPはec2-\*\*-*\*-*\*-*\*-**************.ap-northeast-1.compute.amazonaws.comのようなものです。パスワードについては、ターミナル上で"token=\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*"のような形でどこかに載っているので、それをコピペしましょう。

# 参考URL
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-basics.html
https://wisteriasec.wordpress.com/2017/03/11/ec2docker%E3%81%A7jupyter-notebook%E3%82%92%E5%8B%95%E3%81%8B%E3%81%99-part2/
light GBMでimportanceを出す

lightGBMの使い方についての記事はたくさんあるんですが、importanceを出す手順が書かれているものがあまりないようだったので、自分用メモを兼ねて書いておきます。

lightgbm.train()で学習した場合とlightGBMClassifier()でモデルを定義してからfitメソッドで学習した場合でimportanceのある場所と呼び方が変わっちゃうのでちょっとややこしいですね。

## 試行環境
- Windows 10 64bit
- Python 3.6.6
- lightgbm 2.2.2
- jupyter notebook

## lightgbm.train()を使う場合

```
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split

# Iris データセットを読み込む
iris = datasets.load_iris()
X, y = iris.data, iris.target

# 学習データとテストデータを分ける
X_train, X_test, y_train, y_test = train_test_split(X, y)

# データを格納する
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)

# 学習条件を設定
params = {'task': 'train',
          'boosting_type': 'gbdt',
          'objective': 'multiclass',
          'metric': {'multi_logloss'},
          'num_class': 3,
          'learning_rate': 0.02,
          'num_leaves': 23,
          'min_data_in_leaf': 1,
          'num_iteration': 1000,
          'verbose': 0}

# 学習する
model = lgb.train(params,
                  lgb_train,
                  num_boost_round=50,
                  valid_sets=lgb_eval,
                  early_stopping_rounds=20)

# テストデータで予測する
y_pred = model.predict(X_test, num_iteration=model.best_iteration)
y_pred_max = np.argmax(y_pred, axis=1)

# Accuracy を計算する
accuracy = sum(y_test == y_pred_max) / len(y_test)
print('accuracy:', accuracy)

# importanceを表示する
importance = pd.DataFrame(model.feature_importance(), index=iris.feature_names, columns=['importance'])
display(importance)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/93f0897e-2716-57c3-683b-9b8f46d654ba.png)


## lightGBMClassifier()を使う場合

```
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split

# Iris データセットを読み込む
iris = datasets.load_iris()
X, y = iris.data, iris.target

# 学習データとテストデータを分ける
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 学習条件を設定
model = lgb.LGBMClassifier(objective='multiclass',
                        num_leaves = 23,
                        learning_rate=0.1,
                        n_estimators=100)

# 学習する
result = model.fit(X_train, y_train,
                   eval_set=[(X_test, y_test)],
                   eval_metric='multi_logloss',
                   early_stopping_rounds=20)

# テストデータで予測する
y_pred = model.predict(X_test, num_iteration=result.best_iteration_)

# Accuracy を計算する
accuracy = sum(y_test == y_pred) / len(y_test)
print()
print('accuracy:', accuracy)

# importanceを表示する
importance = pd.DataFrame(model.feature_importances_, index=iris.feature_names, columns=['importance'])
display(importance)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/5453e2bc-50dc-2235-61f6-fc158be11879.png)
OneToMany データ更新(Update)

# はじめに
OneToManyの関係のテーブルにデータを更新(Update)する。
「[OneToMany データ取得(Select)](https://qiita.com/ma33588/items/15ffe20b558ee5b4e507)」の続き。

# データ更新(Update)
## Controllerよりアクセス
ControllerからRepository経由でアクセス

```php:app/Customize/Controller/SamplePageController.php
/**
 * @Route("/sample/{id}", name="sample_index")
 * @Template("Sample/index.twig")
 */
public function index($id)
{
    $product = $this->productRepository->find($id);
    dump($product);

    $comments = $product->getProductComments();
    if (!$comments->isEmpty()) {
        $keys = $comments->getKeys();
        foreach ($keys as $key) {
            $comment = $comments->get($key);
            $comment->setComment(date("Y/m/d H:i:s")."=\r\n".$comment->getComment());
        }
        $this->entityManager->persist($product);
        $this->entityManager->flush();
    } else {
    }
}
```


## ブラウザよりアクセス
/sample/1 でdtb_product_commentのデータを更新できた。


#まとめ
find()して値を設定してpersist()してflush()

#参照
[OneToMany データ取得(Select)](https://qiita.com/ma33588/items/15ffe20b558ee5b4e507)
PHPのハマりポイントのリンク集

PHPのハマり情報のまとめです。主に罠な仕様、予想外の振る舞い、ドキュメントに詳しくは書いてない振る舞いについての情報をまとめていきます。ここに載ってない情報があればぜひとも教えて下さい。頂いた情報をもとに随時更新していきます。

* [PHPは引数が足りないときはエラーになるが、引数が多いぶんには何も言わない - Qiita](https://qiita.com/suin/items/cffe65aed89935572016)
* [PHPはときどき掛け算ができない - Qiita](https://qiita.com/takepan/items/47c61aedd017b14bc61e)
* [PHPのDateTime::ISO8601はISO8601ではない - Qiita](https://qiita.com/hogesuke_1/items/6d887c5669adeb1d1b08)
* [SplFileObjectのREAD_AHEAD, SKIP_EMPTY, DROP_NEW_LINEはPHPのバージョンによって挙動がバラバラな件 - Qiita](https://qiita.com/suin/items/5f2322d2762d7d1677bb)
* [PHP: iterable型はiterator_to_array()に渡しちゃいけない - Qiita](https://qiita.com/suin/items/5f76a3eeaca70a5c3ba8)
* [PHPの正規表現で^$より\A\zがいい理由 - Qiita](https://qiita.com/suin/items/2b9376ddd14a7fb40759)
* [PHP:文字列が整数かの検証にはis_numeric, ctype_digit, filter_varどれが適切か？ - Qiita](https://qiita.com/suin/items/988e29f71a74456fd42f)
* [PHP: trait由来の静的プロパティはミックスインした時点の値で束縛される - Qiita](https://qiita.com/suin/items/b4ef9f182f32c92a8436)
* [PHP「1...10 === '10.1' は true」僕「えっ──！？」 - Qiita](https://qiita.com/suin/items/c008b7da90a4750835da)
* `empty(0)`は`true` - [PHP isset, empty, is_null の違い早見表 - Qiita](https://qiita.com/shinichi-takii/items/00aed26f96cf6bb3fe62)
* [PHPのforeachで参照渡しを使ったときの落とし穴 - Qiita](https://qiita.com/ttskch/items/c6d8ea00c57640c52cd8)
* [[PHP] ファイルオープンモードに関するマニュアルの記述は間違っている - Qiita](https://qiita.com/mpyw/items/3adcec3c66e515895b08)
* [DateTime::createFromFormatの!と|はUnixエポックにはリセットしない - Qiita](https://qiita.com/crhg/items/2ba25210461dfe8d2f83)
* [PHPのquotemetaは空文字列に対してfalseを返す - Qiita](https://qiita.com/crhg/items/b06e862951e18418e5ec)
* [自分自身から__callStaticを呼び出したい - Qiita](https://qiita.com/rana_kualu/items/d6e96d073fbb95692afe)
* [PHP: PDOStatement::fetchは途中でMySQLサーバが落ちたとしても静かに処理を中断してしまう - Qiita](https://qiita.com/suin/items/0f56a4088b490312795d)
* [PHP: callable型の引数に、privateメソッドを渡すことができたり、できなかったりする - Qiita](https://qiita.com/suin/items/652c833ca29c2e05c553)
* [PHPではネストした三項演算子は左から評価される - Qiita](https://qiita.com/suin/items/fb5f21f8d1a75542bd8e)
* (クラスにプロパティの)[定義が無いのに代入できるって怖くね？ - Qiita](https://qiita.com/kamawanu/items/bab1fc9cd66247cc6070)
* [switch文の比較、JavaScriptは'==='、PHPは’==’ - Qiita](https://qiita.com/ryoo_ss/items/b5e6e08409c328d7a1d0)
【Rails】enumとは？メリット、使い方、カラムの追加方法について

## enum(列挙型)とは？
読み方は「イーナム」。
DBにんはint型やboolen型で保存をし、使うときに文字列として使うことができる型。
model上で数値と文字列を定義すると、数字と対応した文字列を取り出すことができる。

## どういうときに使用するか？
あるインスタンス(@userや@item)において、その状態を管理したいとき。
たとえば、あるユーザーが**入金前、入金確認中、入金完了など状態の変化**をするとき。
入金前を0、入金前を1、入金前を2とすることで、表現することができる。


## enum型を使用するメリットは？
- 数字として管理することで、　静的なオブジェクトとして扱うことができ、安全性を高めることができる。
- 状態を管理するとき、メソッドを使うことができる。
- 文字列が変わったとしても数字で管理しているので、改修が簡単になる。

## デメリット
- mysql側から見ると数値で保存されてしまうため、**マジックナンバー**が増える

### マジックナンバーとは？
0が未処理、1が処理中、2が処理済みだったとして、ある数字が意味を持つ(1は数字ではなく未処中という意味)


## 実際にコードを見る

model/item.rb

```rb
class Item < ApplicationRecord
  enum l_category_id: [['---',""], ['レディース', 1], ['メンズ', 2],['ベビー・キッズ', 3]]
end
```


new.html.erb

```rb
= f.select :l_category_id, Item.l_category_ids.keys, {}, class: "select-default"
```


↓

コンパイルされたhtml

```html
<select class="select-default" name="item[l_category_id]" id="item_l_category_id"><option>---</option>
<option value="レディース">レディース</option>
<option value="メンズ">メンズ</option>
<option value="ベビー・キッズ">ベビー・キッズ</option>
```



## dbはint型としてカラムに保存する
```rb
class AddStatusToItems < ActiveRecord::Migration[5.0]
  def change
    add_column :items, :status, :integer, null:false
  end
end

```
Oracleネタ帳 UNDO表領域についていろいろ

# UNDO 表領域の使用率

計算式は `UNDO 表領域の使用率 = (ACTIVE + UNEXPIRED のエクステントサイズ) / UNDO 表領域全体のサイズ` です。

以下のSQLで確認できます。

``` sql
select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') "TIME",
       round("USED_SIZE(MB)", 3) "USED(MB)",
       round("TBS_SIZE(MB)", 3)  "TBS(MB)",
       round("USED_SIZE(MB)"/"TBS_SIZE(MB)" * 100, 3) "USAGE(%)"
  from (select sum(BYTES)/1024/1024 "USED_SIZE(MB)"
          from DBA_UNDO_EXTENTS
         where STATUS in ('ACTIVE', 'UNEXPIRED')
           and TABLESPACE_NAME = 'UNDOTBS1') ,
       (select sum(BYTES)/1024/1024 "TBS_SIZE(MB)"
          from DBA_DATA_FILES
         where TABLESPACE_NAME = 'UNDOTBS1') ;
```
WSLでAzure CLIを試してみる

WSL上のUbuntu 18.04でAzure CLIを試してみる。  

基本は[公式の手順](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-apt?view=azure-cli-latest)をベースに作業を行ったが、apt-keyがうまく動作しなかったので、ここに記す。

# 事前準備

WSLのUbuntuがインストールされていること

# ソースリストのインストール

```
sudo apt-get install apt-transport-https lsb-release software-properties-common -y
AZ_REPO=$(lsb_release -cs)
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | \
    sudo tee /etc/apt/sources.list.d/azure-cli.list
```

# Microsoftの署名キーのインストール

この作業でapt-keyコマンドで正しくインストールできなかったので、直接パッケージをインストールした

```
curl -OL http://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
```

# Azure CLIのインストール

```
sudo apt update
sudo apt install azure-cli
```

# Azureのログインの確認

```
az login
```
ニューラルネットワーク(AI)はプラレール新幹線をどれだけ分類できるのか Part.3

- 前回の「[Part2](https://qiita.com/ichigoryume/items/cea541924eb5d819d94c)]」では、すこし難しい画像を1000枚ほど追加することで、正解率が91%程度の難易度に問題を調整した。
- 今回は、ネットワークに隠れ層を追加し、正解率がどう変化するか実験する。

#実験１： 隠れ層を1層追加
- 隠れ層を1層追加することの効果を測る
- またそのニューロン数の違いが結果にどう影響するかを測る
- 追加する隠れ層のニューロン数は32, 128, 512の3種類

## 結果
- 横軸をエポック数、縦軸を正解率(1=100%)として、正解率の推移を比較
- 隠れ層０のグラフは前回の隠れ層無しの実験データ

![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190122/20190122141327.png)

## 考察
- 隠れ層を追加したネットワークはいずれも正解率が向上し、また収束に必要なエポック数は低下しており、隠れ層の効果が見て取れる。
- 但し、計測はしなかったが隠れ層のニューロン数を増やすほど計算時間は増加する傾向。ニューロン数512では隠れ層無しと比べて体感で数倍遅い。
- 正解率の観点でみると
    - ニューロン数128および512が高く、512では最大99%、128では100%に到達した。
    - 128のほうが結果がよいため、やみくもにニューロン数を増やせばよい、ということではないようだ。
- エポック数の観点でみると
    - 128と512が優秀。すばやく収束している。
    - 但し、実行速度を考慮すると128の方がすばやく収束したと思う。
- 以上、まとめると
    - 隠れ層を１つ追加するだけで正解率は向上する
    - 但し、そのニューロン数は多すぎても少なすぎてもよい結果が得られない。適した数を実験から見極める必要がありそう。
    - ニューロン数を増やすほど実行速度が遅くなるため、なるべくニューロン数はふやしたくない。

# 実験２：隠れ層を2層追加
- 実験１で最も結果の良かった128ニューロンの隠れ層をもつネットワークに対して、さらに1層追加しそのニューロン数を変えながら認識率の推移を比較してみる。

## 結果
- 横軸をエポック数、縦軸を正解率(1=100%)として、正解率の推移を比較
- 128-０のグラフは実験１の128ニューロンのもの

![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190122/20190122145643.png)

##考察
- 正解率でみると
    - 最終的にもっともよかったものは128-0。
    - 層を追加したものはすべて正解率がさがっている。
    - 第2層のニューロン数の差は結果にあまり影響はなさそう。
- エポック数でみると
    - 隠れ層を2層にしたもののほうが速いが、劇的によくなったというわけではなさそう。
    - 第2層のニューロン数の違いはあまり結果に影響していない模様。
- 以上、まとめると
    - 単純に層を増やせば結果がよくなるということではない。反対に結果がわるくなることがある。

# 隠れ層1、ニューロン数128が今回の問題ではベスト。またしても正解率100%に到達！
- やっぱり隠れ層は効果がある。使い方は要注意だけれども。
- CNNなどのディープラーニング手法が多くの隠れ層をもってないことと今回の実験結果は合致する。
Rails gem acts-as-taggable-onを使ってみた

#はじめに
この記事はRailsのgem acts-as-taggable-onを実践的に使ってみる記事です。
ですが、私自身まだまだなので至らないところもあるかもしれませんが、どうかよろしくお願いいたします。
準備などは軽く紹介する程度で使うことに重きを置いていきます。

#参考
[mbleigh/acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on)より詳しく書いてありますのでこちらを主に参照するといいと思います。
エラーなど私は出ませんでしたが、もしあればここも参考になると思います。

#準備

```ruby:Gemfile
gem 'acts-as-taggable-on', '~> 6.0'
```

```
bundle install
```

```
rails acts_as_taggable_on_engine:install:migrations
```

```
rake db:migrate
```


タグ機能を付加したいモデルファイルに記述しましょう。

```model.rb
acts_as_taggable
```

#応用
タグでの検索や似たタグの取得などの機能を実装したくなると思います。
それらを実装しようと思います。
まず検索から

##検索機能
ちなみにですが検索機能を作る際にはfrom_tagを使うようにしましょう。
こちらの記事を参照してください。

[【Rails】form_for/form_tagの違い・使い分けをまとめた - Qiita](https://qiita.com/shunsuke227ono/items/7accec12eef6d89b0aa9)

```ruby:search_controller.rb
#検索
#imageモデルにタグをつけている場合
#form_tagで:search_tagを送信。検索する文字列です。
#match_allは完全一致で検索
Image.tagged_with([params[:search_tag]], :match_all => true)...

#anyは部分一致で検索
Image.tagged_with([params[:search_tag]], :any => true)...

#excludeは検索対象を含まない検索
Image.tagged_with([params[:search_tag]], :exclude => true)...
```

##似たタグのデータ取得
この機能もよく見かけると思います。
簡単に作ってみました。
ある画像のページを開いた際にその画像についたタグと似たタグのついた
画像をいくつかランダムに取得しましょう。

```ruby:match_tag_controller.rb
#選択された画像のデータを取得。URLにIDを載せます。それを取得し表示
selected_image = Image.find_by("id = ?", params[:id])
#タグの一致検索
@match_tag_image =Image.tagged_with([selected_image.tag_list] :any => true)...
```

#最後に
自分が制作した際に使った機能を自分も忘れないようにメモ程度に書きましたが、
もし役に立てば幸いです。
他も方々も多く記事が出ていますので、そちらも参考にするとよりいいと思います。
ありがとうございました。
tensorflow.jsで7セグメントLED

#概要

tensorflow.jsで7セグメントLED、学習してみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/K/8/C/K8Cp.jpg?t=1548125407)

#モデルを作って、教師データを学習する。

dataset

```
const t_x = tf.tensor2d([
    [0, 0, 0, 0],
    [1, 0, 0, 0], 
    [0, 1, 0, 0],
    [1, 1, 0, 0], 
    [0, 0, 1, 0],
    [1, 0, 1, 0],
    [0, 1, 1, 0],
    [1, 1, 1, 0],
    [0, 0, 0, 1], 
    [1, 0, 0, 1]], [10, 4]);
const t_y = tf.tensor2d([
    [1, 1, 0, 1, 1, 1, 1], 
    [1, 1, 1, 1, 1, 1, 1],
    [0, 1, 0, 0, 1, 1, 1],
    [1, 1, 1, 1, 1, 0, 1],
    [1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 1, 1, 0], 
    [1, 0, 0, 1, 1, 1, 1], 
    [1, 0, 1, 1, 0, 1, 1],
    [0, 0, 0, 0, 1, 1, 0], 
    [0, 1, 1, 1, 1, 1, 1]], [10, 7]);
```


モデルは、入力4、出力7、全結合20、sigmoidの分類。
オプチマイザーは、adam
学習は、5000回
biasとweightをsaveする。

http://jsdo.it/ohisama1/oFyg

#学習したモデルを使ってデモ。

学習済みモデルを読み込む。

http://jsdo.it/ohisama1/uxM9

#tensorflow.jsを使わないでデモ。

biasとweightを使って、自前関数。

http://jsdo.it/ohisama1/K8Cp


以上。
TypeError: fs.existsSync is not a functionの対処法(強引な解決方法)

##環境
仮想環境のOS：Ubuntu
Electron 1.8.2
node v8.10.0

## 状況
ReactとElectronでのアプリ作ってる時に、自分が書いたプログラムに問題があるわけではなさそうなんだけど。。。
プログラムの中で、require('electron')すると、エラーが出た

```
TypeError: fs.existsSync is not a function
(anonymous function)
node_modules/electron/index.js:7
   4 | 
   5 | var pathFile = path.join(__dirname, 'path.txt');
   6 | 
>  7 | if (fs.existsSync(pathFile)) {
   8 |   module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'));
```

## 解決方法
こういう、「関数ではないよ」みたいな謎のエラーは他にもよく見たことあるけど、今回は特殊。Electron単体ではなくReactと組み合わせて開発してるので、fsモジュールは使えない。デスクトップアプリを作るとはいえweb感覚での開発なので、ファイルの入出力はできない。

なので、とりあえずコメントアウトする。

```javascript:index.js
var fs = require('fs')
var path = require('path')

var pathFile = path.join(__dirname, 'path.txt')
/*
if (fs.existsSync(pathFile)) {
  module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
  throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
}
*/
```

## 例
例えば、何かのAPIを使う上でアクセストークンが書かれたjsonファイルをfsモジュール使ってファイル取得しようとしても同じようなエラーが出るので、jsonファイル使わず直接文字列で指定して解決したこともありました。
もっと良い方法を知っている方いれば教えていただけると幸いです。

## 感想
Reactでfsモジュールは使えないってことを知れたのはかなりでかい。
ニューラルネットワーク(AI)はプラレール新幹線をどれだけ分類できるのか Part.1

- 勉強を兼ねて、実際にニューラルネットワークで多値分類をやってみたい！
- けどMNISTはもういいや、ほかの題材でやりたい！
- しかし、画像はどうやってあつめようか。撮影するっていっても枚数いるしなぁ・・・あ、iPhoneの連射機能つかえばいいじゃん！

というわけで、そのときたまたま目に入ってきた息子のプラレール新幹線を撮影して多値分類に挑戦。その過程でやったこと、わかったことを書いていきます。

# ５種類の新幹線で実験
![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190121/20190121185536.png)

- 左から
    - 500系
    - 700系
    - E5系（はやぶさ）
    - E6系（こまち）
    - E7系（かがやき）
- 手元にあったのがこの５車種だったので、これらを使うことにした。
- 新幹線以外のプラレールは新幹線と大きく形状がことなるので、問題としておもしろくないかな、と思い省いた。

# 計１０００枚ほど撮影
![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190121/20190121195019.png)

- iPhoneの連射（バースト）機能をつかって、車両の周囲と屋根部分をぐるっと撮影
- １車両ごとに２００枚程度撮影
- 背景を変えたり、レールに載せたり、カーブに合わせてまげたり、といった画像は今回は撮っていない。
- 多少手振れ画像になっていたり、自分の影が落ちていたりする画像があるが、気にせず使用

# 実験ではグレースケール画像を使用
![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190121/20190121193121.jpg)

- 新幹線はそれぞれ色がことなるのでカラー画像だと簡単すぎるかと思い、グレースケール画像にすることで形状によって分類できるかを実験することにした。

# まずはシンプルなネットワーク構造で実験

- 隠れ層無し、入力層と出力層のみ
 
```:tensorflow
f = tf.matmul(x, w) + b
p = tf.nn.softmax(f)
```

- 画像サイズは 504 x 378 ⇒ 入力層のノード数は190512
- wとbは0で初期化
- 誤差関数は交差エントロピー
- 確率的勾配下降法を使用。バッチ数は100。エポックは5000。学習時間は30分ほど。
- 用意した画像のうち、ランダムに選択した100枚をテスト用画像として、それ以外をトレーニング用画像として使用した。

# エポック1000で正解率93%！
-  シンプルなネットワークの割には高い数値じゃないだろうか・・・正直おどろいてしまった。
- エポックをさらに増やせば誤差の値はまだ下がりそう

![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190121/20190121195709.png)

# 判定ミスした画像は人間には簡単な画像
- 判定ミスした画像には各新幹線の特徴的な部分がうつってなかったのか？と思い確認してみると、そんなことはなく、人間には簡単に判定できる画像ばかりだった。そこが反対に面白いなと感じた。
- よく見ると自分の手などがうつりこんでいる。でもいいノイズだと思うので今後もこのまま使う。

![](https://cdn-ak.f.st-hatena.com/images/fotolife/i/ichigoryume/20190121/20190121195729.png)

# エポックを増やしたら正解率が100%に
- 誤差はまだ順調にさがりそうだったので、試しにエポックを10000にしてみたところ6100あたりで正解率100%になってしまった。ニューラルネットワークおそるべし・・・。
- おそらく問題が簡単すぎるのだろう。[次回は背景などを変えた画像をもっと増やすことにする。](https://qiita.com/ichigoryume/items/cea541924eb5d819d94c)
ButtonはtextAllCaps="false"しないとSpannableStringBuilderが適用されない

おもいっきりハマったのでメモ。

ButtonにSpannableStringBuilderを使って装飾したかったが、反映されなかった。

理由はこれ
[SpannableString on button not works for API21?](https://stackoverflow.com/questions/28778456/spannablestring-on-button-not-works-for-api21)

以下のように対応しました。
（該当の箇所に取り消し線を引きたかった）

```kotlin:ButtonExtension.kt
object ButtonExtension {
    @BindingAdapter("setStrike")
    @JvmStatic
    fun Button.setStrike(strikeText: String) {
        this.setAllCaps(false) // ← これがないと反映されない

        val spannableStringBuilder = SpannableStringBuilder(this.text)
        val start = this.text.indexOf(strikeText)
        val end = start + strikeText.length

        spannableStringBuilder.setSpan(StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

        this.text = spannableStringBuilder
    }
}
```

こうしておくと、XML側で

```lang:XML
<Button
//...
app:setStrike="hoge" />
```
と書くだけでOKです。
わざわざ ``textAllCaps="false"`` を書く必要はありません。
Ruby奇数番目の文字を取り出す

```
str = gets;
str.length.times{ |n| print str[n] if n.even? }
```

```
str = gets

str.each_char.with_index{|c, index|
  print c if index.even?
}
```

# 参考



- [rubyで言語処理100本ノック](https://gist.github.com/Madogiwa0124/3c388b8570052b9269fd6022beb7cc6e)
- [文字列を大文字にして奇数番目のみ出力する](http://sinyt.hateblo.jp/entry/2013/12/22/183217)

# 次にやること

[エンジニアが死滅シタ世界](https://paiza.jp/botchi/home)
をやる
amentからcolconに移行したときに依存関係で悩んだ話

せしまるです。

ros2 ardentからbouncyもしくはcrystalにバージョンアップした際に、ビルドシステムが変わりましたよね。

そう、amentからcolconに。
他の使ってる方は関係ないかも…。

私の環境では、amentで全ビルドできていたものをそのまんまcolconで全ビルドしようとしてコケました。

## 依存関係
問題としてはこれです。
自前のパッケージを他のパッケージで使用する場合に発生します。
amentの時はrclcppとかのros2のパッケージをpackage.xmlとかに書いておけば通ったのですが、colconでは自前のものもしっかりと書いておかないとダメ見たいです。

以下簡単に
使われる側

```xml:package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>marumaru</name>
  <version>0.1.0</version>
  <description>seshimaru package for ROS2</description>
  <maintainer email="xxxxxxx@xxxx.com">seshi maru</maintainer>
  <license>Apache License 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <build_depend>rclcpp</build_depend>

  <exec_depend>rclcpp</exec_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>
```

使う側

```xml:package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>hogehoge</name>
  <version>0.1.0</version>
  <description>seshimaru package for ROS2</description>
  <maintainer email="xxxxxxx@xxxx.com">seshi maru</maintainer>
  <license>Apache License 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <build_depend>rclcpp</build_depend>
  <build_depend>marumaru</build_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>marumaru</exec_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>
```

これがないとcolcon buildをかけたときに、marumaruがないよ！と言われてしまいます。
以下のコマンド実行してlocal_setup.bashを読み直せば通るけど多分間違った方法。

```console:console
// パッケージを指定してビルドするオプション.
$ colcon build --packages-select marumaru
$ source install/local_setup.bash
```

ちなみにpackage.xmlの記述についてはこんな感じ
書いてないタグも載せておきます。

|         記述          |                                説明                                           |
|:---------------------:|:----------------------------------------------------------------------------:|
|build_depend           |ビルドするときに必要なパッケージ                                                 |
|build_export_depend    |ライブラリをビルドするときに必要なパッケージ                                      |
|exec_depend            |生成した実行ファイルを実行するときに必要なパッケージ。これがないと実行時に落ちたりする|
|test_depend            |テストを実行するときに必要なパッケージ                                            |
|depend                 |上記のtestを除いた3種類を合わせたもの。別々で書くなら纏めたほうが簡潔になる          |
|build_type             |パッケージを処理するときに何を使って処理するかを指定する                            |

一番下のbuild_typeは人それぞれですかね。
ament使う場合やcatkin使う場合もありますし。
foundation-railsを6.3.1=>6.5.1でエラー時のめも

CSSフレームワークのFoundationを久しく上げていなかったので更新することに。
[公式のRelease Notes](https://github.com/zurb/foundation-rails/releases)を見ても特に破壊的な変更はなさそうだったので安心していたが、、、

```console
bundle update foundation-rails
```
して、[公式README](https://github.com/zurb/foundation-rails/blob/develop/README.md)の通りにGemfileに`autoprefixer-rails`を追加。

その後サービスを起動しようとしたら下記エラーに遭遇。

```console
% bundle exec rails s
...lib/active_support/dependencies.rb:292:in `require': cannot load such file -- sprockets/es6 (LoadError)
```

[issue](https://github.com/zurb/foundation-rails/issues/273)が上がっていたのでそのとおりに、Gemfileに`gem "sprockets-es6"`を追加したら無事起動。

```ruby:Gemfile
︙
gem "foundation-rails"
gem "autoprefixer-rails"
gem "sprockets-es6"
︙
```
よかったよかった
agora.io Dashboard RESTful APIの利用例

#概要
agora.ioではSDKの他に、ユーザーの入室制限や、チャネルの利用状況を確認できるDashboard RESTful APIがあります。
[公式ドキュメント(英文)](https://docs.agora.io/en/Video/dashboard_restful_communication?platform=All_Platforms)
システム組み込みにおいて利用頻度の高い機能をピックアップします。


#ソースコード
[Githubに公開しています](https://github.com/fu-jimoto/AgoraIO-Dashboard-RESTful-API)


#認証について
APIの認証はBasic認証で行います。ユーザー名,パスワードは[ダッシュボード上](https://dashboard.agora.io/restful)から取得できます。
![スクリーンショット_0031-01-22_15_22_51.png](https://qiita-image-store.s3.amazonaws.com/0/300377/384a76b9-a785-f5f2-76ee-284e6a9c4193.png)


#実装例
##基本設定

```php:config.php
<?php
$baseUrl  = "https://api.agora.io/dev/v1"; 
$userName = "USERNAME";
$password = "PASSWORD";
```

##ユーザーの入室制限

・Method:POST
・Path:BaseUrl/kicking-rule/
・Parameter:

```json
{
  "appid":"",   // 必須, project App ID
  "cname":"",   // オプション, チャネル名。
  "uid":"",     // オプション, JoinChannel時のuid。
  "ip":"",      // オプション, 接続元IPアドレス。
  "time": 60    // オプション, 制限期間。デフォルト60分で、設定可能時間は1〜1440分。 
  "privileges":["join_channel"]
}
```

実装例

```php:banUsers.php
<?php
require 'config.php';

$url = sprintf("%s/%s/",$baseUrl,"kicking-rule");

$data['appid'] = '';
$data['cname'] = 'demo';
$data['uid']   = '1000';
$data['time']  = '1440';

$jsonData = json_encode($data);

$ch = curl_init();
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERPWD, $userName . ":" . $password);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);

var_dump($result);
```

結果

```
{"status":"success","id":2177083}
```
チャネルに参加中であれば、APIをコールした時点で追い出しが発生します。


##チャネル利用状況

・Method: GET
・Path: BaseUrl/channel/user/
・Parameters: appid, cname

実装例

```php:getUserInChannel.php
<?php
require 'config.php';

$appId = "";
$cname = "demo";
$url = sprintf("%s/%s/%s/%s/%s",$baseUrl,"channel","user",$appId,$cname);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, $userName . ":" . $password);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
$result = curl_exec($ch);
curl_close($ch);

var_dump($result);
```


結果

```
{"success":true,"data":{"channel_exist":true,"mode":2,"broadcasters":[2461386049,3430352033],"audience":[],"audience_total":0}}
```




#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=ff945c246cfcec489948)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=ff945c246cfcec489948)
UIButtonの角丸をInterface Builderでやる方法

`layer.cornerRadius`, `layer.masksToBounds` を設定する。

![Screen Shot 2019-01-22 at 16.19.17.png](https://qiita-image-store.s3.amazonaws.com/0/27895/f0c022c2-c2bb-086e-1173-4b8072df30ac.png)
【初心者】OracleでLimit句が使えないんだね。【備忘録】

### OracleでLimit句が使えなかった。
- MYSQL では使えててさ、わたし、Limit句大好きだったんだ…。
- Oracle初心者は使えると思って叩いた。

```
select ID from DUMMY limit 10;
[結果]
行1でエラーが発生しました。:
SQLコマンドが正しく終了されていません。
```

は？エラーとか聞いてないし。Oracleでは **LIMIT句ってない** んですね。

### どうしても使いたかった。
だって、データ量が多すぎるけど中身なんだか知らなんだ…

### ROWNUM を使用するとそれっぽいことができるらしい…？
ROWNUM ってなに？
#### ROWNUM とは？
 - ROWNUM 疑似列
 - WHERE 条件に入れることでレコード数を制限できる。
 - **ORDER BY と WHERE に併用すると WHERE 条件が先に評価される。**
 ←（うん？？うううん？ソートして ROWNUM は別の方法になる…？）

### 実際に使ってみた。
```
select ID from DUMMY WHERE ROWNUM <= 10;
[結果]
ID
--------------
             1
             2
～ 略（10件データでてきた！！やった～）
```
できた！！

### ソートしてID大きい順に出したい。出したい。
order by を使用するときは 副問合せ をすると良いらしい。

```
SELECT ID FROM 
( SELECT ID FROM DUMMY ORDER BY ID DESC )
WHERE ROWNUM <= 10;
[結果]
ID
--------------
         99672
         99671
         99670
         99669
         99668
         99667
         99666
         99665
         99664
         99663
```
できた！

### まとめ
- Oracleでlimitみたいなことするには、ROWNUM 疑似列 を使用する。
- ソートするときは副問合せの中でソートする。
- limit 句のことは忘れる。そんなやつはじめから、いなかった。
ON句とWHERE句、結合条件と抽出条件



## 抽出は2箇所ある

すごいわかりやすい → [SQLの結合条件と抽出条件の解説をリライトした例：技術屋のためのドキュメント相談所：オルタナティブ・ブログ](http://blogs.itmedia.co.jp/doc-consul/2015/11/sql.html) 

- ON 結合前抽出
- WHERE 結合後抽出

抽出するところは、2箇所あるということ！

結合前に抽出、結合後に抽出

## ONの役割

ON句には「結合前抽出 条件」と「結合 条件」を記述することができるが、それぞれは全く別物であるということ！！

ONの役割：

- 結合 条件：それぞれのテーブルを「どのカラム同士で結合するか」を指定する
- 結合前抽出 条件：それぞれのテーブルから、「結合する前にどのようにデータを抽出するか(絞るか)」

ON って、結合前のそれぞれのテーブルの抽出の役割もあるのか！

## 参考文献

- [FROM句とWHERE句 - SQLer 生島勘富 の日記](http://d.hatena.ne.jp/Sikushima/20100612/1276311628)
- [OUTER JOINのONに書く条件とWHERE句に書く条件とでは、条件の意味合いが違うんだな - CAMUSのこくばん －クエリの板書所－](http://d.hatena.ne.jp/CAMUS/20070609/1181354100)
- [SQLの結合条件と抽出条件の解説をリライトした例：技術屋のためのドキュメント相談所：オルタナティブ・ブログ](http://blogs.itmedia.co.jp/doc-consul/2015/11/sql.html)
VueやNuxtでよく見る「@」と「~」といったのエイリアス

## はじめに

Vueでよく使うエイリアスに@と~がある。
違いや使い分けがあるのか調べたのでメモしておく。

このエイリアスはフレームワークが提供しているものではなく、webpackで設定しているものです。
そのため以下は、デフォルトのVueやNuxtにおけるデフォルトのwebpackの設定についてです。

## @と~で違いはない

結論として@と~で違いはない。
ただし注意点はある。

| エイリアス | ディレクトリ |
|-----|------|
| `~` or `@` | srcDir |
| `~~` or `@@` | rootDir　|

Vue CLIのデフォルトは `srcDir` と `rootDir` が異なる。
Nuxtのデフォルトでは `srcDir` と `rootDir` は同じ。


### 注意点

Vueテンプレート内で `assets` または `static` ディレクトリへのリンクを使う時は`~/assets/image.png` と使う。


[参考](https://ja.nuxtjs.org/guide/directory-structure#%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9-%E5%88%A5%E5%90%8D-)