OmniAICreator/Qiita-1.07M huggingface dataset:
phpでクラスと関数の名前がかぶった時の挙動｜バグの原因になるかも？

#経緯
オブジェクト指向を再入門中に以下のコードを書いていたところ
予想していた結果と違っていた。
自分的に忘れそうなのでメモします。

```php.php

class TestObject {
	public $subject;
	private $message = "オブジェクト";

	public function testobject() {
		echo $this->message;
	}
}

$instans = new TestObject();
$instans->testobject();

```

```実際の結果.php
オブジェクトオブジェクト
```


```予想していた結果.php
オブジェクト
```

#原因
~~色々と~~テストし、調査してみて結論としてはクラス名と関数名が
かぶっているときに発動する挙動でした。
[こちらの記事](http://d.hatena.ne.jp/heavenshell/20100825/1282744486)が参考になりました。

どうやらphp4のころはコンストラクタを指定するときに
クラス名と同じ名前の関数を定義していたらしい。

だからコンストラクタとして認識され2回出力されていたんですね。

そういえばphpstormからConvert constructor new styleなんてメッセージがでていて
最初「関数を一つしか定義しないとコンストラクタとして認識されるのか？」と思いました。

~~しかし、いろいろテストしているとどうもそうでもないらしい。~~
そこで以下のようにしてみると

```テスト１.php

class TestObject {
	public $subject;
	private $message = "オブジェクト";

	public function testobject() {
		echo $this->message;
	}
}

$instans = new TestObject();
//$instans->testobject();

```

```テスト1結果.php
オブジェクト
```

やはりコンストラクタとして認識されるっぽい。

しかし上記のソースを以下のように変えると

```関数を2つ定義した時.php
class Test_object {
	public $subject = "サブジェクト";
	private $message = "オブジェクト";

	public function test_object() {
		echo $this->message;
	}
	public function test_subject() {
		echo $this->subject;
	}

}

$instans = new Test_object();
$instans->test_object();
$instans->test_subject();
```

```関数を2つ定義した時ー結果.php
オブジェクトオブジェクトオブジェクト
```

２つあっても発動している。
「関数を一つしか定義しないとコンストラクタとして認識されるのか？」説は間違いと判明。

ここでもしやと思い「PHP クラス名　関数名　同じ」で検索して
[こちらの記事](http://d.hatena.ne.jp/heavenshell/20100825/1282744486)にたどり着きました。

```クラス名と関数名を違うものに設定.php
class Test_Object {
	public $subject = "サブジェクト";
	private $message = "メッセージ";

	public function testmessage() {
		echo $this->message;
	}
	
}

$instans = new Test_Object();
$instans->testmessage();
```

```クラス名と関数名を違うものに設定ー結果.php
メッセージ
```

やはり名前がかぶったことが原因のよう。。。
確認のため

```クラス名と関数名を同じに設定.php
class Test_Object {
	public $subject = "サブジェクト";
	private $message = "メッセージ";

	public function test_object() {
		echo $this->message;
	}
	
}

$instans = new Test_Object();
$instans->test_object();
```

```クラス名と関数名を同じに設定ー結果.php
メッセージメッセージ
```

#結論
phpでクラスと関数の名前がかぶった時にコンストラクタとして認識される。
[参考記事](http://d.hatena.ne.jp/heavenshell/20100825/1282744486)

また改めて検索してみて以下の記事も参考にさせていただきましたので張り付けておきます。
[関数名とクラス名が被っても大丈夫](https://qiita.com/ngyuki/items/c22efce043f025169b8c)
[__construct()があると、クラス名と同じメソッドはコンストラクタとはならないみたい](https://qiita.com/suin/items/48d84474c46142dc949a)

ちなみにphpのバージョンは5.6、7.0共に同じ挙動でした。
Windows10にNode.jsインストール

Windows10端末の中にNode.jsをインストールします。

#Windows環境
私のWindows10環境はVersion1703 64bitです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/53d50038-081d-bdd7-2d08-fcc8f4632286.png)

#手順
[ここ](https://nodejs.org/en/)にアクセスしてLTS版クリックして実行すると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/3833569c-1459-244e-366b-fd8677d6a5a2.png)
ウィザードが起動するので
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/e7662469-fcd5-a36f-54e5-9feda8c19923.png)
Next
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/d3104448-1ca2-a15d-86ab-ff4f24c42335.png)
Next
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/9fe46034-8615-93c8-d0a3-8b1bf174f791.png)
Next
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/5de43fe8-a20a-6ad5-6707-55d427d1309f.png)
Install
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/bb3318d8-cbb7-8b2f-91cf-90b87c6c2b93.png)
Finish
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/ebc93a19-edd9-c338-3548-acd505224bbd.png)

#確認
コマンドプロンプトでバージョン確認実行して正常にインストールされたこと確認します。

```:cmd.exe
>node-v
v8.9.4

>npm -v
5.6.0
```

できました。
ColdFusionをローカルアップデートする

# 概要

社内で需要があったので、ひとまずメモ記事に。

インターネットから切り離されているサーバーにColdFusionをインストールすると、アップデートサイトへ繋がらないためにWeb管理画面から更新ができません。
事前にインターネットアクセスできる環境で更新プログラム本体（JARファイル）をダウンロード＆手作業実行する方法で対処します。

# 手順

## 【１】ホットフィックスのダウンロード

アップデートサイトからホットフィックスファイル（JARファイル）をダウンロードします。

- ColdFusion 11 Updates  
https://helpx.adobe.com/coldfusion/kb/coldfusion-11-updates.html

「File: ColdFusion 11 Update XX」と書かれているリンクからダウンロードできます。（XXにはアップデート番号）
ファイル名は「hotfix_XX.jar」という名前になります。

```
※IEでダウンロードすると拡張子が「zip」（圧縮ファイル）になる場合があります。
拡張子をjarに変えておきます。
```

## 【２】所定の位置にコピー

ダウンロードした「hostfix_XX.jar」を下記のフォルダにコピーします。

```
C:\ColdFusion11\cfusion\hf-updates
```

## 【３】アップデートを実行

1. Winキー ＋ Rキーを押して、「ファイル名を指定して実行」を表示します。
1. 「cmd」と入力してEnterキーを押します。
1. 「C:\ColdFusion11\jre\bin\java.exe -jar C:\ColdFusion11\cfusion\hf-updates\hotfix_XX.jar」と入力してEnterキーを押します。  
![コマンド入力例](https://qiita-image-store.s3.amazonaws.com/0/3934/8573ca1a-b364-3d5b-96c7-a1012b408215.png)


暫くするとアップデートウィザード画面が立ち上がるので、指示にしたがって進めてください。
（基本OKボタンをクリックするだけで良いはず。）

# トラシュー

ありがちなエラーメッセージと対処法について。

## Error: Unable to access jarfile XXXXXX

JARファイルパスの入力間違いがあります。タイプミスがないか確認してもう一度入力してください。

## Error: Invalid or corrupt jarfile XXXXXX

JARファイルが壊れている可能性があります。もう一度ダウンロードしなおしてみてください。

## エラー: メイン・クラス XXXXXX が見つからなかったかロードできませんでした

"-jar" が抜けていませんか？
BookAnnie（自前で簡易AppAnnie）

嫁が小説を出した。電子書籍サイトで配信され、そのランキングをたまに眺めるようになった。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/236794/0dd7abfb-8d87-5dc7-8851-3adc9124a9ab.png)

