OmniAICreator/Qiita-1.07M huggingface dataset:
Aurelia。それはReactやVue.jsに出遅れ感のある私に刺さりそうなフレームワーク

# はじめに

このエントリーを読んでAureliaに出会いました。
[SPAフレームワーク戦争後期にReactでもVue.jsでもなく、Aureliaを選んだ理由 (2019年所信表明)](https://qiita.com/pannpers/items/1b11987311fabfa4b88b)

普段はサーバーサイドエンジニアとして働いているので、フロントエンドのほうは弱いけど、世の中的にReactとかVue.jsとか流行ってきて、そろそろ使えるようにしておかないとまずいよなぁと思っていました。

そこで、Aureliaです。

現在、日本での知名度はかなり低いようですw
ただし、今後Aureliaが流行るようなことがあれば、大きなアドバンテージになること間違いなしです。

React、Vue.jsに出遅れ感を持っていた私にぴったりかもと思わせるフレームワークです。

ReactでもVue.jsでもAngularでもなく、Aureliaに一点投資しようというわけにはいかないのですが、とりあえず、触ってみようかなぁと思いました。

# Aureliaについて
Aureliaについて調べてみると、2015らへんに少し話題になって、その後は消えてるという感じでした。

<img width="800" alt="スクリーンショット 2019-01-07 9.11.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/32503/09edad15-3c21-ec16-e71b-6f3a57dd22a1.png">
https://aurelia.io/home

公式のトップにはこう書いてありましたが、`Unobtrusive`の意味がわかりません。
-> Unobtrusiveは「控えめな、でしゃばらない」という意味でした。

こちらの [チュートリアル](https://aurelia.io/docs/tutorials)をひととおりやってみたんですが、確かにフレームワークっぽい記述があまり出てこなくて、普通にjavascriptを書ければできそうです。

# まとめ
React、Vue.jsをできる人ならば、Aureliaも普通にできちゃいそうw
とはいえ、人を雇う立場の人ならばエンジニア集めるのが簡単とも言えるのではないでしょうか。

少しはコアな部分までできるようにならないと意味はなさそうなので、それなりに学習コストはかかりそうです。今からReact、Vue.jsでバリバリ書いている人に追いつこうとするのか、Aureliaの人を目指すのがいいのか悩むところではあります。

すでに出遅れてるんだし、ちょっとくらいバクチしてみようかなと思ってます！

# どうやって勉強するか
[公式のドキュメント](https://aurelia.io/docs) 
日本語の情報ほぼないので、公式のドキュメント読むかな。Google翻訳におまかせだね。

[日本語のドキュメント](https://github.com/aurelia/documentation/tree/master/alpha/Japanese)
あるじゃん！と思ったらちょっと古いみたい

 [TODOアプリを作るチュートリアル](https://aurelia.io/docs/tutorials/creating-a-todo-app)
よくあるTODOアプリ。でしゃばらないがどういうことかわかる

 [連絡先管理を作るチュートリアル](https://aurelia.io/docs/tutorials/creating-a-contact-manager)
左ペインにリスト出してクリックするとメインに詳細を表示的なチュートリアル

[RealWorldっていうサンプル](https://github.com/gothinkster/aurelia-realworld-example-app)
いろんなフレームワークで同じサンプルが実装されているようで、Aureliaも用意されています。色々な機能が揃ってるので公式のマニュアル読みつつこれを読み解いていこうかと思います。
H8/3664ではじめるマイコン制御7 TimerAでカウントアップ

前回二桁で押された回数をカウントするプログラムを作りましたが、今回はTimerAを用いて1秒ごとに自動でカウントアップするようにします。

```c:TimerCountUP.c
//1秒ごとにカウントアップするプログラム　
#include <stdio.h>

#define	BRR		(*((unsigned char *)0xFFA9))
#define	TMA		(*((unsigned char *)0xFFA6))
#define	IRR1	(*((unsigned char *)0xFFF6))
#define IRRTA 0x40 
//TimerAはIRR1の第6ビットが立つ

#define	PMR1	(*((unsigned char *)0xFFE0))
#define	PMR5	(*((unsigned char *)0xFFE1))

#define	PCR1	(*((unsigned char *)0xFFE4))
#define	PCR5	(*((unsigned char *)0xFFE8))
#define	PCR7	(*((unsigned char *)0xFFEA))
#define	PCR8	(*((unsigned char *)0xFFEB))

#define	PDR5	(*((unsigned char *)0xFFD8))
#define	PDR7	(*((unsigned char *)0xFFDA))

void wait();



main()
   {
	unsigned char LED[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7d,0x27,0x7f,0x67};//1の位用配列
	unsigned char LED10[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfc,0xa7,0xff,0xe7};//10の位用配列
	int i,count=0,count10=0;
	
	//SWの状態記憶用
	int OldState=0;
	int State=0;
	

	BRR=12;			//16MHZ時には１２を　デフォルトは７　ボーレート変更	
 	PMR1 = 0x00;			/*ポート１を汎用ＩＯに設定*/
 	PMR5 = 0x00;			/*ポート１を汎用ＩＯに設定*/

	TMA = 0x18; //1秒
	
 	PCR1 = 0xff;	//アドレス　FFE4
    PCR5 = 0xff;	//FFE8
    PCR7 = 0x00;	
    PCR8 = 0xff;	//FFED		//00入力　　ff出力
    
       for (;;) {/* 無限ループ */
        
        PDR5=LED[count];
        wait(500);
        PDR5=0x00;
        wait(50);
        
        PDR5=LED10[count10];
        wait(500);
        PDR5=0x00;
        wait(50);
        
       	State=0;
       	
        if((IRR1 & IRRTA) != 0){
        	State=1;
        	IRR1 &= ~IRRTA;//IRRTAを~IRRTAと反転させIRR1と＆をとりフラグを解除する
        }
        
        if(OldState!=State && OldState!=1){
        	if(count<9){
        		count++;
        	}
        	else{
        		count10++;
        		count=0;
        	}if(count10>=9)count10=0;
        }
        
        OldState=State;
        
    }
    return 0;
   }

void wait(int n)
{
	int i;
 	for(i=0;i>n;i++);
}
```

今まで飾りと化していたTMAにようやく出番が回ってきました。

```
#define TMA     (*((unsigned char *)0xFFA6))
#define IRR1    (*((unsigned char *)0xFFF6))
#define IRRTA 0x40 
```
#TMA

タイマAの機能は、「タイマモードレジスタA（TMA）」より設定します。

```c

TMA = 0x18; //1秒 0001 1000
```
TMAの第3ビットを1にすると時計用サブクロック、0にするとシステムクロックを使うことができます。今回は1をたて時計用クロックを使います。
　1秒間隔の周期イベントを発生させるには、TMAの第2ビットから第0ビットを「000」とすることで周期を1秒に設定することができます。第7ビットから第5ビットはクロック出力のためのものなので今回は使っていません。
000　1秒
001　0.5秒
010　0.25秒
011　0.03125秒

#IRR1

タイマAの発生する周期イベントは、IRRによって通知されます。IRRTAフラグは「割り込みフラグレジスタ1（IRR1）」の第6ビットにあります。IRRTAフラグは、タイマカウンタがオーバフローすると「1」にセットされますが、IRRTAフラグは1がたったらその後変化しなくなるので、プログラム側で0に戻してやる必要があります。
そのため今回は

```c
#define IRRTA 0x40 
```
を定義し

```c
IRR1 &= ~IRRTA;
```
で0に戻しています。

次回[H8/3664ではじめるマイコン制御8](https://qiita.com/kiki0817/items/d1a31c937cdb21ef1e65)
【pgrep】grepコマンド実行結果からgrepコマンド実行プロセスを取り除く[Linux]

#**はじめに**
実行中のプロセスを確認する際、`grep`コマンドを併用することが多いかと思いますが、その際、grepコマンド実行プロセスも結果に表示されてしまい結果がわかりにくくなってしまいます。

そこで、一例のみですが、grepコマンド自体のプロセスは取り除いて最終的な結果のみを表示させるコマンドを下記に記しました。

#**1. grepコマンドのvオプション**

```
$ ps aux | grep mysql | grep -v grep
```
上記コマンドは、mysqlのサーバーが上手く起動していれば、mysqlの文字を含んだプロセスを表示するコマンドです。

二つ目のパイプ`|`のあとの、`vオプション`つき`grep`コマンドでgrep自体のプロセスを取り除いています。

#**2. pgrepコマンドを利用**
上記のコマンドの代わりにfオプション、lオプション指定の`pgrep`コマンドでも同様のことが行えます。

```
$ pgrep -fl mysql
```
- fオプション コマンドライン全体をパターンマッチの対象とする
- lオプション プロセスIDとともにプロセス名も表示する


#**おわりに**
こちらの記事が役に立ったという方は、いいね、よろしくお願いします(^^)
業務中も堂々とtwitterをするために、twitterをslackっぽく表示するchrome拡張のパクリ

[表題のtweet](https://twitter.com/chanchii0707/status/1064513758960054272) が大変バズりましたが、chanchii0707さんのextensionがググっても見当たらないので作りましたー

![](https://i.gyazo.com/7836ac9ee78fa80e96f38111f964fc03.png)

https://github.com/prexlab/twitter2slack

あくまで雰囲気ですけども。
適当にカスタマイズして、ご利用くださいー
【GAS】Sheet - メソッド一覧

## Sheet

### getName()
シート名を取得する

```
sheetObj.getName()
```

### getRange()
セルを取得する（単体のセル）

```
sheetObj.getRange('セル番地');
```

### getRange()
セルを取得する（複数のセル）

```
sheetObj.getRange('セル番地1:セル番地2');
# Range Obj
```

### getLastRow()
シートの最終行数を取得する

```
sheetObj.getLastRow();
```
【GAS】SpreadsheetApp - メソッド一覧

## SpreadsheetApp

### getActiveSpreadSheet()

アクティブなスプレッドシートを取得する

```
SpreadsheetApp.getActiveSpreadsheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();
# SpreadsheetApp obj
```

### getActiveSheet()
アクティブなシートを取得する

```
SpreadsheetApp.getActiveSheet();
var sheet = SpreadsheetApp.getActiveSheet();
# Sheet obj
```

### getSheetByName()
スプレッドシートから、指定したシート名に該当するシートを取得する

```
spreadsheetObj.getSheetByName('シート名');
var sheet = spreadsheetObj.getSheetByName('シート名');
# Sheet obj
```


### getName()
スプレッドシート名を取得する

```
spreadsheetObj.getName();
# String obj
```
Let's Encrypt導入前に準備すべきこと

[リリースチェッカー](https://a.noare.net/)というサービスを個人で運営しています。先日、HTTPS化のため、Let's Encryptのサーバ証明書を導入しました。

手順は簡単だったのですが、事前に準備しておけば、もっとスムーズに進められたはずです。準備しておくべきだった3つの項目をご紹介します。

# 環境

- CentOS 6.10
- httpd 2.2.15
- certbot 0.30.0

# 導入手順（参考）

```
$ cd /usr/local/bin
$ sudo wget https://dl.eff.org/certbot-auto
$ sudo chmod a+x certbot-auto
$ sudo ./certbot-auto --apache -d a.noare.net
```

# 準備しておくべきだった項目

## 1. バーチャルホストの設定

`certbot-auto` コマンドの初回実行時に、下記のエラーが出てしまいました。

```
Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.
```

原因はバーチャルホストで運用していなかったためです。 `/etc/httpd/conf/httpd.conf` に `<VirtualHost>` ディレクティブを追加することで解消しました。

## 2. mod_rewriteの有効化

再度 `certbot-auto` コマンドを実行すると、違うエラーが出てしまいました。

```
Syntax error on line 1 of /etc/httpd/conf.d/le_http_01_challenge_pre.conf:
Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration
```

原因はmod_rewriteを無効にしていたためです。 `/etc/httpd/conf/httpd.conf` 内の下記の行をアンコメントすることで解消しました。

```
#LoadModule rewrite_module modules/mod_rewrite.so
```

## 3. mod_sslの設定

さらに `certbot-auto` コマンドを実行すると、HTTPSをリッスンするようにはなったものの、自己署名証明書が有効になってしまいました。

原因は、mod_sslのインストール時に作られた `/etc/httpd/conf.d/ssl.conf` に `<VirtualHost _default_:443>` セクションが存在し、その中に下記の行があったためでした。

```
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
```

`<VirtualHost _default_:443>` セクションをまるごと削除することで、Let's Encryptの証明書が有効になり、問題が解消しました。

事前にmod_sslをインストールし、 `ssl.conf` を編集しておくのが無難だろうと思います。
【GAS】Logger - メソッド一覧

## Logger

### log()
ログに出力する

```
Logger.log('テキスト');
Logger.log(値);
```
### log(format, x, y, ...)　：　for Class
ログに出力する（書式文字列の指定）

```
Logger.log(書式文字列を含むテキスト, x, y, ...)
```
【GAS】Range - メソッド一覧

## Range

### getValue()
セルの値を取得する（単体セルの値）

```
rangeObj.getValue();
# Object
```

### getValue()
セルの値を取得する（行列の指定）

```
rangeObj.getValue(行, 列);
```


### getValues()
セルの値を取得する（複数セルの値）

```
rangeObj.getValues();
# Object[][] : 二次元配列
```

### setValue()

セルに値を入力する

```
rangeObj.setValue('テキスト');
rangeObj.setValue(値);
```
WordPressでテーマのテンプレートファイルではなくプラグインなどから任意のファイルを読み込ませる

テーマ本体をさわるんじゃなくてプラグインからごにょごにょしたいけど、
テーマ本体にフック用意されてねーし！

って時に強制的に上書きしたい時って、あるよね！

```
function ｍｙ_custom_template_file() {
	if ( get_post_type() == 'post' && is_single() ) {
		// 読み込ませたいファイルを指定
		require( 'template-parts/doc/frame-salary-archive.php' );
		die();
	}
}
add_action( 'template_redirect', 'ｍｙ_custom_template_file' );
```

たぶん die(); じゃなくて他の関数使えよ！とか、
こんな方法の方がセオリーだよ！
ってのがあったらコメントください！
CaboChaで係り受け解析を試してみる

## 下準備
- 必要なファイルを準備
  - cabocha-0.69.tar.bz2
  - CRF++-0.58.tar.gz
- CRF++のインストール
<pre>
tar xzvf CRF++-0.58.tar.gz
cd CRF++-0.58
./configure
make
make install
</pre>

- 共有ライブラリの依存関係情報を更新します。下記を追記し反映コマンドを実行。

```/etc/ld.so.conf
/usr/local/bin #追記
/usr/local/lib #追記
```
<pre>
sudo ldconfig # 反映
</pre>

## CaboChaのインストール
<pre>
tar xf cabocha-0.69.tar.bz2
cd cabocha-0.69
LDFLAGS="-Wl,-rpath=/usr/local/lib -L/usr/local/lib" ./configure --with-charset=utf8 --enable-utf8-only
sudo make
sudo make install
</pre>

## CaboChaをrubyで使えるようにしました。
gem "cabocha"を使用する事にしました。

- SWIGインストールしなくてもcabocha v0.68以降であれば、下記コードで対応可能との記事あり
http://sinyt.hateblo.jp/entry/2014/04/23/173849
※展開したcabochaディレクトリ内のrubyディレクトリで作業する事
<pre>
ruby extconf.rb
make
make install
</pre>

- v0.67以前に関してはSWIGのインストールが必要との事。

 - 必要なファイルを準備
<br>
swig-3.0.12.tar.gz
 - コマンド履歴
PCREがないよと怒られたので
<pre>
sudo yum install pcre pcre-devel
</pre>
 - SWIGをインストール
<pre>
tar xf swig-3.0.12.tar.gz
cd swig-3.0.12
./configure
sudo make
sudo make install
</pre>



## cabocha-rubyを使ってみる
https://qiita.com/aadiimmz/items/d0f08517037b4894702d

簡易的にrubyプロジェクトを作成し、動作を確認する。
<pre>
mkdir cabocha_test
cd cabocha_test
bundle init
</pre>

```ruby:Gemfile
gem "cabocha" # 追記
```
<pre>
bundle install --path vendor/bundle
</pre>
<pre>
bundle exec irb
require "cabocha" 
include CaboCha
parser = Parser.new
tree = parser.parse("太郎は花子が読んでいる本を次郎に渡した")
tree.toString(FORMAT_TREE_LATTICE).force_encoding("UTF-8") # 実際に使えるデータが出力される。
</pre>

``` console:result
太郎は---------D
花子が-D     |
読んでいる-D   |
本を---D
次郎に-D
渡した

EOS
* 0 5D 0/1 -0.742128
太郎  名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー
は  助詞,係助詞,*,*,*,*,は,ハ,ワ
* 1 2D 0/1 1.700175
花子  名詞,固有名詞,人名,名,*,*,花子,ハナコ,ハナコ
が  助詞,格助詞,一般,*,*,*,が,ガ,ガ
* 2 3D 0/2 1.825021
読ん  動詞,自立,*,*,五段・マ行,連用タ接続,読む,ヨン,ヨン
で  助詞,接続助詞,*,*,*,*,で,デ,デ
いる  動詞,非自立,*,*,一段,基本形,いる,イル,イル
* 3 5D 0/1 -0.742128
本  名詞,一般,*,*,*,*,本,ホン,ホン
を  助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
* 4 5D 1/2 -0.742128
次  名詞,一般,*,*,*,*,次,ツギ,ツギ
郎  名詞,一般,*,*,*,*,郎,ロウ,ロー
に  助詞,格助詞,一般,*,*,*,に,ニ,ニ
* 5 -1D 0/1 0.000000
渡し  動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ
た  助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS
```

encodeしても文字列はASCII-8BITで返されるので、.force_encoding("UTF-8")を使用します。
<br>
なかなか面白そうなので、もっと積極的に触っていきたいと思います。

## 参考サイト
https://taku910.github.io/cabocha/
https://qiita.com/nezuq/items/f481f07fc0576b38e81d
http://kumagonjp2.blog.fc2.com/blog-entry-82.html
AWS EC2 Amazon Linux 2 AMI + Apache 2.4 + PHP-FPM 7.2 の構成にて、.html拡張子でPHPを動作させる

#概要
Amazon Linux 2 AMI + Apache 2.4 + PHP-FPM 7.2 の構成にて
.html拡張子でPHPを動作させるためのメモ。
amazon-linux-extras を使用します。
コマンドは管理者権限で実施します（sudo su）。

#手順
##Apahche2.4インストール
yum install httpd

##PHP-FPM 7.2インストール
amazon-linux-extras install php7.2


##html拡張子設定
httpd.confの中ではなく、/etc/httpd/conf.d/php.conf にて設定します。
拡張子に.htmlを追加します。
１．
変更前

```
AddType text/html .php
```

変更後

```
AddType text/html .php .html
```

２．
変更前

```
<IfModule !mod_php5.c>
  <IfModule !mod_php7.c>
    <FilesMatch \.(php|phar)$>
        SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
    </FilesMatch>
  </IfModule>
</IfModule>
```
変更後

```
<IfModule !mod_php5.c>
  <IfModule !mod_php7.c>
    <FilesMatch \.(php|phar|html)$>
        SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
    </FilesMatch>
  </IfModule>
</IfModule>
```


##PHP-FPM セキュリティ設定
/etc/php-fpm.d/www.conf にてセキュリティ設定を追加します。
これを設定しないとAccess denied. と表示されます。

変更前

```
;security.limit_extensions = .php .php3 .php4 .php5 .php7
```

変更後（行を追加）

```
security.limit_extensions = .php .html
```

##再起動
service php-fpm restart
service httpd restart

##自動起動設定
systemctl enable php-fpm
systemctl enable httpd

#動作確認
vim /var/www/html/info.html

中身

```
<?php
  phpinfo();
```
IPアドレス/info.htmlにアクセスして確認する
MacでPHP実行時にLibrary読み込みエラーが出る



## 環境情報

- macOS Mojave 10.14

## 問題

macターミナルでphpを動かそうとすると下記エラーが出る

```
$ php -v
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.61.dylib
  Referenced from: /usr/local/opt/php@7.2/bin/php
  Reason: image not found
Abort trap: 6
```

## 解決方法:boar:

```
$ brew reinstall php@7.2

$ php -v
PHP 7.2.13 (cli) (built: Dec  7 2018 10:41:23) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.13, Copyright (c) 1999-2018, by Zend Technologies
```
VimAdventures 　ステージ４，５攻略



# 解説動画
https://youtu.be/Kq_DaNrduXI

#レベル4
最初のエリアは赤い文字を「x」で削除⇒「W」,「E」を取得

W:「.」や「,」などを無視せず、次の単語の最初の文字に移動。
E:「.」や「,」などを無視せず、今いる単語の最後の文字に移動。

下のエリアに移動⇒まず「r」を取得⇒「x」と「r」を使いクリア⇒レベル4クリア

r:カーソルのある位置の文字の修正

#レベル5
最初のエリアは「x」と「r」を使いクリア⇒「d」を取得

d:「w」や「e」などと組み合わせて復数文字を削除できる。

下のエリアに移動⇒「dw」や「de」、「db」を駆使してクリア⇒鍵出現、人が出現
![bandicam 2018-12-30 13-21-30-972.jpg](https://qiita-image-store.s3.amazonaws.com/0/71162/415beb59-6688-7161-06b2-342a95ab91b5.jpeg)

出てきた人曰く、次のカギの出現には縦読みが必要だそうです。


右のエリアに移動⇒dw」や「de」、「db」、「dj」、「dE」を駆使してクリア
![bandicam 2018-12-30 13-20-53-957.jpg](https://qiita-image-store.s3.amazonaws.com/0/71162/158a0007-1aa2-6987-1907-dd937125d807.jpeg)

赤い部分を縦読みすると、「to get key dw on X」和訳すると「Xの上でdwキーを押してください」と書いてあります。

⇒最終行の「X」にカーソルを合わせて「dw」⇒鍵出現




戻って扉を開けてレベル5クリア

twitter: https://twitter.com/omegala81

前回：レベル1～3：　https://qiita.com/arufa/items/1cac121ea73cebc421dc　　　

次回　レベル6:　https://qiita.com/arufa/items/4214bfbc48fba51444c7
VBA_組み合わせ出力_5種

#1.概要
5種類の配列の組み合わせを出力するプログラム。

#2.ソースコード
```vb

Option Explicit

Sub 組み合わせ_5種()

    Dim ar0 As Variant
    Dim ar1 As Variant
    Dim ar2 As Variant
    Dim ar3 As Variant
    Dim ar4 As Variant
    
    ar0 = Array("a1", "a2", "a3", "a4")
    ar1 = Array("b1", "b2", "b3", "b4")
    ar2 = Array("c1", "c2", "c3", "c4")
    ar3 = Array("d1", "d2", "d3", "d4")
    ar4 = Array("e1", "e2", "e3", "e4")
    
    Call func_組み合わせ_5種(ar0, ar1, ar2, ar3, ar4)

End Sub

Function func_組み合わせ_5種(ar0, ar1, ar2, ar3, ar4 As Variant)

    Dim m As Long '行方向のカウンタ
    Dim kind_ As Long: kind_ = 5
    
    Dim n_a, n_b, n_c, n_d, n_e '列方向のカウンタ
    
    Dim Buf_() As Variant '生成した組み合わせのバッファ
    ReDim Buf_(kind_)
    
'組み合わせ生成ループ
    For n_a = 0 To UBound(ar0)
        m = 0 '0行目を対象
        Buf_(m) = ar0(n_a)
                
        For n_b = 0 To UBound(ar1)
            m = 1 '1行目を対象
            Buf_(m) = ar1(n_b)
            
            For n_c = 0 To UBound(ar2)
                m = 2 '2行目を対象
                Buf_(m) = ar2(n_c)
                
                For n_d = 0 To UBound(ar3)
                    m = 3 '2行目を対象
                    Buf_(m) = ar3(n_d)
                
                    For n_e = 0 To UBound(ar4)
                        m = 4 '2行目を対象
                        Buf_(m) = ar4(n_e)

                        Call DebugPrintArray(Buf_)
            
                    Next
                Next
            Next
        Next
    Next
 
End Function

'配列のDebugPrint
Function DebugPrintArray(var As Variant)
    
    Dim hoge As Variant
    
    '改行無し、各要素間はスペース
    For Each hoge In var
        Debug.Print hoge + " ";
    Next
    
    '改行する
    Debug.Print
    
End Function
```
#3.実行結果
a1 b1 c1 d1 e1  
a1 b1 c1 d1 e2  
a1 b1 c1 d1 e3  
a1 b1 c1 d1 e4  
a1 b1 c1 d2 e1  
a1 b1 c1 d2 e2  
a1 b1 c1 d2 e3  
a1 b1 c1 d2 e4  
a1 b1 c1 d3 e1  
a1 b1 c1 d3 e2  
a1 b1 c1 d3 e3  
a1 b1 c1 d3 e4  
a1 b1 c1 d4 e1  
a1 b1 c1 d4 e2  
a1 b1 c1 d4 e3  
a1 b1 c1 d4 e4  
a1 b1 c2 d1 e1  
a1 b1 c2 d1 e2  
a1 b1 c2 d1 e3  
a1 b1 c2 d1 e4  
a1 b1 c2 d2 e1  
a1 b1 c2 d2 e2  
a1 b1 c2 d2 e3  
a1 b1 c2 d2 e4  
a1 b1 c2 d3 e1  
a1 b1 c2 d3 e2  
a1 b1 c2 d3 e3  
a1 b1 c2 d3 e4  
a1 b1 c2 d4 e1  
a1 b1 c2 d4 e2  
a1 b1 c2 d4 e3  
a1 b1 c2 d4 e4  
a1 b1 c3 d1 e1  
a1 b1 c3 d1 e2  
a1 b1 c3 d1 e3  
a1 b1 c3 d1 e4  
a1 b1 c3 d2 e1  
a1 b1 c3 d2 e2  
a1 b1 c3 d2 e3  
a1 b1 c3 d2 e4  
a1 b1 c3 d3 e1  
a1 b1 c3 d3 e2  
a1 b1 c3 d3 e3  
a1 b1 c3 d3 e4  
～以下略
Cisco892J+対外で実験環境（コンフィグメモ）

#目的
- ルーター一台で複数のネットワークを使った演習を行いたかった。
- 対外接続をいい感じに配りたかった。


#仕様

- 7つの相互通信可能なネットワーク
- 運営用の1つのネットワーク（フィルタリングなし）
- DHCPが有効になっているポートで対外接続をNAT
- パブリックDNSをフォワード（各GW指定で利用可能）
- DNSを統一したい時用に、ループバックアドレス作成済み

#環境
- Cisco 892J

#コピペ可能なコンフィグ

```
vlan 10,20,30,40,50,60,70,100
exit

interface loopback 0
ip address 192.168.100.254 255.255.255.0
exit

interface fastEthernet 0
switchport mode access
switchport access vlan 100
no shutdown
exit


interface fastEthernet 1
switchport mode access
switchport access vlan 10
no shutdown
exit

interface fastEthernet 2
switchport mode access
switchport access vlan 20
no shutdown
exit

interface fastEthernet 3
switchport mode access
switchport access vlan 30
no shutdown
exit

interface fastEthernet 4
switchport mode access
switchport access vlan 40
no shutdown
exit

interface fastEthernet 5
switchport mode access
switchport access vlan 50
no shutdown
exit

interface fastEthernet 6
switchport mode access
switchport access vlan 60
no shutdown
exit

interface fastEthernet 7
switchport mode access
switchport access vlan 70
no shutdown
exit

interface gigabitEthernet 0
ip nat outside
ip address dhcp
exit

interface vlan 10
ip address 192.168.1.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 20
ip address 192.168.2.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 30
ip address 192.168.3.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 40
ip address 192.168.4.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 50
ip address 192.168.5.254 255.255.255.0
no shutdown
exit

interface vlan 60
ip address 192.168.6.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 70
ip address 192.168.7.254 255.255.255.0
ip nat inside
no shutdown
exit

interface vlan 100
ip address 192.168.10.254 255.255.255.0
ip nat inside
no shutdown
exit

access-list 1 permit 192.168.1.0 0.0.0.255
access-list 1 permit 192.168.2.0 0.0.0.255
access-list 1 permit 192.168.3.0 0.0.0.255
access-list 1 permit 192.168.4.0 0.0.0.255
access-list 1 permit 192.168.5.0 0.0.0.255
access-list 1 permit 192.168.6.0 0.0.0.255
access-list 1 permit 192.168.7.0 0.0.0.255
access-list 1 permit 192.168.10.0 0.0.0.255

ip nat inside source list 1 interface gigabitEthernet 0 overload
ip route 0.0.0.0 0.0.0.0 dhcp

ip dns server
ip domain-lookup
ip dns view default
dns forwarding
dns forwarder 8.8.8.8
exit
```
【Python】三項演算子

# 三項演算子

```Python:
# 他言語のように書くとエラーになる
>>> y = (x > 0) ? 10 : 20
  File "<stdin>", line 1
    y = (x > 0) ? 10 : 20
                ^
SyntaxError: invalid syntax

# 同様のことは以下のように書く
>>> y = 10 if x > 0 else 20

```
※Python 3.7.1 で確認

[6\. 式 \(expression\) — Python 3\.7\.2 ドキュメント](https://docs.python.org/ja/3/reference/expressions.html#conditional-expressions)
NodebrewでNodeをインストールする


## 参考リンク
- [公式：GitHub - hokaccha/nodebrew: Node.js version manager](https://github.com/hokaccha/nodebrew)
- [nodebrewで複数バージョンのnodeを一元管理する。 | Parsetree](https://parsetree.jp/blog/20180828/)
- [nodebrewでNode.jsをインストールする。 - Qiita](https://qiita.com/33yuki/items/bae442fa6314bd8f9d7a)

## 始める前に
nodeがインストール済みの場合、アンインストールが必要です。

homebrewの場合

```
brew ls  // nodeが表示されたら、以下のコマンドでアンインストール
brew uninstall --force node
```

npmの場合

```
npm ls -g node  // nodeが表示されたら、以下のコマンドでアンインストール
npm uninstall -g npm
```

## Nodebrewをインストールする

- インストール
`brew install nodebrew`

- 確認
`nodebrew -v`
バージョンが表示されればOK。

- 環境変数を追加
`vi ~/.bash_profile`で、以下を追加する。

```
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

bash_profileを更新して設定を反映させる。
`source ~/.bash_profile`

セットアップ。これやらないとインストールできない。
`nodebrew setup`

## バージョン指定してnodeをインストールする

- インストール可能なバージョンを確認
`nodebrew ls-remote`

- nodeのインストール
`nodebrew install-binary <version>`
> ※　nodebrew installでインストールするとスゴイ時間がかかるので、上記のコマンドが良いらしい。

現時点だとv10.15.0が最新なので、これをインストール
`nodebrew install-binary v10.15.0`

- インストールしたバージョンを確認
`nodebrew ls`

- 使いたいバージョンを指定
`nodebrew use v10.15.0`

もう一度`nodebrew ls`を叩いて、currentが指定されてればOK。

- 最後に
`node -v`でバージョンが表示されれば万事完了！
【Python】ファイル内画像を一括して指定ピクセルサイズで分割・保存

超初心者です。学生です。初投稿です。お手柔らかにお願いします。
なにかありましたら優しく教えてください💛

機械学習をやる際のテストデータ、教師データを特定ピクセルサイズのパッチに加工しようと思いました。しかし、ググってみても自分の欲しいドンピシャなコードが見つからない…（もしかすると僕のググり力不足かもしれません）
なので、メモ代わりに投稿します。

参考文献
https://qiita.com/kino15/items/ece822ec20ad5e80e382
上記の方のコードをベースに、分割する数を一々割り切れるように調節するのが面倒だったので端を切るようにしたのと、画像ファイル内にある画像に対して一括処理するようにしただけです。



```splitimage.py
import os
import glob
import cv2
import numpy as np
import sys
import matplotlib.pyplot as plt
from PIL import Image, ImageChops

# ディレクトリ設定
inputdir = "ここに入力"
outputdir = "ここに入力" # ディレクトリが存在しなくても勝手に作る

# 分割したいパッチのサイズ指定
height = 200
width = 200

# ディレクトリが存在しない場合は作成する
if not os.path.exists(outputdir):
    os.mkdir(outputdir)

# ファイル検索　※今回はjpegにしてますが、適宜変えてください
pngsearchpath = os.path.join(inputdir, '*.jpg')
pngfiles = glob.glob(pngsearchpath)

# 各ファイルの処理
for file in pngfiles:
    # 画像ファイルを開く
    print(file)
    im = Image.open(file)
    name, ext = os.path.splitext(os.path.basename(file))
    im_height ,im_width =im.size

    a=im_height//height
    b=im_width//width

    def ImgSplit(im):
        # 縦の分割枚数
        for h1 in range(b):
            # 横の分割枚数
            for w1 in range(a):
                w2 = w1 * height
                h2 = h1 * width
                print(w2, h2, width + w2, height + h2)
                yield im.crop((w2, h2, width + w2, height + h2))

            for number, ig in enumerate(ImgSplit(im), 1):
            # 保存先フォルダの指定
                ig.save(outputdir+"/"+name+"-%01d.jpg" %number, "JPEG")


if __name__ == '__main__':
    main()
```

なんか色々突っ込みどころ満載かと思いますが、適宜書いていただけると嬉しいです。
ユニットテスト（単体テスト）の大切さ

こんにちは、サム （[@sbenemerito](https://twitter.com/sbenemerito)） です。奥多摩の留学生で、日本語を勉強しています。2018年10月に日本にフィリピンから来ました。

この記事で、ユニットテストについて話します。ユニットテストとは「単体テスト」を意味しています。目的は、ユニットテストを知らない人とかユニットテストを書いたことがない人にユニットテストを紹介します。

## ユニットテストとは

![image.png](https://qiita-image-store.s3.amazonaws.com/0/300933/818dd144-2fa5-37be-6261-866808f4415a.png)

ユニットテストとは、プロジェクトの部分が個々の機能を正しく果たしているかどうかを検証するテストです。その部分は「単位」か「ユニット」と呼ばれることです。通常、プロジェクトの関数がユニットテストの単位（ユニット）となります。そして、ユニットテストは、開発時など早い時で開発者によって実施されることです。それで、利用者の観点からは、ユニットテストを見ることができません。

たとえば、プロジェクトに郵便番号を入力関数を追加したいです。その関数を作りながら、ユニットテストを使って、無効なデータとか郵便番号の書式のような見つけにくい論理の欠点を簡単に見つけることができます。それで、開発者はコードが正しくて機能的に自信が上げるようになります。その自信は大事なこと（特に大きな事業のソフトウェアの開発時）です。

ユニットテストのコードは開発者が書くので、プロジェクトのコードをわかることが必要です。プロジェクトの開発者が書いたテストが一番いいユニットテストです。

### 大切さ・メリット
- __コードの品質が上げます。__総合テスト前に欠陥を見つけろことができます。また、コード作成時前など早い段階でユニットテストを書くによって、コードをやりたいことについてもっと考えることができます。
- __開発がより敏捷になります。__プロジェクトにいくつかの関数を追加したら、時々、先のデザインかコードを変更しなければなりません。テストしたコードを変更することが危なくて時間をかけることが可能です。でも、もしユニットテストがあったら、テストしたコードを変更することが自信を持って、簡単にできます。
- __他のコードに影響を与える可能性が低くなります。__開発者は統合前に自分で書いたコードをテストするので、欠陥を早くに見つけます。
- __ドキュメンテーションを提供します。__ ユニットによって提供される機能とその使用方法を学びたい開発者は、ユニットテストを調べてユニットの構造の基本的な知識を得ることができます。
- __コストを引き下げます。__ バグ直することはコストがあります（特にシステム総合後に発見されたバグ）。早くに発見されたバグは修正がより簡単です。なぜなら後に発見されたバグは通常多くの変更の結果であり、バグの原因を見つけにくいです。

ユニットテストはたくさんのメリットがありますが、いくつかの不利益もあります。

### 不利益
- __ユニットテストを書くことは時間をかけます。__たとえば、小さいプロジェクトでは、テストによる厳密な品質管理より、締め切りに間に合うのほうがいいです。
- __考えられるすべてのシナリオを実行することが不可能です。__テストデータは開発者の考えに限定されていますので、確認が完璧じゃないです。

## まとめ
小さいプロジェクトより、大きなプロジェクトにユニットテストほうがいいです。小さいプロジェクトもユニットテストから利がありますが、ユニットテストがちょっと時間がかかりますので、「本当に必要ですか？」か「締め切りに間に合いますか？」のような質問をプロジェクトマネージャーが決めなければなりません。

基本的に、ユニットテストにやる価値があります。ほとんどの開発者にとって、ユニットテストはいつも必要ですが、たぶん小さいプロジェクトには、必要じゃありません。もし未来にプロジェクトが大きくなりたいなら、早くにユニットテストにやるほうがいいです。
Hyper-V + vagrantで共有ディレクトリのマウントができない場合

## Hyper-V + vagrant + centos/7 の場合の注意

VirtualBoxだと /vagrantが勝手にできて、読み書きともに出来るけど今回の環境では「もともと Vagrantfileの存在するディレクトリに存在したファイル、ディレクトリ」しか共有されない。ファイルの新規作成もダメ。
なので共有ディレクトリをsmbでマウントするようにした。

```ruby:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.provider "hyperv"
  # enable network 
  config.vm.provision "shell", run: "always", inline: "systemctl restart network.service"
  config.vm.network "private_network", ip: "172.29.202.34"
  config.vm.synced_folder ".", "/vagrant"
  
  config.vm.synced_folder "./workspace", "/vagrant/workspace", create: true, type: "smb", mount_options: ["vers=3.0"]
  config.vm.provider "hyperv" do |h|
  end
  
end
```

## smbでのマウントがうまくできない

上の設定でOKかと思ったが、何度やっても以下のようになる。

```
vagrant up
...
Stderr:

Error:

Stdout:
```

つまり、何もない。辿れない。
困ったのでデバッグオプション付きで実行してみた(`vagrant up --debug`)が、smb_prepareが失敗している、程度のことしかわからない。
別のPCで同じVagrantfileを使って vagrant up してみたら上手く行く。ユーザー名とパスワードを入力するのは面倒だが、上手く行く。
何が何だかわからない。

### 原因

しばらくgoogleでいろいろ探してみたところ、 環境変数 %TMP% %TEMP% の内容がおかしいらしい、とわかった。

システム環境変数で確認すると %TMP% は %USERPROFILE%\AppData\Local\Temp となっていて、%USERPROFILE% は c:\Users\自分のWindowsログイン名 となっている。
つまり user = okadabasso でWindowsにログインしている場合 %TMP% は c:\Users\okadabasso\AppData\Local\Temp になるはずなのだが、どういう訳か c:\Users\okadab~2\AppData\Local\Temp になっていた。

多分、以前空白付きのユーザー名を使っていたのを修正したときにおかしくなったのだと思う。
`fsutil 8dot3name`を使って短いファイル名を無効にしてもダメだった。

仕方がないので %TMP%と%TEMP%を無理やり正しい内容にセットしてやるとうまく `vagrant up`できて、ちゃんと対象のディレクトリが共有出来ていた。

### PowerShellの初期化コード

エクスプローラーからPowerShellを開くのが便利なのでPowerShellの場合。

初期化コードのスクリプトファイルを開くのはこう。(ファイルがない場合は別)

```
[PS]>notepad $profile
```

内容はこんな感じ

```
$env:TEMP=$env:USERPROFILE + "\AppData\Local\Temp"
$env:TMP=$env:USERPROFILE + "\AppData\Local\Temp"
```

で、PowerShellウインドウを開いてから vagrant up すると、対象のディレクトリが共有できる。

## その他

この作業で結局二日費やしてしまった。前にvagrantとdockerでいろいろやろうとしてた時も同じような場所ではまっていた。

現段階では Hyper-V + vagrant + Docker for Windows で頑張るより VirutalBox + vagrantで適当なlinuxホストを実行し、その中でdocker使うほうがましなんじゃないか、って気がしている。
GKE+Cloud Build+kustomizeのデプロイ

# 概要

GKEにCloud Buildを使ってデプロイする。
Cloud Build内のstepでkubectlの代わりにkustomizeを使う。

# 手順

## 1. Code Buildを有効にする
Webコンソール等でCode Buildを有効にする

## 2. Code BuildのIAMにGKE権限付与

Code BuildのIAM（ex. 123456789012@cloudbuild.gserviceaccount.com）に
"Kubernetes Engine 管理者" の権限を与える。

## 3. [cloud-builders-community/kustomize](https://github.com/GoogleCloudPlatform/cloud-builders-community/tree/master/kustomize) を使う

cloud-builders-communityにkustomize入りbuilderがあるのでそれを使う。
READMEにあるように

```
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community
cd cloud-builders-community/kustomize
gcloud builds submit --config cloudbuild.yaml .
```

する。
（事前に ```gcloud config set project``` が必要）

そうするとREADMEにあるように

```yaml

- id: deploy
  name: 'gcr.io/$PROJECT_ID/kustomize'
  args:
  - 'build'
  - 'overlays/prod'
  env:
    - 'APPLY=true'
    - 'CLOUDSDK_COMPUTE_ZONE=us-west1'
    - 'CLOUDSDK_CONTAINER_CLUSTER=tf-k8s'
    - 'GCLOUD_PROJECT=compound-dev'
```

というようにstepを記述してkustomizeを実行できる。

# その他

## stageでconfを分ける

このあたりはいまいち固まりきってないけど

* develop
    * ブランチへのpushをトリガーにする
    * latest, develop等のタグへDockerイメージをpush
    * Deploymentを強制的に更新するためにsedで無理やりテンプレート置換してgitのハッシュをannotationに入れる
* production
    * タグのpushをトリガーにする
    * $TAG_NAMEをDockerイメージをpush
    * kustomizeのimageTagsでイメージのタグを上書き指定
 
としてみている。いろいろ気持ち悪さがあるのでもうちょっとなんとかしたい。。
sedのところはkubectl patch deploymentするのとどっちがいいか微妙なところ。

```overlays/develop/app.yaml
# ...
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      annotations:
        git-sha: _COMIT_SHA_
# ...
```

```yaml:cloudbuild.develop.yaml
steps:
# ...
- name: 'gcr.io/$PROJECT_ID/kustomize'
  entrypoint: bash
  args:
  - '-c'
  - |
    gcloud container clusters get-credentials --zone "$$CLOUDSDK_COMPUTE_ZONE" "$$CLOUDSDK_CONTAINER_CLUSTER"
    kustomize build "overlays/develop" | sed -e "s/__COMMIT_SHA__/$COMMIT_SHA/g" | kubectl apply -f -  
  env:
    - 'APPLY=true'
    - 'CLOUDSDK_COMPUTE_ZONE=$_ZONE'
    - 'CLOUDSDK_CONTAINER_CLUSTER=my-cluster'
    - 'GCLOUD_PROJECT=$PROJECT_ID'
```

```overlays/production/kustomization.yaml
# ...
imageTags:
  - name: asia.gcr.io/my-project/my-app
    newTag: v0.0.2
```

```yaml:cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
  args:
    - 'build'
    - '--tag=asia.gcr.io/$PROJECT_ID/my-app:$TAG_NAME'
    - '.'
- name: 'gcr.io/cloud-builders/docker'
  args: ["push", "asia.gcr.io/$PROJECT_ID/my-app:$TAG_NAME"]

- name: 'gcr.io/$PROJECT_ID/kustomize'
  args:
  - 'build'
  - 'overlays/production'
  env:
    - 'APPLY=true'
    - 'CLOUDSDK_COMPUTE_ZONE=$_ZONE'
    - 'CLOUDSDK_CONTAINER_CLUSTER=my-cluster'
    - 'GCLOUD_PROJECT=$PROJECT_ID'

```

## 参考

>Cloud BuildとkustomizeでGKEのCDパイプラインを作る - y-ohgi's blog
>https://y-ohgi.hatenablog.com/entry/2018/09/06/080921
人工知能の三つの法則

こんにちは、エンジェルともします。
最近、AIについてのドキュメンタリーを見ました、アシモフによる人工知能の3つの法則について話します。

#人工知能とは
基本的には、人工知能（AI）は考え、学ぶためのコンピュータプログラムです。人工知能の概念は、人間のように思考し、行動し、学ぶことができる機械を組み立てるという考えに基づいています。

今日、人工知能は以前よりもずっと早く進歩しています。私たちは気づかずに人工知能を使うことがよくあります。

#Asimovの三つの法則とは
サイエンスフィクションはすでに人工知能が人間を傷つける可能性があることを想像しており、さまざまな解決策を提案しています。最も有名なのは、ロボットが人間を傷つけないようにするために設計されたIsaac Asimovの3つの法則です。

1942年に、サイエンスフィクションの作者Isaac Asimovは、Runaroundと呼ばれる短編小説を発表しました。その中で、彼はロボットの行動を管理する3つの規則を導入しました。

技術は良くも悪くもない、それは常にあなたがデータを使用する方法に依存します。
人工知能を作成するための法的要件はありませんが、各企業にはデータを使用するための独自のポリシーがあります。ロボット工学の3つの原則は理想的にはロボットがどのように振る舞うべきかについてのアイデアとロボットの相互作用から人間を守るための提案です。

**1.) ロボットが人間を傷つけることは許されない**
この第一法則をするために作成者はロボットへのデータ入力を制限する必要があります。
創造主は自分の目標に集中し、必要なデータだけを入力しなければなりません。

**2.) ロボットは、そのような命令が第一法則と矛盾する場合を除き、人間からの指示に従わなければなりません。**

この第二法則をするために創造主はいつも彼らの発明を超えて一歩踏み出さなければなりません。
私たちが自分よりも賢い人工知能を作成するのであれば、我々は実際にそれらをコントロールすることができないかもしれないということを受け入れなければなりません。

**3.) ロボットが第一法則または第二法則と矛盾しない限り、ロボットはその存在を保護しなければなりません。**
この第三法則を実行するために、ロボットは自分自身を危険にさらすべきではありません。

#まとめ
ロボットが私たちの社会の支配的な部分になるにつれて、私たちは彼らがどのように振る舞うかを支配する規則を間違いなく必要とするでしょう。でも、私達の技術は急速にそして広範囲に成長しているので、人々はもっと多くの規則を追加しそして実行することを望む。私たちは自分自身と社会を守るためにこれらの規則が必要です。これらの法律は空想科学小説から始まりましたが、それでも重要であり、各人工知能企業の原則に含まれています。

**ソース:**
https://www.auburn.edu/~vestmon/robotics.html
https://hackernoon.com/a-laymans-guide-to-artificial-intelligence-ai-8a81b372c68d
v-html で出力したタグにスコープのスタイルをあてる

# v-html
親のコンポーネントから文字列をタグつきで受け取って表示する際

```vue
<div v-html="content"></div>
```
こんな感じで指定しておくと、親で `content="<a href='#'>link</a>"` と指定された文字列がタグとして反映されて出力されます。ただ、 `scoped` されたこの中身にスタイルをあてようとすると、ひとクセ必要です。

```scss
<style scoped>
  .a >>> .b {
    /* Styles */
  }
</style>
```
上記のように `>>>` コンビネータを使用することで、適用することができます。
ただ、 `<style lang="scss" scoped>` した時にうまくあたらなかったのでメモ。

## そんな時は `/deep/` コンビネータを使う
SASS のようなプリプロセッサは `>>>` をうまく解析できないため、エイリアスになっている `/deep/` を代わりに使います。

```scss
<style lang="scss" scoped>
  .a {
    /deep/ .b {
      /* Styles */
    }
  }
</style>
```

としたらうまくあたりました。

```vue
<template>
  <div>
    <dl>
      <dt>{{ dt }}</dt>
      <dd class="a" v-html="dd"></dd>
    </dl>
  </div>
</template>

<script>
  export default {
    props: ['dt', 'dd']
  }
</script>

<style lang="scss" scoped>
  .a {
    /deep/ .b {
      /* Styles */
    }
  }
</style>
```

ちなみに受け渡す元の要素には `<a class="b" href="#">link</a>` のようにクラスをつけておいた方がいいらしいです。

## 参考

- [スコープ付き CSS](https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html)
- [Scoped styles with v-html](https://medium.com/@brockreece/scoped-styles-with-v-html-c0f6d2dc5d8e)
- [Scoped styles don't apply to v-html injections](https://github.com/vuejs/vue-loader/issues/749)
dplyr使いのためのpandas dfply データ加工編（tidyr）

#はじめに
dplyr同様の操作を可能にするdfplyライブラリのまとめ、今回はデータの加工編です。
なんと、tidyrの関数も使えます！

基本操作は下記記事をご参照ください。
[dplyr使いのためのpandas dfplyすごい編](https://qiita.com/T_Shinomiya/items/c039451869382e0790f4)

#事前準備、例データ
例データはseabornライブラリに付属しているみんな大好きtitanicと簡単に作成したデータを使います。

```Python:Python：事前準備
import pandas as pd
import numpy as np
from dfply import * #dfply読み込み

import seaborn as sns
titanic = sns.load_dataset('titanic') #titanic読み込み
```
##gather long形式データへ変換
long形式のデータへ変換する関数です。

```Python:Python：dfply-gather
#gather(variable=新しいKey列名, 新しいデータ列名, 列指定)
titanic_long = titanic >> head(3) >> select(X.fare, X.age) >>
    gather('variable', 'value', [X.fare, X.age])

#列指定をしないと全列で変換が行われる
titanic_long = titanic >> head(3) >> select(X.fare, X.sex, X.age) >>
    gather('variable', 'value', add_id=True)  # _ID列を付与
```
![gather.png](https://qiita-image-store.s3.amazonaws.com/0/318124/5183ba5b-3901-106b-0df0-913fd7e034ef.png)

##spread wide形式データへ変換する
```Python:Python：dfply-spread
#_ID列をユニークKey, variableとvalueをwide形式データに変換
titanic_wide = titanic_long >> spread(X.variable, X.value, convert=True) #convertで型を自動変換

#型タイプを見る
print(titanic_wide.dtypes)
```
![gather2.png](https://qiita-image-store.s3.amazonaws.com/0/318124/262f52e9-4eed-ffcc-6cbc-22aca5452293.png)

 ↓　データの型（convert=Falseやデフォルトだとすべてobject型になる）
_ID       int32
age     float64
fare    float64
sex      object
dtype: object

##separate 列分割
```Python:Python：dfply-separate
#検証用データ
d = pd.DataFrame(["1-a-3" ,"1-b", "1-c-3-4", "9-d-1","10"], columns=["a"])

#separate
d >> separate(X.a, ['col1', 'col2'], sep="-", fill='right', extra='merge', remove=False, convert=True)
#sep：区切り記号、何文字目かで区切るかも指定できる（図参照）
#fill：left or right 分けれなかったときの左右詰設定
#extra：drop or merge 分けきれなかったデータを落とすか、くっつけておくか
#remove：分割前列を除く
```
![separate.png](https://qiita-image-store.s3.amazonaws.com/0/318124/bb95e124-50f0-1f94-5f25-0e72da6d63e9.png)

##unite 列結合
```Python:Python：dfply-unite
#検証用データ
d = pd.DataFrame({"a": ["1", "2", "3"], "b": ["a", "b", "c"], "c": [True, False, np.nan]})

#unite
d >> unite('united', X.a, 'b', 2, sep='*', remove=True, na_action='maintain')
    #X.a, 'b', 2はいずれも列を指定するもの
    #sep：結合時に挟む文字
    #remove：結合材料列を除く
    #na_action：maintainはNaNを無視しない、ignoreは無視、as_stringで文字と認識して結合
  
```
![unite.png](https://qiita-image-store.s3.amazonaws.com/0/318124/0e38a6e1-93de-75e8-dea3-c61ae26457e5.png)


#まとめ
上記の機能（tidyr）もRデータフレーム加工ではよく使用される関数で、それも実装されているのは非常に助かりますね。dplyr使いにとってなんとありがたいライブラリなのでしょうか。
Djangoのページを追加する

# Djangoでページを作成する手順

# ディレクトリ

```
$ tree
.
project
├── instagram_report_site
│   ├── settings.py
│   ├── test.py
│   ├── urls.py ←編集する
│   └── wsgi.py
├── manage.py
├── static
├── report
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   ├── templates　←追加する
│   │   └── report
│   │       └── post_list.html
│   ├── urls.py　←追加する
│   └── views.py ←編集する
└── uwsgi.ini
```

#全体のURL 

まずはこのファイルを編集

```
├── instagram_report_site
│   ├── urls.py ←編集する
```

編集した箇所はdjango.urlsのincludeを呼び出し


```urls.py
from django.contrib import admin
from django.urls import path, include # ←includeの記述を追加

urlpatterns = [
    path('report/', include('report.urls')), # ← ここを追加
    path('admin/', admin.site.urls),
]
```

#個別のURL

個別のテンプレートを呼び出す設定をする

```
・
├── report
│   ├── urls.py　←追加して編集
・
```

```urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
]
```

```
・
├── report
│   ├── views.py　←編集
・
```

```views.py
from django.shortcuts import render

# Create your views here.
def post_list(request):
    return render(request, 'report/post_list.html', {})
```


reportの配下にtemplatesとreportのディレクトリとpost_list.htmlを作成します

```
・
├── report
│   ├── templates　←追加する
│   │   └── report
│   │       └── post_list.html
・
```

```post_list.html
<html>
<body>
    <p>Hi there!</p>
    <p>It works!</p>
</body>
</html>
```

runしているサーバーを再起動
以下のURLにアクセス

http://xxxxxx.com/report/

![ec2 18 191 62 6 us east 2 compute amazonaws com 8000 report .png](https://qiita-image-store.s3.amazonaws.com/0/187963/b4e00dfb-77ae-1212-fb69-df2c6fd99b10.png)

# 参考記事
https://tutorial.djangogirls.org/ja/django_urls/
[Vim]ステータスラインにファイル名+一つ上のディレクトリを表示する[lightline]

# まとめ

**困っていたこと**
Reactで開発していて、 `components/{Component名}/index.js` としてディレクトリをわけていたら、ステータスラインにファイル名しか表示されないと「どのindex.jsだよ！」となった。

**解決策**

Before
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90487/54b93e1c-3861-6dfd-43df-d34392080a63.png)

After
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90487/80f69385-5171-00de-d130-8c2a7ef6034f.png)

一つ上のディレクトリまで表示することにしました。

# やったこと
[lightline](https://github.com/itchyny/lightline.vim)を使っていたため、 lightlineのカスタマイズをすることにしました。

[公式READMEの"ファイル名と変更サインの間のバーを消すことはできますか？"](https://github.com/itchyny/lightline.vim#can-i-trim-the-bar-between-the-filename-and-modified-sign)を参考にしました。

**完成形vimrc**

```vimscript:.vimrc
let g:lightline = {
      \ 'component_function': {
      \   'filename': 'LightLineFileNameWithParentDir'
      \ }
      \ }

function! LightLineFileNameWithParentDir()
    if expand('%:t') ==# ''
        let filename = '[No Name]'
    else
        let dirfiles = split(expand('%:p'), '/')
        if len(dirfiles) < 2
            let filename = dirfiles[0]
        else
            let filename = dirfiles[-2] . '/' . dirfiles[-1]
        endif
    endif
    return filename
endfunction
```

**解説**
lightlineの設定を入れる変数である `g:lightline` に `component_function` という、新しい表示項目を生成、もしくは既存の項目を上書きする関数を登録する項目があります。
既存の`filename`という項目はREADMEを見る限り[^1] `expand('%:t') !=# '' ? expand('%:t') : '[No Name]'` で表示されているようなので、それを参考にカスタマイズしました。

[^1]: ソースコードの中では見つけられませんでしたが..
良いUIの影響

こんにちは、私はミカエラです。この記事では、良いユーザーインターフェイスの重要性と、それがユーザーに与える影響について説明します。

# どちらがいいですか
これはデザインの例です。
ユーザーとして、どのデザインが良いですか？
![3.png](https://qiita-image-store.s3.amazonaws.com/0/326045/c353e249-32f2-9df8-a915-0366efed1f06.png)
> *Figure 1.*
どちらがいいですか？　どちらは簡単にわかりやすい？　AかBか？

![4.png](https://qiita-image-store.s3.amazonaws.com/0/326045/ae290d19-cfc8-daf8-dd8c-02e0fbdfb33b.png)
> *Figure 2.*
どちらがいいですか？　どちらが読みやすいですか？

# 良いデザインの資質
良いUIの質は何ですか？いっしょうに見分けましょう。

- **首尾一貫　「Consistent」**： インターフェースのレイアウトとの整合性が必要です。 一貫性は、ユーザーが使用パターンを開発するのに役立ちます。これは、ユーザーが要素を簡単に習得するのに役立ちます。
- **可読　「Readable」**： デザインは読みやすいはずです。 デザイナーは、ユーザーが読みやすいフォントスタイルとフォントサイズを使用する必要があります。 Figure 2の例のように、テキストがすべての年齢層にとって読みやすいものであることが重要です。
- **アトラクティブ　「Attractive」**： アトラクティブUIは、顧客の注目を集めるのに役立ちます。　製品のインターフェースが魅力的であれば、ユーザーはそれを使用する可能性が高くなります。　人々の注意は魅力的なデザインによって簡単に捉えられます。 これがあなたのシステムが持っている品質であれば、それはそれが良いUIを持っていることを意味します。 
- **打てば響く　「Responsive」**： デザインはそれが表示するコントロールの期待される機能に従って正確に対応しなければなりません。 たとえば、ボタンに画像が表示されると予想される場合は、正確に表示する必要があります。

#良いデザインの影響
製品に記載された資質がある場合、製品はターゲットユーザーからの良いフィードバックを受け取る可能性が高い。次に良いUIの影響があります。

- **より効率的な製品またはサービスのマーケティング。** 良いUIにより、ユーザーはシステムがどのように機能するのかを理解できます。 製品マーケティングがより良くなるのを助けるです。
- **良いUIは時間を節約します。** ユーザーは、インターフェイスの使い方を考え出すためにあまりにも多くの時間を費やす必要はありません。 各コントロールは簡単に理解できます。 たとえば、ボタンなどの機能に関する十分な情報があります。 ユーザーがコントロールを理解するのが難しいと感じた場合、インターフェースはユーザーフレンドリーではありません。 彼らは使いやすい別の製品を探すかもしれません。 
- **サービスの適切なレンダリング。** 良いUIはユーザーに適切なサービスを提供できるようになります。これは、上記の良い品質をすべて組み合わせることで、ユーザーがそのコントロールを理解し、期待どおりにサービスまたは製品を使用できるようになるためです。

# まとめ
この記事は、開発者が自分のアプリケーションのユーザーインターフェイス設計にもっと注意を払うように促すためのものです。デザイナーとして、私は開発者が彼らの製品がどのように見えるかに注意を払うことが重要であると思います。デザインは顧客が新しい製品やサービスを試そうとしたときに最初に目にするものであるため、UIは製品またはサービスにとって不可欠です。 ユーザインターフェースが快適であれば、顧客が魅了される可能性が高くなります。
【Python】Falseと判定されるもの

# Falseと判定されるもの

```Python:
>>> bool(())
False
>>> bool([])
False
>>> bool({})
False
>>> bool(None)
False
>>> bool('')
False
>>> bool("")
False

""" 注意 """
>>> bool("0")
True
```
※Python 3.7.1 で確認
【教えてエロイ人】javascript の use strict と prompt

`use strict` ってよく知らなかったのですが……。

```whatyourname.html
<!DOCTYPE HTML>
<html>
  <head>
    <script>
      'use strict';
      name = prompt('What your name?', 'Jhon');
      alert(`Hello, ${name}`);
      age = 42;
    </script>
  </head>
  <body></body>
</html>
```

name は (正しく？) 代入されるケド、age の代入は `Uncaught ReferenceError: age is not defined` と (そういう意味では正しく) エラーになるのですorz

なにゆえ……。

chrome でも safari でも同様だから、ブラウザ依存じゃ無いっぽいし……。
docker imagesの中に入る際

## メモ
docker-composeで構築したimagesの中に入る際に、いつも忘れるので、記載しておく。

```
[root]~/dev# docker-compose ps
           Name                          Command               State               Ports             
----------------------------------------------------------------------------------------------------
dev_db_1          docker-entrypoint.sh postgres    Up      5432/tcp                      
dev_gitlab_1      /assets/wrapper                  Up      22/tcp, 443/tcp, 80/tcp       
dev_ldap_1        /container/tool/run              Up      0.0.0.0:389->389/tcp, 636/tcp 
dev_nginx_1       /bin/sh -c echo "REVERSE_P ...   Up      0.0.0.0:80->80/tcp            
dev_registry_1    /entrypoint.sh /etc/docker ...   Up      5000/tcp
```

上記でldapのimageに入る場合

```                      
[root]~/dev# docker exec -it dev_ldap_1 bash 
root@2bad97735422:/# cd /usr/lib/ldap
root@2bad97735422:/usr/lib/ldap#  ls -ltr 
(省略)
root@2bad97735422:/usr/lib/ldap# exit
exit
```
Bundler 2.0の変更点

先日リリースされたRuby2.6で標準ライブラリに取り入れられたBundlerですが、[2019年1月3日にv2.0.0がリリースされました](https://bundler.io/blog/2019/01/03/announcing-bundler-2.html)。
v1.17からの変更点は上記リンクに書かれているとおりですが、日本語での情報が見当たらなかったので、ここで紹介しておきます。

## Ruby 2.3以上、RubyGems 2.5以上が必須に
Ruby 2.2系のサポートは2018年3月で[終了しました](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/)。それに伴って新しいBundlerでもサポートされません。
Bundler 2.0.0ではRubyGems 3.0以上が必須とされていましたが、インストール時に問題が多発したようで、翌日にリリースされた2.0.1でRubyGems 2.5に戻されました。

## Githubからのインストール時にhttpsがデフォルトに
```ruby:Gemfile
gem 'rails', github: 'rails/rails'
```
上記のように書いたとき、今までは`git://github.com/rails/rails.git`からダウンロードしていましたが、gitプロトコルはセキュリティ上の理由から非推奨でした。
Bundler 1.17までは`bundle config github.https true`とするか、

```ruby:Gemfile
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
```
をGemfileに書くことで、httpsでダウンロードできました（[参考](http://y-yagi.tumblr.com/post/150244664010/bundler-1130%E3%81%A7gemfile%E3%81%AB-github)）。

Bundler 2ではhttpsがデフォルトになるため、こうした設定が必要なくなります。

## エラーメッセージが`STDERR`に出力されるように
```shell-session:v1.17.2
$ rm -f Gemfile*
$ bundle install
Could not locate Gemfile
$ bundle install > /dev/null
```
```shell-session:v2.0.1
$ rm -f Gemfile*
$ bundle install
Could not locate Gemfile
$ bundle install > /dev/null
Could not locate Gemfile
```

2.0ではエラーメッセージが`/dev/null`に消えていないのがわかります。
てか今まで`STDOUT`だったんですか……

## lockファイルによってv1とv2を自動で切り替え
`Gemfile.lock`を開くと、最後の方に`BUNDLED WITH`という項目があり、`bundle install`したBundlerのバージョンが記載されています（[参考](https://qiita.com/suu_g/items/2b1630b8015d51c5292e)）。
Bundler 1と2を両方インストールしている場合、`Gemfile.lock`を見て適切なバージョンのBundlerを起動してくれるそうです。


## さいごに
メジャーアップデートとは言っても、それほど大規模な変更はない印象です。

なお、Ruby 2.6.0に付属のBundlerは1.17.2です。最新バージョンを使いたい場合は`gem update bundler`をしてください。
macOSのプレビューappを使い、擬似電子捺印を実現する

ハンコの捺印自体は好きなんだけど、その前後の印刷とスキャンの手間が面倒なんだよね。

というわけで、macOSのデフォルドでついているプレビューアプリを使い、ハンコの捺印をアプリ上で行うやり方を説明する。

# 登録
<img width="868" alt="Screen Shot 2019-01-07 at 17.23.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/68213/56115c13-05fa-0e9a-f2ce-1cdec87ce2e8.png">
ここからカメラを選択して、紙に捺印した印影を写す

# 使用
<img width="533" alt="Screen Shot 2019-01-07 at 17.41.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/68213/400d520c-11d3-3b21-665b-65b80632fd21.png">
これのTの横のサインマークのところから、使用する印影（サイン）を選択する。その後、右から3番目のロの字のようなマークをクリックして赤を選択する

# 参考
https://support.apple.com/ja-jp/guide/preview/prvw35725/mac
[Git] コミット前に設定ファイルを確認する

## はじめに

開発時に「ちょっと本番データを見てみたい」とフラグをいじって、コミットする前に元に戻すのをうっかり忘れないように、今までは .gitignore を使っていました。しかし当該フラグ以外に設定ファイルを編集したいこともしばしばあること、リポジトリに含めているファイルを .gitignore に記述するのは本来あるべき運用とは思えないことから他の方法をとることにしました。

## フックによるチェック

pre-commit のフックで「あるべき設定値」のが存在していることを確認します。

後々、コミットが失敗したときに理由がわからないと困るので、フックによるチェック処理を行っている旨、最初に echo します。

```sh
#!/bin/sh

echo "hooks/pre-commit で設定ファイルを確認します。"

configFile=my_config.config

# 設定ファイルの存在を確認する。
if [ ! -e $configFile ]; then
	echo "${configFile} が存在しません。"
	exit 1
fi

# 本番環境を使用しない設定であることを確認する。
grep UseProductEnvironment=0 $configFile
if [ $? != 0 ]; then
	echo -n "Error: 本番環境を使用する設定になっています。"
	echo "コミットする際はフラグを戻してください。"
	exit 1
fi

echo "コミット OK です。"
exit 0
```

確認したいことが増えたら grep や if を増やしていけばよいかと思います。

これでうっかりコミットを防ぎます。
NETATMOのクライアント認証APIをaxiosでよぶ

NETATMOウェザーステーションが届いた！
デバイスの初期設定して管理画面からデータが自動でアップされている事を確認。
楽でいいねー

サーバーに登録されたデータ(気温や湿度）を取得するためにはAPIで`token`を取得しなければならない。

今回はそのtokenをaxiosの勉強も兼ねてjsで取得するコードを書いた。

ちなみに初めてaxiosを触ったけど、すごく手軽にAPIコールが書けて良いね！

## 公式のAPIリファレンス
クライアント認証
https://dev.netatmo.com/en-US/resources/technical/guides/authentication/clientcredentials

## コード

シンプルなお手軽版

```javascript
const axios = require('axios')
const qs = require('qs')

const axiosClient = axios.create({
  baseURL: 'https://api.netatmo.com',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

const auth = {
  client_id: 'xxxxx',
  client_secret: 'xxxxxxxxxxxxxxxx',
  username: 'xxx@xxxx,
  password: 'xxxxxx',
  grant_type: 'password'
}

axios({
  method: 'post',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  url: 'https://api.netatmo.com/oauth2/token',
  data: qs.stringify(auth)
})
  .then(respons => {
    console.log('Success')
    console.log(respons.data)
  })
  .catch(error => {
    console.log('Failure')
    console.log(error.response.config)
    console.log(error.response.data)
  })
  .then(() => {
    console.log('Complete')
  })
```

こんな書き方もできた。

```javascript
const axiosClient = axios.create({
  baseURL: 'https://api.netatmo.com',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

axiosClient
  .post('/oauth2/token', qs.stringify(auth))
  .then(respons => {
    console.log('Success')
    console.log(respons.data)
  })
  .catch(error => {
    console.log('Failure')
    console.log(error.response.config)
    console.log(error.response.data)
  })
  .then(() => {
    console.log('Complete')
  })
```
インスタンス化した方が使い回せていいね。

ログにaccess_tokenが表示されれば成功。

次はサーバーから温度/湿度/二酸化炭素の値をとる記事を書く。

## 参考url
- https://github.com/axios/axios
- https://github.com/mariusbreivik/Netatmo
- https://dev.netatmo.com/resources/technical/samplessdks/codesamples
Macを初期化して最低限必要なアプリをインストール

# 前提

5年ちかく使ってるmacbook proの動作が重すぎてつらかったので、年末年始の勢いあまって初期化しました。

[Macが重たくなったのでデータ退避して初期化インストールした](https://apple-teach.com/macroom/recovery_install/)

そして期待通り、めっちゃ早くなった。
もっと早くやればよかった。

今後も重くなったら初期化やると思うので、
作業に必要な最低限のアプリをインストールした手順を備忘録としてまとめました。

※大半が参考にしたリンクをまとめてるだけなので、詳しい手順は各リンク先にあります。

## アプリ一覧
- Karabiner
- iterm2
- homebrew
- git
- docker
- その他macの設定など

## Karabinerインストール

日本語配列のmacbookに外付けでUSキーボード使ってるので、Karabinerで設定をいじる。

[Karabiner - Software for macOS](https://pqrs.org/osx/karabiner/)
[本家 Karabiner-Elements が USキーボードの左右 Commandキーによる「英数 / かな」の切り替えに対応！ | R](https://beadored.com/the-original-karabiner-elements-command-switching-eisuu-kana/)

## iterm2インストール

ターミナルアプリ。
カスタマイズしなくてもいいけど、したほうがテンションあがるので。

[iTerm2 - macOS Terminal Replacement](https://www.iterm2.com/)
[iTerm2を快適に操作するためのカスタマイズ集 - Qiita](https://qiita.com/okoysm/items/adf36737973c4e2d0336)
[bash_completionで「-bash: __git_ps1: command not found」となった時の対処法 - くりにっき](https://sue445.hatenablog.com/entry/2012/08/30/005627)

[参考] bash_profileの初期設定

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

export CLICOLOR=1
export LSCOLORS="GxFxCxDxBxegedabagaced"

# define for PS1
black=$'\e[30m' # Black - Regular
red=$'\e[31m' # Red
green=$'\e[32m' # Green
yellow=$'\e[33m' # Yellow
blue=$'\e[34m' # Blue
purple=$'\e[35m' # Purple
cyan=$'\e[36m' # Cyan
white=$'\e[37m' # White

# display git status
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1="\u@\[$green\]\w\[$red\]\$(__git_ps1 [%s])\[$white\]> "

```

## homebrewインストール

gitとdockerインストールするのに使うやつ。

[macOS 用パッケージマネージャー — macOS 用パッケージマネージャー](https://brew.sh/index_ja)

## gitインストール

```
brew update
brew install git
```

gitのPATHがapple既存のgitに向いてたら、brewのほうにPAHTを変更する。
PATHはインストール文言中にあるので目を皿にして探しましょう。`echo ~ `ってのがあります。

### ユーザー設定

```
git config --global user.name 'yourName'
git config --global user.email 'yourEmailAddress'
```

### GitHubでssh接続する

[お前らのSSH Keysの作り方は間違っている - Qiita](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)

## dockerインストール

[とりいそぎhomebrewでDocker for Mac 1.12をインストールする - TIM Labs](http://labs.timedia.co.jp/2016/08/homebrewdocker-for-mac-112.html)

```
brew update
brew upgrade
brew cask install docker
↓これでdocker起動する or GUIで起動
/Applications/Docker.app 
```


## その他

[macOSでディスプレイ1枚で作業する技術 - Qiita](https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60)
別DBにあるテーブルのアクセス

# はじめに
複数店舗で商品情報を共通化したいとのこと。
別DBに保存してあるテーブルを参照、更新できるのか試す。
まさしく[これ](https://qiita.com/chihiro-adachi/items/bb47fa419bb13e2c339a)なのでEC-CUBE4に合わせてみる。

# Entity `@ORM\Table`

```php:app/Customize/Entity/ProductSize.php
/**
 * ProductSize
 *
 * @ORM\Table(name="eccube4x.dtb_product_size")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Entity(repositoryClass="Customize\Repository\ProductSizeRepository")
 */
class ProductSize extends \Eccube\Entity\AbstractEntity
{
  :
}
```

`@ORM\Table`のnameでDB名を付加

これで特に問題なく別DBのテーブルをアクセスできそう。

# 参照
[EC-CUBEで複数DBで会員データを共通化する](https://qiita.com/chihiro-adachi/items/bb47fa419bb13e2c339a)