[AppAnnie](https://www.appannie.com/)を[tableau](https://www.tableau.com/)で眺めるなど、スマートフォンアプリのランキングなどの推移を気軽に把握できるような感じで、この電子書籍のランキングも、自動取得してグラフで眺められたら知見になると思い、ツールを作った。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/236794/47951056-df67-d9f9-94aa-f42a95756f7d.png)

↑ランキングのグラフ表示はExcelのピボットチャートを利用し、毎日のランキングデータの取得はrubyで行う。

rubyのプログラミング。

open-uriとNokogiriで、ランキングのHTMLをスクレイピング。

```ruby
doc = Nokogiri::HTML.parse(open(uri), nil, "UTF-8")
doc.xpath('//div[@class="ranking_area"]').each do |node|
  rank = node.xpath('dl/dt[@class="hidden"]')
    .text.scan(/\d+/).first.to_i
  # ...
end
```

Excelのシートの最後の行以降に追加していく。

```ruby
lastrow = worksheet.Cells
  .SpecialCells(ExcelConst::XlCellTypeLastCell).Row
range = worksheet.Cells.Range("A#{lastrow + 1}")
```

このツールを、Windowsのタスクスケジューラに、毎日行うタスクとして登録しておく。これにて自動でランキングデータを取得し、Excelでいつでも閲覧できるようになった。

GitHubにあげておいた。

https://github.com/tomotochi/ruby-excel-bookannie
Kawaii SQL

あるSQL文をみていると```(`ID`)```という文字列がなんとなく可愛く見えてきた。

SQL構文を使って
顔文字がたくさんあるSQL文を作れないかと思ってやってみたが、
大したモノは作れなかった。

```SQL
CREATE TABLE IF NOT EXISTS           jn_ni 
(
                                     n_n
bigint
                                     (83) 
, PRIMARY KEY 
                                     (n_n)
);REPLACE INTO
                                     jn_ni 

                                     (n_n)
VALUES
                                     ('3')
,
                                     ('0')
;SELECT 
                                      n_n 
FROM 
                                     jn_ni
;
```
bxSlider でスライドを3つ表示して中央寄せする (レスポンシブ対応)

bxSlider はとても便利なのですがちょっと作り込もうと思うとやはりCSSなどで手を入れなくてはいけません。

特によく使われるであろう、画像を3つ表示させて両端の画像を切れさせるというようなことは標準ではできないです。

なので、CSSを使って実装する必要があります。

Codepenにデモを置いておきますのでコードと動作を確認して下さい。

<p data-height="265" data-theme-id="0" data-slug-hash="aqmaNK" data-default-tab="css,result" data-user="shingorow" data-embed-version="2" data-pen-title="Centering bxSlider (support Responsive)" class="codepen">See the Pen <a href="https://codepen.io/shingorow/pen/aqmaNK/">Centering bxSlider (support Responsive)</a> by Shingo Matsui (<a href="https://codepen.io/shingorow">@shingorow</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

こちらにもコードを掲載しておきます。

```sample.html
<div class="slider-wrapper">
  <div class="slider">
    <div class="slider-1 slide">
      <p>Slider 1</p>
    </div>
    <div class="slider-2 slide">
      <p>Slider 2</p>
    </div>
    <div class="slider-3 slide">
      <p>Slider 3</p>
    </div>
  </div>
</div>
```

```sample.css
body {
  margin: 0;
  padding: 0;
}
.slider-wrapper {
  overflow: hidden;
}

.slider {
  position: relative;
  left: 15vw; /* (100vw - SlideWidth) / 2 */ /* 20180210 変更 */
  overflow: visible !important;
}

.slide {
  width: 70vw !important;
  height: 150px;
}

.slide p {
  width: 80%;
  height: 200px;
  margin-left: auto;
  margin-right: auto;
  padding: 15px;
  background-color: #999;
  color: #EEE;
}

/* bxSlider */
.bx-wrapper {
  box-shadow: none;
  border: none;
  margin: 0;
}
```

```sample.js
$('.slider').bxSlider({
  auto: true
});
```

大きなポイントとしては

- スライダーの親要素で overflow:hidden
- スライダーを左に移動する。移動幅は ```(100vw - SlideWidth) / 2```

です。

これで、ウィンドウサイズを変えても画像が3つ表示されるようになります。

スライドの幅とスライダーの移動幅は SASS で変数と式を使うと変更の際に便利ですね。

それではまた。
PowerPointで写植

![image.png](https://qiita-image-store.s3.amazonaws.com/0/236794/5c8c3fa7-98c3-f547-5b73-1949f1dc0d36.png)

「マンガの原稿があがってきて、フキダシの中に活字を入れていく工程」

を写植（写植を貼る）と呼ぶらしい。

なぜか彼女が、その写植のお仕事を請け負っていた。具体的には「フキダシに番号を振って、フキダシと台詞の対応付けをする」というお仕事。

彼女は物書きであるのだが、なぜこうした作業を請け負わされるのかは謎。請け負った側にしてみると、おこづかい程度の額を上乗せ請求できるらしい。

ただ、ページ数の多くなる場合があって、大変そうだ。Webサイトで公開するマンガで「1ページで1コマ」の時などは、全体で数百ページにもおよぶ。

大量のjpgファイルを渡され、まとめてPDFとして納品しなければならない。

そこで、ツールを作った。

工程の全容は下記の通りなのだけど、

1. 高解像度の連番のjpgを、サイズ縮小して、PowerPointファイルに1ページに1つずつ埋め込む
2. フキダシに台詞の番号を振る
3. PDFとして保存

その中の1.の部分をツール化した。

プログラミング。

rubyで、PowerPointとImageMagickのOLEインスタンスを作る。

```ruby
require "win32ole"

ppt = WIN32OLE.new "PowerPoint.Application"
im = WIN32OLE.new "ImageMagickObject.MagickImage.1"

class PpConst; end
WIN32OLE.const_load(ppt, PpConst)
```

ImageMagickのconvertを呼ぶ。

```ruby
im.Convert("-resize", "640x640", pic, thumb)
```

PowerPointで画像を追加する。

```ruby
pre = ppt.Presentations.Add
slide = pre.Slides.Add(
    pre.Slides.Count + 1, PpConst::PpLayoutBlank)
slide.Shapes.AddPicture(thumb)
pre.SaveAs(pptfile)
pre.Close
ppt.Quit
```

GitHubにあげておいた。

https://github.com/tomotochi/ruby-powerpoint-photoalbum/
GTMで動画再生イベントを検知する


`ga.send` ならサクッと行けたのでなめてたら予想以上に苦戦したのでメモ。
バージョンアップによるUI変化も激しいのでノウハウ検索が結構しんどかった。

# やりたいこと
ページ内コンテンツの埋め込み動画（HTML5）の再生数をカウントしたい

# GTMを使うメリット（エンジニア視点）
- GTMタグのみ貼り付ければよい
- イベント検知やなんやらの部分をエンジニア側で管理しなくて済む
- マーケティング担当が（知識があれば）自分で直接いじれる

# 流れ
1.  動画再生イベントを検知するリスナを追加する
1. イベントの発火を検知するトリガーを追加する
1. トリガー発動時にGAへイベントを送信する

![gtm1.png](https://qiita-image-store.s3.amazonaws.com/0/107279/ea6225fd-2e1f-07c0-b679-44e8a2ca0d75.png)

## 動画再生イベントを検知するリスナを追加する
GTMでのイベントはグローバル変数 `dataLayer` に集約される
[参考] https://qiita.com/kat2n/items/d33c12fff2ba48ea766c
イベント発生時に `dataLayer` へ必要な情報を入れれば後はGTMで煮るなり焼くなりできるという仕様。

直接ページに組み込むとGA時代と変わらないので、GTMの管理画面からタグ＞カスタムHTMLでページ読み込み時に埋め込むことに。
ページロード時に登録し、最初の再生イベントだけを取りたいので発火後にリスナを削除するようにしています。

```html
<script>
$(function() {
  $('video').on('play', function() {
    dataLayer.push({
      event: 'PlayVideo',
    })
    $(this).off('play')
  })
})
</script>
```

![gtm2.png](https://qiita-image-store.s3.amazonaws.com/0/107279/a9422be6-351e-ff24-3975-aad70858807e.png)

## イベントの発火を検知するトリガーを追加する

`dataLayer` の変更はGTMがいい感じに検知してくれるので先ほど指定したイベントが発生時にトリガーを発動するように設定します。
トリガー＞カスタムイベントでイベント名を `PlayVideo` に設定。
![gtm3.png](https://qiita-image-store.s3.amazonaws.com/0/107279/b1c7f527-5c6e-563f-bc5e-e311d98edac1.png)

## トリガー発動時にGAへイベントを送信する
タグ＞従来のアナリティクスを作成して必要事項を入力。
再生されたページのURLはデフォルトで変数が用意されていたのでそれを利用。
トリガーは先ほど作ったトリガーを指定。

![gtm4.png](https://qiita-image-store.s3.amazonaws.com/0/107279/d52a06c9-a7c2-f9c7-2725-397c417865c5.png)

## 動作確認
プレビューモードにするとGTMを設定したページにプロファイラが表示されるのでそれを見ながらデバッグできます。
![gtm5.png](https://qiita-image-store.s3.amazonaws.com/0/107279/37b7604b-a4d3-6f8d-fbf6-bc7935d2abdf.png)

イベントリスナ周りは非エンジニアにはむずい気がするので結局設定はえんじにあのおしごと！になりそう。
prefix(プレフィックス)とsuffix(サフィックス)

今更恥ずかしいけど、急に忘れて調べると調べた先のサイトが
スペルミスしてたり、つられると危ないし、サイト探すのが面倒なのでメモ！

prefix：接頭辞

suffix：接尾辞
メモ: chromeデスクトップ (siomiz/chrome)に感動した

## 参考

* [ConoHa & Chrome Remote Desktopで艦これ！ - Qiita](https://qiita.com/cha2maru/items/309354a014fdfb94046a)にて詳細な情報があるが自分用にメモ
* https://hub.docker.com/r/siomiz/chrome/

## 起動方法

```sh:起動方法
docker run -p 127.0.0.1:5900:5900 siomiz/chrome
```

----

```rb:サイズも小さい(展開後835MB)
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
siomiz/chrome       latest              009f9abacdcb        3 weeks ago         835 MB
```

## パスワードを有効にする

```sh:パスワードの作成
# abcdという接続用パスワードを指定
echo abcd | vncpasswd -f > vncpasswd
```

```sh:run.sh
# データーコンテナの作成
docker run -d \
 --name chrome-profile \
 siomiz/chrome

# chromeコンテナ起動
docker run -d \
 --volumes-from chrome-profile \
 -v $(pwd)/vncpasswd:/home/chrome/.vnc/passwd \
 -p 5900:5900 \
 siomiz/chrome
```

```sh:起動
sh run.sh
```

```sh:接続
vncviewer localhost
```

## 日本語入力

* [Google 入力ツール](https://chrome.google.com/webstore/detail/google-input-tools/mclkkofklkfljcocdinagocijmpgbhab?hl=ja)を使うと日本語入力が出来ます。
ApacheとPHPには依存関係があるのかい？

#状況
AWS環境で急に一部のWebページに繋がらなくなる。
当該Webアプリを再起動しても状況変わらず。他にもポートを分けて別のWebアプリが入っており、そちらのページは問題なくつながる。あれれ？と思って、そういや前段にReverseProxyとしてApache入れてたな、と思い出しApacheのエラーログを見ると、以下のようなログが。
`[core:notice] [pid 10388] AH00052: child pid 20974 exit signal Segmentation fault (11)`
えー。Segmentation Faultじゃん。なんで？と思ったものの、とりあえず復旧を優先し、httpdを再起動。
#気になる箇所
事象は解決したのだが、ちょこっと気になるので、ググってみる。
http://digape.com/201204/php-php5-4-apache-2-4%E3%81%A7segmentation-fault/

なんかLAMP環境ではまっている人が多そうだ。(単にLAMPの利用人数が多いだけかもしれないが)

apacheのアクセスログを見ると、
`::1 - - [xx/Jan/2018:xx:yy:zz +0900] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) PHP/5.4.16 (internal dummy connection)"`

以前はなかったはずの「PHP/5.4.16」の文字が。これOPTIONSだから、ELBからのヘルスチェックのはずで、mod_phpなんて使ってなかったんだけど、勝手に連携されたらしい。
そういえば、別件でPHPインストールしたんだった。Webアプリとしては使ってなかったんだけど。yumでインストールしても依存関係とかあるのかなあ、とも思いつつも、どうせ使う予定ないので、アンインストール。

```
Running transaction
  削除中                  : php-5.4.16-42.el7.x86_64                        1/1
  検証中                  : php-5.4.16-42.el7.x86_64                        1/1

削除しました:
  php.x86_64 0:5.4.16-42.el7

完了しました!
```
これでしばらく様子見。

```
$ httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug  4 2017 03:19:10
```
git pushが失敗したとき

覚え書きとして。


リモートからgit pull し忘れて作業をしてしまい、git push しようとしてrejectを食らう、という事案。


ついうっかりやってしまった時の対処。


そういう時は、「リモートの変更を先に受けてからこっちの変更をマージしてpushしなおしたい」という方針であれば


```
git pull --rebase origin (ブランチ名)
```

で対処上記コマンドの後にpushをしてやる。

コンフリクト発生の場合などは別途対処が必要だが、解決案の一つとして認めておきます。
dockerでコマンドが変に折り返される...

## 概要
「docker exec -it」コマンドでコンテナに入ると80文字ぐらいで変に折り返され、表示がおかしくなるようになったので、調べてみた結果をメモしておく。

## 端末の行数および桁数
ターミナルの行数と桁数の設定があるようで、デフォルトが「 桁数：80, 行数：24 」となっているようです。
そのため、80文字を超えると変に折り返されてしまうようだ。。。

```bash
root@*********:/# echo $COLUMNS,$LINES
80,24
root@*********:/# stty size
0 0
```

＜参考サイト＞
- [Fix terminal rows, columns, and type when using old versions of kubectl exec](https://coderwall.com/p/qtk07q/fix-terminal-rows-columns-and-type-when-using-old-versions-of-kubectl-exec)

vagrantで起動したCentOSはターミナルのサイズを変更すると、自動変更してくれるようだが、dockerのコンテナはそうはいかないようだ。

とりあえず、変に折り返されると表示がおかしくなって使いづらいので、設定変更を調べてみる。

## 環境変数COLUMNS,LINESを使う
docker接続時に環境変数で桁数と行数を指定する。

```bash
# コマンドで指定する方法
$ docker exec -it jenkins env COLUMNS=200 LINES=50 TERM=xterm bash

# 「-e」オプションで指定する方法
$ docker exec -it -e COLUMNS=200 -e LINES=50 -e TERM=xterm jenkins bash
```

＜参考サイト＞
- [Linux コマンドライン画面の表示行数・桁数を変更する](http://linux-topics.com/02linuxkowaza/005.html)
- [Docker number of lines in terminal changing inside docker](https://stackoverflow.com/questions/38786615/docker-number-of-lines-in-terminal-changing-inside-docker)

## sttyコマンドを使う
sttyコマンド： 端末ラインの設定を変更・表示する

```bash
# jenkinsコンテナへ接続
$ docker exec -it jenkins bash

# 端末の行数および桁数をセットする
root@*********#$ stty rows 50 cols 200

# カーネルが保持している端末の行数および桁数を表示
root@*********$ stty size
50 200
```

＜参考サイト＞
- [terminal - How to change the width of remote serial console ...](https://unix.stackexchange.com/questions/106644/how-to-change-the-width-of-remote-serial-console)
- [sttyコマンド](https://www.mkssoftware.com/docs/man1/stty.1.asp)
- [How do I get more than 80 columns in command line mode?](https://askubuntu.com/questions/219547/how-do-i-get-more-than-80-columns-in-command-line-mode)

## まとめ
根本的な解決ではないので、Dockerfileなどで環境変数を大きめの値でセットしておくか、
自動でサイズを変更してくれるような仕組みがないかな・・・
ファイル内一括検索とファイル内一括置換のコマンド

## ファイル内一括検索

```
find /path/to/dir/ -type f -print | xargs grep "検索対象の文字列"
```

**具体例**

```
find /path/to/dir/ -type f -print | xargs grep "hogehoge"
```

## ファイル内一括置換

```
find /path/to/dir/ -type f -print | xargs sed -i -e "s/置換対象の文字列/置換後の文字列/g"
```

**具体例**

```
find /path/to/dir/ -type f -print | xargs sed -i -e "s/hogehoge/hugahuga/g"
```

* 参考サイト
    * http://qiita.com/kkyouhei/items/b4ff839a2f36ba194df3
    * http://kawatama.net/web/1141
    * http://deadcode.hatenablog.jp/entry/2015/05/18/192018
Swiftでは変数名に日本語を使える

# Swift勉強中

Swiftでは変数名に日本語が使えるらしい。

```swift
let 消費税 = 0.05
let 原価 = 10000.0
let 税込価格 = 原価 * (1.0 + 消費税)

// 10500.0
print(税込価格)
```

凄いけど、使い道はあまり無さそう。
英語が存在しないような業務で利用する・・・？
なんかソースコードが書き下された詳細設計書と同じ匂いがしてくる。
豆知識程度に。
PassingCars

まず、所感から入る。

**難解だ。**
何を言っているのか分からない。東西に走る車の通過数を答えろ、というような設問だが、何を答えればいいのか判然としない。

どうしても分からないため、[答え][a]を参考に、設問の意味の理解に努めた。
すると、ようやく分かった。

例えば、以下の配列が与えられたとする。

  A[0] = 0
  A[1] = 1
  A[2] = 0
  A[3] = 1
  A[4] = 1

このとき、A[0] ～ A[4] まで５つの車が存在し、それぞれの車が東に向かう（[0]）か、西に向かう
（[1]）かが示されている。
例えば、A[0] = 0 は、１台目の車が東に向かうことを意味し、A[1] = 0 は、２台目の車が西に向かうことを意味する。
なので、この時点で一つの組が生まれる。それは、(0, 1) になる。なぜなら、１台目と２台目がpassing (≒行き違う）しているからである。残りの A[2] ～ A[4] においても行き違う車の組を探し、組の数を数える、という問題。

## [1st][a]

今回は、上記[答え][a]のコードを見て設問の意味を理解したため、コード自体が頭に残っており、自分でコードを考えても、どうしても先人のコードが脳裏をよぎり、その考え方から離れられなかったため、考え方は先人のコードのものとなっている。

<table>
    <tr><th>正確性</th><th>性能</th><th>スコア</th></tr>
    <tr>
        <td>100%</td>
        <td>100%</td>
        <td>100%</td>
    </tr>
</table>

```php
function solution($A) {
    $cnt = 0;
    $east = 0;

    foreach($A as $value) {
        // Count cars traveling east
        if(0 == $value) {
            $east++;
        // Count pairs of cars passing
        } else {
            $cnt += $east;
            // If the number of pairs exceeds 1,000,000,000, return -1
            if($cnt > 1000000000) {
                return -1;
            }
        }
    }
    return $cnt;
}
```

考え方は先人と同じで、先人のコードは java で書かれていたため`for`ループだったが、このコードはPHP なので、`foreach`を使った、というのが唯一の違い。（変数名も少し違う。）

この考え方は、東に向かう車(east)が増えた分、西に向かう車(west)と行き違う数も増えるため、加算代入によって west += east とするもの。配列の要素の値が 0 のときはもちろん east++ となるだけ。
かなりシンプルで分かりやすい考え方。

対して、最初に筆者が考えたのは、組み合わせとして解けないか、というもの。配列のすべての要素を異なる値ととらえ、考えられる (0, 1) の組み合わせをすべて数えれば、答えになるはず。だが、この場合、恐らく `O(N^2)` の計算量となるため、性能要件でアウト。というより、そもそもコードに表現し切れない気がする。ぱっと調べた感じ、C言語では、再帰的関数を使って実現しているよう。
まあ、こういう**難しそう**を一つずつ解決していくことでスキルが向上していくんやろうけど。
悲しいかな、やる気が出ない。

<!-- 以下、参考 URL -->
[a]: http://codility-lessons-jp.blogspot.jp/2014/07/lesson-3-passing-cars.html
[b]: https://app.codility.com/demo/results/training46B3XF-ZYG/
<!-- 以下、Codility 和訳
N個の整数からなる空でないゼロインデックスな配列Aがある。
配列Aの連続な要素は、道路上を走る連続した車を表す。

配列Aは複数の0 and/or 1を含む配列である：

０は東に向かう車を表す。
１は西に向かう車を表す。
目的は、通過する車を数えることである。
一組の車(P, Q)が 0 ≤ P < Q < N のとき、Pは東に向かい、Qは西に向かい、行き違っている。

例えば、配列Aが次の場合：

  A[0] = 0
  A[1] = 1
  A[2] = 0
  A[3] = 1
  A[4] = 1

５組の通過する車があるということだ: (0, 1), (0, 3), (0, 4), (2, 3), (2, 4).

次のように関数を書け：

function solution($A);

これは、N個の整数からなる空でないゼロインデックスの配列Aが与えられたとき、行き違う車の組の数を
返すものである。

その関数は、行き違う車の組の数が1,000,000,000を超えた時、-1を返す。

例えば：

  A[0] = 0
  A[1] = 1
  A[2] = 0
  A[3] = 1
  A[4] = 1
上で説明した通り、その関数は5を返す。
-->
PDF.jsを使って、pdfファイルを出力する

コミックサイト作成した時に使用しました。

pdfファイルのページ数に対して、canvasを生成し
pdfファイルをレンダリングしています。
以下がコードになります。

```js
(function(){
  var url = 'file.pdf';

  PDFJS.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

  var pdfDoc = null;
  var pageNum = 1;
  var pageRendering = false;
  var pageNumPending = null;
  var scale = 1;
  var numi;
  var n;
  var ctx;
  var viewport;
  var canvas0;
  var renderContext;
  var renderTask;
  var pdfDoc;
  var createdom = document.getElementById("canvas");

  PDFJS.getDocument(url).then(function(pdfDoc_) {
    pdfDoc = pdfDoc_;
    document.getElementById('page_count').textContent = pdfDoc.numPages;

    renderPage(pageNum);
  });

  function renderPage(num) {
    pageRendering = true;
    fragment = document.createDocumentFragment();

    for(var i = 1; i < pdfDoc.numPages + 1; i++){
        cv = document.createElement("canvas");
        cv.setAttribute("id","canvas" + i);
        fragment.appendChild(cv);

      pdfDoc.getPage(i).then(function(page) {
          numi = i++;
          n = numi-3;
          canvas0 = document.getElementById("canvas" + n);
          ctx = canvas0.getContext('2d');
          viewport = page.getViewport(scale);
          canvas0.height = viewport.height;
          canvas0.width = viewport.width;

          renderContext = {
            canvasContext: ctx,
            viewport: viewport
          };

          renderTask = page.render(renderContext);

          renderTask.promise.then(function() {
            pageRendering = false;
            if (pageNumPending !== null) {
              renderPage(pageNumPending);
              pageNumPending = null;
            }
          });
          return;
        });

    }
      createdom.appendChild(fragment);

    document.getElementById('page_num').textContent = pageNum;
  }

  function queueRenderPage(num) {
    if (pageRendering) {
      pageNumPending = num;
    } else {
      renderPage(num);
    }
  }

  function onPrevPage() {
    if (pageNum <= 1) {
      return;
    }
    pageNum - 2;
    queueRenderPage(pageNum);
  }
  document.getElementById('prev').addEventListener('click', onPrevPage);

  function onNextPage() {
    if (pageNum >= pdfDoc.numPages) {
      return;
    }
    pageNum + 2;
    queueRenderPage(pageNum);
  }
  document.getElementById('next').addEventListener('click', onNextPage);


})();

```

少し、力技になってしまっている箇所がありますが、実装できました。
Hyper-V仮想ディスクの最適化(圧縮)メモ

容量可変タイプの Hyper-V 仮想ディスク を最適化(圧縮)する方法のメモ。

#手順
1. PowerShell を管理者で起動。
2. 次のコマンドを順番に実行。

```powershell
PS> $targetvhd = "VHD(X)のフルパス"
PS> Mount-VHD $targetvhd -Readonly
PS> Optimize-VHD $targetvhd -Mode Quick
PS> Optimize-VHD $targetvhd -Mode Quick
PS> Dismount-VHD $targetvhd
```

##メモ
- 事前準備は不要。
- Optimize-VHD コマンドを２回実行するといいらしい。
    - 圧縮されないから手順や環境に間違いがあると思ってた・・・。

#参考サイト
- http://www.atmarkit.co.jp/ait/articles/1609/26/news016.html
- https://yamanxworld.blogspot.jp/2017/09/vhdx.html
InterfaceBuilderを利用せずにカスタムNavigationItemクラスを適用する

方法はとても簡単でViewControllerの`navigationItem`をoverrideすれば良い。

```swift
class SampleViewController: UIViewController {
    override var navigationItem: NavigationItem {
        return CustomNavigationItem()
    }
}
```

UINavigationBarは画面のpush遷移時に遷移先ViewControllerに定義してあるnavigationItemを自身の管理する`items`プロパティに挿入するような仕組みになっている。

なので、ViewControllerに定義してあるnavigationItemは直接呼び出しても、それは今画面に出ているNavigationItemとは別物です。
（set onlyで定義してある時点でわかるとは思いますが。。。）

仕組みさえ覚えれば簡単なのですが、UINavigationBarが`setItems`、`pushItem`というトラップを提供しており[^1]、ドキュメント読み込まない人お断り的雰囲気に若干の辛さを覚えるのでした。

[^1]: これはUINavigationBarをUINavigationController以外のコンテキストで利用する場合に使える機能で、UINavigationController上で利用する場合アプリがクラッシュします。
備忘録(Spring Web)

Qiita初めての投稿。(お試し投稿を兼ねる)

##~~POJO~~オブジェクト型変数をXML形式で返却するには
元々~~POJO~~オブジェクト型変数をjson/xml形式でResponseへ自動変換するには、
```java:xml.java
@XmlRootElement(name = "test")
@XmlType
```
上記の様なアノテーションをつけるだけで、あとはコントローラ側のメソッドが自動で返してくれるものだと思っていたが、そうなるのはJSON形式の場合のみの様で、XML形式にしたい場合は、
```java:build.gradle
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.1')
```
と、設定を追記してあげる必要があるみたい。

``POJOの使い方が微妙っぽかったので修正しました。``

(2018/02/16追記)
XMLを入れ子にしたり、XMLタグの表示方法などを細かく設定している場合は、
[こちら](https://qiita.com/kurukurupapa@github/items/6e680f512adb238bd3eb)のサイト様のJAXBに関する記述も書く必要があるみたい。
各コントローラの戻り値には(任意のHttpStatusも入れたかったので) `ResponceEntity<XML化したいBean> ` の様に書いていたのが、
戻り値を`ResponceEntity<String>` にして、

```Java
StringWriter sw = new StringWriter();
JAXB.marshal(BeanToXMLClass,sw);
return ResponceEntity<>(sw.toString(), HttpStatus.OK);
```

の様にしてあげることで、
無事に変換後のXML文字列とステータスコード:200が渡された。
Cognos Analytics でリストに自動的に集計行が作成されるのを止める

#概要
Cognos Analyticsのレポートの機能で、リストに数値のデータアイテムを追加すると、以下のように勝手に集計行が追加されて、いちいち消していて面倒くさい思いをされている方もいると思います。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/98e7068c-127f-d38f-d58b-c5de42bd897a.png)

#手順
この動作を止める方法ですが、レポートの機能の「・・・」から「オプション」を選択します。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/36267edb-0686-083f-fe1b-0fafabf2e435.png)

「レポート」タブで「リストの自動グループ化と集計の動作」のチェックを外します。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/4f576b43-1333-4675-6a4e-aef3c15c368e.png)

個人的にはこの方が使いやすいので、止めれてうれしいです。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/386ea0f4-1571-eb0a-28b6-767691ad4a04.png)
Laravel Socialiteで認証後のリダイレクト先を動的に設定する

# はじめに
リダイレクト先の設定はconfig/services.phpに書くことで設定は可能ですが、
マルチテナントなシステムで、テナントごとに戻り先が替わる場合には設定ファイルの定義だけでは定義しきれない。
これの解決方法を残しておきます。

コードはTwitterで書きます。

# どうやるの？
* customCreatorsでインスタンスを作るようにする。

これだけ。
中身は、
> \Laravel\Socialite\SocialiteManager::createTwitterDriver()

そのまま。

```php

public function redirectToProvider($tenant)
{
    $url = route('hogehoge.twitter.callback', [$tenant]);

    $provider = Socialite::extend('twitter', function ($app) use ($url) {
        $config = $app['config']['services.twitter'];
        $config['redirect'] = $url;

        return new TwitterProvider(
            $app['request'], new TwitterServer(Socialite::formatConfig($config))
        );
    })->driver('twitter');
}
```

テナントごとに各キー値を書き換えたければ、他のも書き換えればOK。

# 他の方法は？
Socialite::driver('twitter')で取れるTwitterProviderの$serverプロパティを取るためにズルする。
$serverプロパティを取れれば、getClientCredentials()->setCallbackUri($new_uri)で書き換え可能。

# 終わりに
本当はredirect先だけ書き換えれれば良かったので、インスタンス毎作る必要はないけど、
設計思想がconfigの設定で1セットって考え方だと思うので、こうなるのかなーと割り切ってコレで実装しました。
他のイイやり方があったら是非教えてください。
意外と知られていないGmailの仕様

最近、知らない人からのメールが大量に届いたり、買った覚えのない買い物履歴が届いていて困っているんです。

GmailのToに「自分」と書かれていますが、詳細を開くと自分のアドレスではないメールアドレスが。。。。

で、Google先生がすでに回答のリンクを合わせて掲載されているので、そのページを見てみると

<a href="https://support.google.com/mail/answer/7436150" target="_brank">https://support.google.com/mail/answer/7436150</a><br />
<img width="830" alt="スクリーンショット 2018-02-07 9.53.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/76892/f0727ac2-a0df-92c6-e9b3-963d2d0f0449.png">

つまり。

私も持っているメールアドレスが「hoge2222@gmail.com」だったとすると、

hoge.2222@gmail.com
ho.ge.2222@gmail.com
ho.ge.2222@gmail.com
h.o.ge.2222@gmail.com
h.o.g.e.2222@gmail.com
h.o.g.e.22.22@gmail.com
h.o.g.e.2.2.22@gmail.com
h.o.g.e.2.2.2.2@gmail.com

上記すべてが、「俺のもの（by ジャイアン）」なので、すべて「hoge2222@gmail.com」に届きます。
勝手に使うのは良いのですが、個人情報やアカウントのID、重要な情報まで勝手にGmailが配達してくれるので、
要らない他人の住所や電話番号、楽天で購入した購入履歴なども丸見えです。

メールアドレスがユニークだと思っているサイトって多いので、このgmailの度量の広さを良しとするか、悪しとするかは、あなた次第。

メールアドレスをログインIDとしている会員サイトさんは、gmail対策をした方が良いのでは？
余計なお世話かもしれませんが。。。
SVN＋WebDAVでBasic認証に加えてIP制限もかけたいとき

SVN (Subversion)＋WebDAVを使ってHTTPSでのリポジトリ環境を構築したのですが、**ユーザーIDによるベーシック認証に加えてIP制限もやっとこ、**のところでつまずいたのでメモ的に残しておきたいと思います。

どちらかというとApacheの設定ルールメモ。

# 設定ファルの記載例

設定ファイルはいつもの **/etc/httpd/conf.d/subversion.conf** 。
下記のように記載することでIP制限とベーシック認証両方の条件を満たす場合のみアクセスできるようになりました。

```apacheconf
<Location /svn/repos>
        DAV svn
        SVNParentPath "/var/svn/repos/"
        SVNListParentPath on
        AuthType Basic
        AuthName "Subversion"
        AuthzSVNAccessFile /etc/subversion/conf/authzsvn.conf
        AuthUserFile /etc/subversion/conf/authuser.conf
        <RequireAll>
                Require valid-user
                Require ip [許可したいIPアドレス]
        </RequireAll>
</Location>
```

複数条件を ``RequireAll`` で括らないと『全て一致の場合に』とならないんですね。
デフォルトが All だったかと思い、記述しなくてもOKだと思いこんでいました。反省。。。
Rails5 + ActionCableをGAEにデプロイできなかったのでGKEにした

# ActionCable is 何？
WebSocketを使ったリアルタイム処理をRails　wayでお手頃に使えるフレームワーク

# Google App Engine is not supported WebSocket!!

便利になったActionCableをGAEをにサクっとデプロイして本番稼働しようとおもったらGAEはWebSocket非対応のためActionCableが利用できません。

>サポート対象外の機能
次に示す機能は、App Engine フレキシブル環境ではサポートされません。
バックエンド サービスへの HTTP/2 トラフィック
WebSocket
インスタンスに直接アクセスする HTTP リクエスト
https://cloud.google.com/appengine/docs/flexible/ruby/how-requests-are-handled

# Google Cloud PlatformでActionCableを利用するには？

HTTP（S)ロードバランサはWebSocketリクエストを自動的にアップグレードしてくれるため、バックエンドにGCEかGKEをデプロイしておけば対応することができます。

>HTTP(S) ロードバランサが HTTP(S) クライアントからの WebSocket アップグレード リクエストを認識し、バックエンド インスタンスからアップグレード成功のレスポンスが返されると、現在の接続期間中、ロードバランサが両方向のトラフィックのプロキシとして機能します。バックエンドからアップグレード成功のレスポンスが返されないと、ロードバランサが接続を終了します。
https://cloud.google.com/compute/docs/load-balancing/http/?hl=ja


# ロードバランサを使わずに自前でnginxを立てても可

こうやればできるけど素直にHTTP(S)ロードバランサ使ったほうが楽ですね。

```
server {
  location /cable {
    proxy_pass http://0.0.0.0:3000/cable;
    proxy_http_version 1.1;
    proxy_set_header Upgrade websocket;
    proxy_set_header Connection Upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}
```

# Rails + ActionCableのGCPでの最小構成図
![Rails+ActionCable.png](https://qiita-image-store.s3.amazonaws.com/0/108044/c497e464-f620-a37e-5b13-6778c1962c1b.png)

ActionCableはredis（or postgresql)が必要なのでもう1台GCEが必要になります。

はやくGAEでもActionCableが利用できるようになりますように！
Could not stop Cortex-M device

mbedのWEBコンパイラからプロジェクトをエクスポートして、オフラインでMDK-ARM＋ULINK2で作業して数時間経過、突然　Could not stop Cortex-M device　が発生。
ULINK2を付けたり外したり、ターゲットボードの電源ON/OFFを何度か繰り返してもこのエラーから回復せずでした。

＜解決策＞
ターゲットのリセットSWを押しながら電源を入れたら回復しました。
ターゲットボードが壊れたのかと思ってしまいました（こんな簡単なことでも気が付かないとビビります）。
ブータブルUSBを元のUSBメモリに戻す

# ブータブルUSBをUSBメモリとして使えるように戻すには

増設したメモリの確認用に[MemTest86](https://www.memtest86.com/)のブータブルUSBを作成したのですが、USBブートで使用した領域が使えない状態になり、フォーマットしようとしても領域自体を認識しないので困ってしまいました。ネットで探したところ[こちら](www.eastforest.jp/esthome/memo/245)に元に戻す方法が書いてあったので紹介します。
実際に行ったところ、[こちら](www.atmarkit.co.jp/ait/articles/0812/26/news119_2.html#create)にある通りにフォーマットしなおさないと使えなかったので、そちらも後半に加えました。

# 手順

コマンドプロンプトで以下を実行します。

1. `DISKPART`を入力してEnter --> DISKPARTが実行され別のコマンドプロンプト画面が開く
2. DISKPARTのコマンドプロンプト画面にて`list disk`を入力して実行し、USBメモリのディスク番号を確認する
3. `select disk <disk#>`を入力して実行し、USBメモリを選択する
4. `clean`を入力して実行し、USBメモリを初期化する
5. `list partition`でパーティションを確認する
6. `create partition primary`を実行してUSBメモリ容量と等しいサイズのパーティションを作る
7. `list volume`でボリュームを確認する
8. `select volume <volume#>`で6で作成したUSBのボリュームを選択する（Fs=filesystemsがRAWとなっているので分かりやすいはず）
9. `format fs=fat32 label="<new usb name>" quick`を実行してFAT32にフォーマットする 
10. `exit`を入力して実行しDISKPARTを終了する
【Java】Graphicsの透明度(アルファ値)変更


# はじめに
どうやらJavaのGraphicsクラスやColorクラスにはアルファ値だけ変更するメソッドがないようなので，こんな感じの関数作るとが良さそう。処理内容単純だし何回もやらないなら関数化する必要はないかな。


# アルファ値だけ変更
現在セットされてる色で透明度だけ変更

```java
public void setAlpha(Graphics g, int alpha) {
	int R = g.getColor().getRed();
	int G = g.getColor().getGreen();
	int B = g.getColor().getBlue();
	g.setColor(new Color(R, G, B, alpha));
}
```

# Colorとアルファ値を変更
フィールド化された色 (Color.REDとか) を使うなら便利かと

```java
public void setAlpha(Graphics g, Color color, int alpha) {
	int R = color.getRed();
	int G = color.getGreen();
	int B = color.getBlue();
	g.setColor(new Color(R, G, B, alpha));
}
```

# ちなみに
返り値を Color にして，最終行を

```java
return new Color(R, G, B, alpha);
```
に変更すればに色の取得だけできる。
AWS LambdaでLoading your function...となってプログラムを編集できないときの対処法

最近Lambdaを使っているとエディタが「Loading your function...」のままで編集できないときが多々ある。
そのときの対処法のメモ。

##環境
Lambda Node.js 6.10
ブラウザ chrome 64.0
OS Windows10

##現象
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202761/b3cc2e14-b5d8-8c1f-45bb-1505bdfa20d6.png)
ずっとこの画面で昼飯食べて帰ってきてもこの画面。

##対処法
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202761/1aecbc2f-e38e-dadf-ab0d-b38a6afe1501.png)
「Loading your function...」のところで右クリック→フレームを再読み込みで解決

##原因
[こちら](https://stackoverflow.com/questions/47585096/aws-lambda-edit-code-inline-shows-loading-your-function-continuously)のサイトで書いていましたが、
*This is happening in chrome as chrome is disabling the use of cookies from cloudfront domain.*
直訳すると「CloudFrontドメインからのクッキーの使用を無効にしているので、これはchromeで起こっている」
なるほど、私はchromeで広告ブロックの拡張機能を入れているのですが、以下のLambdaのドメインはブロック機能を無効にしています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202761/0cc0a648-e1a4-dfd9-7e5b-4cf20529ac6c.png)
ただAWSで使っているCloudFrontのドメインはブロックしていなかったので、ずっと読み込めなかったんですね。

##まとめ
拡張機能は便利だけどこういった障害（バグという意味ではなく）も意識して使いこなそう。
むしろ会社のPCでは広告ブロックの拡張機能はいらないかも。
windowsでコマンドラインからLINEに投稿(LINE Notifyを利用)

# はじめに
## 構成
下記の構成でcurlでLINENotifyのAPIにPOSTするだけです。
batで作ってますが、各自お好きなスクリプト言語で実装してください。

コマンドライン → curl(POST) →　LINE Notify

# 準備
## LINE Notifyのアカウント作成
[LINE Notify](https://notify-bot.line.me/ja/)

上記からアカウントの登録を行う

## LINE Notifyのアクセストークンを発行
マイページ下部にトーク発行機能がありますのでトークンを発行します。
一度しか表示されないので忘れずに記録しておくこと。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94585/51824875-9a4d-2a74-08a2-6b260b57af08.png)

# 実装
## batファイルの作成

``` bat
@echo off

REM KEYにアクセストークンを記入
set KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
REM 引数
set MASSAGE=%1

REM curlで通知用のAPIを叩く
curl -X POST -H "Authorization: Bearer %KEY%" -F "message=%MASSAGE%" https://notify-api.line.me/api/notify

```

## batファイルのPATHを通す
各自実施すること。

（補足）
私のおすすめの方法は一か所PATHを通したディレクトリを用意しておき、そのディレクトリにショートカットを配置することで簡単にPATHがとおります。
例：C:\\ShortCut を用意し、環境変数に登録する。そこにアプリ、ファイルのショートカットを配置します。例えばファイルサーバーのショートカットの名前を「sv」として配置しておくとファイル名を指定して実行に「sv」と入力するだけで直ぐに該当のファイルサーバーにアクセスできるようになります。キー操作としては「Win+r」→「sv」の2stepなので実質1秒以下でアクセスできるようになります。

# 利用方法
batに引数を渡すことで引数の内容をLINEに投稿してくれます。
※pathを通しているのでファイル名を指定して実行からbatを呼び出しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94585/00cf6164-6064-9067-f8e9-2754be02932d.png)

投稿できました。
日本語が文字化けしていますね。。。。
解消方法が分かりましたら追記します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94585/4de8a854-a9a9-46c2-6c79-165333c3d623.png)
Sketch備忘録~パス編~

#はじめに
sketchを最近触ったので記録。

##環境
sketch Version48.2 (Free Trial)

#今回の備忘録

##作成
Insert > Edit > Vectorでパスを書き始めることができるが、ショートカットキー「V」だけで始められる

##図形のパスの編集
1. 編集したい図形をクリック
2. クリックしたままEditボタンを押す

###補足
* 4種類全て違うので要注意
    1. Straight -> まっすぐなパス
    - Mirrored -> デフォルト、曲線のパス
    - Asymmetric　-> パスが左右非対称になる
    - Disconnected -> それぞれのパスの動きがそれぞれに影響されなくなる

## パスのセグメントの削除
1. 適当な図形を選択
2. Layer>Path>Sissorsを選択
3. 削除したいPathをクリック
![スクリーンショット 2018-02-07 15.51.39.png](https://qiita-image-store.s3.amazonaws.com/0/153719/e301630a-7af9-251c-55cd-da388285602c.png)
4. 完成![スクリーンショット 2018-02-07 15.51.46.png](https://qiita-image-store.s3.amazonaws.com/0/153719/3e9df15d-e0e4-c7a6-fe8a-0c065256d7d2.png)
Project Euler 23「非過剰数和」

今後はコメントで考えてることの軽い説明をいれていこうと思う。

## Problem 23 「非過剰数和」
完全数とは, その数の真の約数の和がそれ自身と一致する数のことである. たとえば, 28の真の約数の和は, 1 + 2 + 4 + 7 + 14 = 28 であるので, 28は完全数である.
真の約数の和がその数よりも少ないものを不足数といい, 真の約数の和がその数よりも大きいものを過剰数と呼ぶ.
12は, 1 + 2 + 3 + 4 + 6 = 16 となるので, 最小の過剰数である. よって2つの過剰数の和で書ける最少の数は24である. 数学的な解析により, 28123より大きい任意の整数は2つの過剰数の和で書けることが知られている. 2つの過剰数の和で表せない最大の数がこの上限よりも小さいことは分かっているのだが, この上限を減らすことが出来ていない.
2つの過剰数の和で書き表せない正の整数の総和を求めよ.

```python
def hoge(num):
    kajousu = []
    # 過剰数を列挙
    for n in xrange(1, num+1):
        if n < get_shinyakuwa(n):
            kajousu.append(n)
    # 2つの過剰数の和で書ける数字を列挙
    kajouwa = { n + m for m in kajousu for n in kajousu if n + m <= num }
    # 便利なdifferenceを使って2つの過剰数の和で書けない数字を取得
    not_kajouwa = set(xrange(1, num+1)).difference(kajouwa)
    return sum(list(not_kajouwa))

def get_shinyakuwa(n):
    shinyaku = [1]
    for m in xrange(2, (n/2)+1):
        if n % m == 0:
            shinyaku.append(m)
    return sum(shinyaku)

print hoge(28123)
```

重い。クッソ重い。
「真の約数の和」を全件算出している部分をどうにかしない限りは早くなりそうにない。
でも閃かない。
パケトレで、コピペで使えるコマンド集

いちいち同じことを設定するのが面倒なので、コピペで済むようまとめてみました。
#Switchのセキュリティを確保するための初期設定（C2960-24TT用）
全てのポートをshutdownにし、vlanの割り当てを1から1001に変更、明示的にポートの状態をaccess portにするっていうセキュリティ用の設定

```
config terminal
vlan 1001
name notuse
exit
interface range fa 0/1-24 , gi0/1-2
shutdown
switchport mode access
switchport access vlan 1001
end
```
 

↑ここまでコピペ

#Routerのポート同士を接続する
 ![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/124948/ee4ed68a-5320-c3fa-b4dd-013f21208af8.png)
↑こんな構成です

```
conf t
ip dhcp exclud 192.168.1.254
ip dhcp pool def-pool
network 192.168.1.0 255.255.255.0
default-router 192.168.1.254
end
```

↑ここまでコピペ
あとはSerialportに192.168.1.254 255.255.255.0を設定してやって、対向のポートでip address dhcpを打ち込んでやればおｋ
Ethernetでやる場合はクロスケーブルで接続して、Ethernet portにip addressを設定してあげてください。

#RouterのGigaPort2つにそれぞれ192.168.1.0/24, 192.168.2.0/24のネットワークを割り当て、さらにdhcpサーバとする
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/124948/ceb26470-3390-f6e2-e129-b56326e1699f.png)
↑こんな構成ですね、ip addressはかなり無駄になってますがとりあえず検証用

```
conf t
enable secret root
line vty 0 4
password root
login
exit
ip dhcp excluded-address 192.168.1.1
ip dhcp excluded-address 192.168.2.1
int gi0/0
ip address 192.168.1.1 255.255.255.0
no shutdown
int gi0/1
ip address 192.168.2.1 255.255.255.0
no shutdown
exit
ip dhcp pool gi00
network 192.168.1.0 255.255.255.0
default-router 192.168.1.1
dns-server 192.168.1.1
exit
ip dhcp pool gi01
network 192.168.2.0 255.255.255.0
default-router 192.168.2.1
dns-server 192.168.2.1
end
```
 
↑ここまでコピペ
あとは対向のルータのポートで ip address dhcp or ホストの設定画面で dhcpを選択してあげてください。
PHP&VSCode 導入手順

1.XAMPPをインストール
https://techacademy.jp/magazine/1722

2.composerをインストール
https://qiita.com/niisan-tokyo/items/8cccec88d45f38171c94
※zlib_decode():data errorで落ちる場合は↓の手順参照
https://qiita.com/bumptakayuki/items/44663e60fd8980fe9d70

3.VS Codeをインストール
https://code.visualstudio.com/

4.拡張機能のXDebug、PHP Intellisense、php-cs-fixerをインストール
http://www.elp.co.jp/staffblog/?p=5620
http://funcs.org/1530

5.XAMPPからApacheを起動し、適当なPHPのコードを書き、以下のことを確認する。
for文をテストコードとして書くと試しやすい。

・デバッグができる
・Intellisenseが動作している
・フォーマッタが動作する(Shift+Alt+Fで自動整形される)
Rubyでネストしたhashの未定義の要素にnilを返させる方法まとめ

ネストしたhashで未定義の要素を取得した場合、親要素から未定義の場合エラーになってしまう。たとえば下のコードでは、`hash_2[:b]`が`nil`を返してしまうので、`hash_2[:b][:b]`を取得すると`#<NoMethodError: undefined method '[]' for nil:NilClass>`のようなエラーが返ってきます。これを回避し、　`hash_2[:b][:b]`が`nil`を返すようにする方法をまとめました。

```
hash_2 = { a: {a: "A"} }

p "a.aを取り出す"
a = hash_2[:a][:a] # Aが出力される
p a

p "a.bを取り出す"
a =  hash_2[:a][:b] # nilが出力される
p a

p "b.bを取り出す"
begin
    b = hash_2[:b][:b] # エラーになるから何とかしたい
    p b
rescue => e
    p e
end
```


# 実行環境

以下の二つのバージョンでの動作確認を行いました。rubyのバージョンによりできることが少し変わっています。

- ruby 2.2.9p480 (2017-12-15 revision 61259) [x86_64-linux]
- ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-linux]

# 回避策
## fetchを使う
Hashのfetchメソッドは引数に`key`と`default`を指定し、`key`が存在すればその値を、存在しなければ指定した`default`を返します。これを使い、以下のようにhashの中間の要素には`default`に空のhash`{}`を、末端の要素に`nil`を指定します。

```
hash_2 = { a: {a: "A"} }

p "fetchを使う"
b = hash_2.fetch(:b, {}).fetch(:b, nil)
p b
```

コードが横に長くなるのが難点。


## &&を使う

`hash_2[:b] && hash_2[:b][:b]`とします。この場合、`hash_2[:b]`が評価された時点でnilなのでそのままnilを返します(`hash_2[:b][:b]`は評価しないのでエラーにならない)。`hash_2[:a] && hash_2[:a][:a]`の場合は前から順番に評価されていき`hash_2[:a][:a]`が返されます。また`&&`の代わりに`and`にすると`{:a=>"A"}`を、つまり`hash_2[:a] && hash_2[:a][:a]`の先頭の`hash_2[:a]`を返してくるのでダメです。

```
hash_2 = { a: {a: "A"} }

p "&&を使う"
b = hash_2[:b] && hash_2[:b][:b]
p b
```

これもfetch同様、横に長くなりますね。

## rescueを使う

`hash_2[:b][:b]`にアクセスしたときのエラーを後ろに置いたresqueで拾って、nilを返すようにします。

```
hash_2 = { a: {a: "A"} }

p "rescueを使う"
b = hash_2[:b][:b] rescue nil
p b
```


この書き方だと`NoMethodError`以外も`nil`を返してしまうのが気になりますが、ネストが何段でもコードが短く済むのと、空配列や0等任意の値を返すようにできるのは便利です。
また、`{ b: "B" }`のように`hash_2[:b]`が定義されて、`hash_2[:b][:b]`が未定義でも`nil`になります(他の方法はだいたいエラーになる)。



## mergeを使う
あらかじめ、全ての要素を`nil`であらかじめ定義したhashを別に作成し、mergeすることで、定義済みの要素はそのまま未定義の要素は`nil`になります。

```
hash_2 = { a: {a: "A"} }

p "mergeを使う"
nil_hash = {
    a: {a: nil},
    b: {b: nil}
}

merge_hash = nil_hash.merge(hash_2)
b = merge_hash[:b][:b]
p b
```

yamlやjsonをロードするとき等、形式は決まっている場合には、最初に一回mergeすれば、以後、`nil`を気にしないで良いのは便利だが、あまり使いたいものではないですね。

## to_hを使う(2.0から？)

`to_h`はhashならそのままhashを、`nil`なら`{}`を返します。

```
hash_2 = { a: {a: "A"} }

p "to_hを使う(2.0から?)"
b = hash_2.2.0から[:b].to_h[:b]
p b
```

fetchよりは短いので2.0からはアリかも


## &.を使う(2.3から)

ぼっち演算子を使うとobject が nil でないときにメソッドを呼びます。これで、`[]`メソッドを読んで取得します。

```
hash_2 = { a: {a: "A"} }

p "&.を使う"
b = hash_2&.[](:b)&.[](:b)
p b
```

長さ的にはto_hと変わらないのと2.3からは次のdigの方がよさそうです。


## digを使う(2.3から)

hashのネストした要素にアクセスし未定義ならnilを返してくれます。

```
hash_2 = { a: {a: "A"} }

p "digを使う(2.3から)"
b = hash_2.dig(:b, :b)
p b
```

基本的にこれを使うべきみたいです。


# まとめ

2.3以上ならdigが便利です。ただ、古いバージョンのRubyを使う場合は私はrescueを使う方法で回避しています。
[読書メモ]学習する組織 - 10章「共有ビジョン」

# なんの本か？
ざっくりすぎて何も言ってないのと、同じレベルのことを言うと組織力を強化するためには学習を続けることが必要ですよという話です。
なんの本なのかについてのよりちゃんとした記述は、全体を読んでからまとめる時に書きます。

# なんで読んだのか？
組織力強化について、自分なりに思いを巡らし始めていた。
そんな時に横山さんに推薦されて面白そうだったから。

 # この記事では何を書くのか？
組織の現状とあるべき姿を比べて、次にとるべき行動を策定する。
2月の自分が持ちたい組織影響目標を定めるために書く。

# 共有ビジョンとは
「自分たちは何を想像したいのか？」と言う問いに対する答えである。
共有ビジョンがあることで組織内に共通性の意識を生み出し、多様な活動に一貫性を与えることができる。

## 共有ビジョンはどこから出てくるのか？
共有ビジョンには個人のビジョンが反映されている必要がある。
むしろそれは個人ビジョンから生まれる。
なぜなら個人にとって重要なビジョンはそのひと自身のビジョン以外にはありえないらである。

## 共有ビジョンがあると何が嬉しいのか？
共有ビジョンは社員と会社の関係を変化させることができる。
共有ビジョンがあることで、あの人の会社ではなく、自分たちの会社になる。
心理学者として有名なマズローは晩年、優れた成果をあげるチームを研究した。
そんなマズローが傑出したチームにみたものはこうだった。
```
任務はもはや自己と区別がつかなかった。...むしろ自己がこの任務と強く一体化しているため、その任務を抜きにして本当の自己を語ることはできなかった。
```

共有ビジョンは、それを実現するために必要なことならなんでもする覚悟を湧き上がらせ、長期的な物事へのコミットメントを生む。

### ３つの社員のタイプ
1. 追従
    - 別の何かを得るためにビジョンを受け入れる。自分に期待されていることを従順にこなす。ルール通りに働く。
2. 参画（参画とコミットは区別が難しい）
    - ビジョンを心底望み、それを実現させる責任を十分に感じている。
3. コミット（参画とコミットは区別が難しい）
    - ビジョンを心底望み、それを実現させる責任を十分に感じている。決められたルール通りに働かない。結果には責任を持つが、必要であればルールを作る。

## 共有ビジョンを広めるためには？
スタート地点は、一人一人がビジョンを持つことである。
ただし、ビジョンを持つことを強制することはできない。
ビジョンを持つような雰囲気を醸成するためにできることは、リーダーがみんながそれぞれのビジョンを語りたくなるような方法で個人ビジョンを伝えることである。

そうして出来上がった個人ビジョンを統合して、共有のビジョンを作る。
共有ビジョンを作った後は、それに各人が参加するように仕向ける必要がある。
だが、これも個人のビジョン同様に強制することはできない。
そのためできる最上のことは、以下の行動によってビジョン参画に最も好ましい条件を整えることだけである。

1.  自分自身がビジョンに参画する
2.  ビジョンに対して正直になる。嘘や誇張せずに説明する。
3.  他者に選択させる。納得させる必要もない。
Rails server を実行しようとしたら openssl エラー発生

# 現象

```bash
$bundle install
Fetching gem metadata from https://rubygems.org/.
Could not load OpenSSL.
You must recompile Ruby with OpenSSL support or change the sources in your Gemfile from 'https' to
'http'. Instructions for compiling with OpenSSL using RVM are available at
http://rvm.io/packages/openssl.
```

# 試した策

## openssl 更新
openssl が向いている方向が違ったので、直した。

before

```bash
$which openssl
/usr/bin/openssl
```
bashrc に追記して PATH を設定

```bash
export PATH="/usr/local/opt/openssl/bin/:$PATH"
```

after

```bash
$which openssl
/usr/local/opt/openssl/bin//openssl
```


## ruby 更新

openssl を更新した後に ruby を再インストールした方が良いという電波を受信した。

```
$ env CONFIGURE_OPTS="--with-readline-dir=brew --prefix readline --with-openssl-dir=brew --prefix openssl" rbenv install -f 2.4.0
$ rbenv rehash
```

完了。そこで ruby のpathとバージョンを確認したら、

```
$which ruby
/usr/local/bin/ruby

$ruby -v
ruby 2.5.0dev (2017-11-17 trunk 60815) [x86_64-darwin16]
```

そうだ、開発版を使って遊んでいたんだった。。。

rbenv で管理された ruby を使うように変更する。
bashrc に以下を追加

```bash
eval "$(rbenv init -)"
```
これで直った。

```bash
$which ruby
/Users/Shumo/.rbenv/shims/ruby

$ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
```
Azure IoT Hub からストレージの Blob にデータを送る

Azure Iot Hub に publish したデータを Blob に保存する方法です。

完成すると次のようになります。
１）　publish します。
![azure_jan0600.png](https://qiita-image-store.s3.amazonaws.com/0/179446/2a4c5a08-f40f-3d23-a9c7-49a744d7cb32.png)

２）　Storage の Blob にデータが作成されます。
![azure_jan0601.png](https://qiita-image-store.s3.amazonaws.com/0/179446/01c91def-4cd6-418d-f5cc-daacd18c3764.png)

３）　データをダウンロードして vi で開きます。
次のようなデータが入っているのが確認できます。

```text
{"device_id":"tulip001","time":"8:36:19","temperature":26.5,"humidity":60.3}
```

![azure_jan0602.png](https://qiita-image-store.s3.amazonaws.com/0/179446/cc8c6b2e-c57e-1f6e-b835-495a8e45e7bb.png)

設定の仕方
Azure Iot Hub
Storage の Blob
は作成済みとします。

publish の方法はこちらです。
[Azure IoT Hub に Node.js で publish](https://qiita.com/ekzemplaro/items/61cb81a9efce4be20f64)

１）デバイスエクスプローラーで　エンドポイントを設定します。
![azure_jan0603.png](https://qiita-image-store.s3.amazonaws.com/0/179446/0e0cef82-9024-c0ff-53e8-fd8272496e60.png)

２）デバイスエクスプローラーで　ルートを設定します。
クエリ文字列は true を入れて下さい。
![azure_jan0604.png](https://qiita-image-store.s3.amazonaws.com/0/179446/d846cd8e-c0bf-0d26-4dbf-a6bd30d6c01f.png)
![azure_jan0605.png](https://qiita-image-store.s3.amazonaws.com/0/179446/94c9f8ce-8be3-d9dd-3050-42a8e44b4e75.png)


３）ホット パス テレメトリのルートは省略します。

設定の詳細は、
[センサー データを含む IoT ハブ メッセージを Azure Blob Storage に保存する](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-store-data-in-azure-table-storage)
[Apex] 権限セットをすべてのユーザに一括で割り当てる

任意の権限セットを、割り当て可能なすべてのユーザに一括で割り当てます。

```
final String PERMISSION_SET_NAME = '権限セットのAPI参照名';

// 権限セットを取得
PermissionSet ps = [SELECT Id FROM PermissionSet WHERE Name =:PERMISSION_SET_NAME];

// 権限セットを割り当てるユーザを取得
List<User> assigneeUsers = [SELECT Id FROM User WHERE IsActive = true];

List<PermissionSetAssignment> psalist = new List<PermissionSetAssignment>();

for (User u:assigneeUsers) {
  PermissionSetAssignment psa = new PermissionSetAssignment(
      AssigneeId = u.Id,
      PermissionSetId = ps.Id
  );
  psalist.add(psa);
}

Database.insert(psalist, false);
```

ユーザのライセンス設定によっては、割り当て可能な権限セットが制限され PermissionSetAssignment レコードの作成がエラーになる場合があります。
そのため `Database.insert` の第二引数に false を指定することで、権限セットの割り当てができないユーザを無視しています。

## 参考資料

- [PermissionSetAssignment - Salesforce および Force.com のオブジェクトリファレンス](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_permissionsetassignment.htm)
- [権限セットの作成 - Salesforceヘルプ](https://help.salesforce.com/articleView?err=1&id=perm_sets_create.htm&type=5)
初めてのＳＱＬ(Learning SQL)を読んだまとめ 2

続きです

# まとめ

## 集合演算の条件
1. 両方のテーブルの列の数が同じでなければならない
1. テーブルを組み合わせるときに対になる列のデータ型が同じでなければならない

ちなみに集合演算というのは``union``とか``intersect``とか``except``とかのことです。イマイチ使ってるところを見たことがない(あとソフトによって名前が違ったりするらしい)

## QUOTE

```sql
quote(Let's Split!)
```

みたいな感じで書くと、中のクオーテーションをエスケープして出力してくれる。  
予め決まってる文章をインポートするときとかに使えるかもしれない。もちろんこれだけでSQLインジェクションが防げるわけではない。  

## REGEXP

```sql
SELECT *
FROM employee
WHERE employee.name REGEXP '^佐藤'
```

``REGEXP``を使えばMySQLでも正規表現が使える！``RLIKE``でもいいぞ！  
ちなみに先輩はそんな高度なことはできないだろうと高をくくってたらしく、結構感動してました。

## SELECT節でのLIKE, REGEXP

LIKEやREGEXPは一致したときに1を返し、それ以外は0を返すのでSELECT節に指定すればDBからレコードを取ってきた時点で真偽に関する列が作れて、もしかしたらビューとかに不要なロジックを持ち込まなくて済む…のかもしれない

## COUNTについて

前のまとめの時に式の評価順序について調べたのだが、GROUP BYでレコードがまとめられたあとにSELECT文が参照されるなら、COUNTで数えられるのは何なんだろうと思っていた。   
理解の助けになったのは、GROUP BYはレコードをケーキのように切り分けているという表現で、GROUP BYがあるとCOUNTはその小分けにされたテーブルの中のレコードを見に行く、と考えるとイメージがつかめた。  
とはいえDISTINCTやらCOUNT(hoge.type=fuga or null)みたいなのが沢山出てくると混乱するときもあるので用心しなければ

## グローバルタイムゾーン セッションタイムゾーン

サーバ起動時にホストマシンのタイムゾーンを読み取ってシステムタイムゾーンにするんだけど、必ずしもホストマシンとログインユーザーのタイムゾーンが一致しているとは限らないのでこういうオプションが必要になってくる(?)  
SUPERな権限を持つユーザはグローバルタイムゾーンを指定できるけど、そうでないときは``SET time_zone = 'Europe/Zurich';``とかでセッションタイムゾーンを変更してあげると、CURDATE()とかNOW()とかで返ってくる時間が意図したものになる  
実はあんまり良くわかってない。

## 時刻のセパレータ
```
2005-3-27 15:30:00
2005/03/27 15:30:00
2005,03,27,15,30,00
20050327153000
```
これ全部暗黙的に日付として変換してくれるらしい。要素の順番には厳格だが、セパレータには寛容とのこと。  
他にも日付を生成するための``str_to_date()``関数などがあり、``STR_TO_DATE('March 27, 2005', '%M %d, %Y')``とかで読み取ってくれるらしい。一々DateTimeクラスをnewしてformatして…とかやらなくて済むようになるかも？

## interval
５日後の日付が欲しいときは``DATE_ADD(CURRENT_DATE(), INTERVAL 5 DAY)``で指定ができる。もちろんDAYの部分にはYEARとかSECONDとかも入れられるしYEAR_MONTHで9年11ヶ月とかも指定できるっぽい。  
あとよく使いそうなのはLAST_DAYで、指定した月の最終日を出してくれる。プログラム側で出そうとすると意外と気にすることが多かったりするので、いつか楽をさせてくれるかもしれない。

## GROUP BYの複数指定について
GROUP BYには複数の列を指定できる。最初見た時はまとめたものを更にまとめるからレコードの量は減るのかなぁとか思ってたんだけど、ここでもケーキのように切り分ける的な表現が役に立って、実際は一度切り分けたものを更に細かく切り分けるから最終的なレコードの量は増える、ということだった。

## wtih_rollup

```sql
SELECT product_cd, open_branch_id,
SUM(avail_balance) tot_balance
FROM ACCOUNT
GROUP BY product_cd, open_branch_id WITH ROLLUP
```

のような形で使うと、GROUP BYされたレコードの小計を出すことが出来る  
分かりにくいので図に出すと  

| product_cd | open_branch_id | tot_balance |
| --- | --- | --- |
| BUS | 2 | 934.55 |
| BUS | 4 | 10.00 |
| BUS | NULL | 944.55 |
| CD | 1 | 11500.00|
| CD | NULL | 11500.00 |
| CHK | 1 | 782.16 |
| ... | ... | ... |
みたいな感じになる

以前Riot.jsで表を出すとき、eachタグの中でグループごとの小計を出すのに頭を悩ませ、結局サーバ側で小計含めた配列を渡すようにしたんだけど、遡ってSQLで出せることを知っていればもっと綺麗に書けたのかもしれないなぁ。
Node.jsからmongoDB操作でのdb.collection is not a functionでハマった

# mongoDBドライバのバージョンアップ
2017年12月にmongoDB Node.js Driverが3.0にアップデートした模様。


今までの書き方でdb.collection is not a function出てハマりました。


###**version 2.2**

```javascript:test.js
const MongoClient = require('mongodb').MongoClient;

const url = "mongodb://localhost:27017/plactice";

MongoClient.connect(url, (err, db) => {
    db.collection("test", (error, collection) => {
        collection.insertMany([
            { name: 'Bob', age: 24 },
            { name: 'john', age: 30 }
        ], (error, result) => {
            db.close();
        });
    });
});
```

###**version 3.0**

```javascript:test.js

const MongoClient = require('mongodb').MongoClient;

const url = "mongodb://localhost:27017/plactice";

MongoClient.connect(url, (err, client) => {  //dbからclientに変更
    const db = client.db("plactice")  //　追加
    db.collection("test",(error, collection) => {
        collection.insertMany([
            { name: 'Bob', age: 24 },
            { name: 'john', age: 30 }
        ],(error,result) => {
            client.close();  //db.close()から変更
        });
    });
});
```


connectの引数のコールバックが今までdbだったものがclientに。

無事にSuccess。