OmniAICreator/Qiita-1.07M huggingface dataset:
IPv6高速ハイブリッド IPv6 IPoE + IPv4でホームゲートウェイのVPNを活用する

# IPv6高速ハイブリッドを申し込んだ
自宅の回線をYahooBBのPPPoEで接続していたのですが、最近は夜間帯でPing RTT値が一瞬100msを超えることや軽度のパケットロスが発生するようになってきたためIPv6高速ハイブリッドを申し込んでみた。

# 今までのVPN機能が使えない
Softbankから提供されるBBユニットをかましてIPv4の仮想トンネルに接続しにいくのですが、NTTから提供されているホームゲートウェイ(HGW)に搭載されているVPNサーバー機能は使いたかった。
HGWからPPPoEをすればVPNサーバーは稼働するのですが、BBユニット配下のネットワークとは異なるため自宅LANに接続できないのが非常に困りました。

# 前提
- NTT西日本
- フレッツ光隼　マンションタイプ
- ひかり電話契約あり
- ONU -> HGWの構成

ここにBBユニットを接続して高速ハイブリッド、IPv6、ひかり電話、そしてVPNを使えるようにする。

# ネットワーク構成
大まかなネットワーク構成は画像の通り

![Untitled Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/166907/a5688c15-bb8a-2cf9-a784-891cf3ef8fcf.png)

実線が物理接続
点線が仮想接続

## ポイント
- HGW
    - IPv6 RA
    - VPNサーバー
    - PPPoE(IPv4 VPNサーバー受け用)
- BBユニット
    - IPv4のDHCPサーバー
    - IPv4デフォルトゲートウェイ
    - IPv6の機能は停止　←最重要

ひかり電話契約でBBユニットをONU直下に接続するとIPv6のIPをHGWと奪い合い、IPv6不安定な状態になります。
BBユニットをHGW配下に設置し、HGWと直結するとIPv6のループが発生し動作しません。

そこで、BBユニットのIPv6機能を切り、BBユニットはIPv4、HGWにはIPv6のルータになってもらいます。

## HGW
IPv4のDHCPサーバーを切る
IPv4の自宅ネットワークのIPを何か固定で割り当てる。画像では192.168.12.2
![スクリーンショット 2018-05-17 23.17.47.png](https://qiita-image-store.s3.amazonaws.com/0/166907/ac4010cd-206e-92df-67cb-de0b7efa793e.png)

## BBユニット
IPv4のIPを設定。画像では192.168.12.1。ゲートウェイになる。
IPv4 DHCP
![スクリーンショット 2018-05-17 23.18.14.png](https://qiita-image-store.s3.amazonaws.com/0/166907/0dae8d58-c533-da82-c467-b4b729e5625c.png)

IPv6を無効化
![スクリーンショット 2018-05-17 23.16.56.png](https://qiita-image-store.s3.amazonaws.com/0/166907/d0c0fa1f-b93e-9073-bb0d-0277e577fa99.png)

# まとめ
IPv4ハイブリッド、IPv6、ひかり電話、VPN接続で自宅ネットワーク接続が最小限の構成で構築できました。

さらにひかり電話でSIP接続ができるのですかね？
自宅電話はそれほど使っていないためそれはチャレンジとして置いておきます。

しかしIPv4ハイブリッドは本当に早いです。
ピーク時間帯でも300Mbps RTTが5.5msとか出ます。

NTTのIPv6の詳細な説明は他の方が書いてらっしゃるのでそちらを参考にしてください。
調べ物で楽をするために、Ewordsのサマリー(単語の意味)を取得して返すGoogle Apps Scriptを作った


IT勉強会向けのカンペ用語集を作ろうと思ったのですが、コピペが面倒すぎてe-wordsのサマリー(単語の定義)を取得するGoogle Apps Scriptを作りました。

# ソース

```
function getEwordsSum(word) {
    var prop = PropertiesService.getScriptProperties().getProperties();

  var html = UrlFetchApp.fetch('http://e-words.jp/w/'+ word +'.html').getContentText("Shift_JIS");
  var doc = Parser.data(html)
                    .from("<div id=\"Summary\"><p>")
                    .to("</p></div>")
                    .build().replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');;
  return doc;
}
```

[Github](https://github.com/MenEnger/GetEwordsSummary)にもアップしています。

#準備
Google Apps Scriptの開発画面を開き、.gsファイルの中身をコピーします。 
次に、「ライブラリ」に「M1lugvAXKKtUxn_vdAG9JZleS6DrsjUUV」(ソース：https://qiita.com/fireowl11/items/e703e35073b600528e7c) を追加します。

# 使い方
Sheetsの任意のセルに、

=getEwordsSum("API")

みたいに入力して使います。セル範囲を指定してもokです。

# 使用例

以下のような感じで、単語集を作るのがはかどります。

![使用例](https://qiita-image-store.s3.amazonaws.com/0/95458/4b18d7bf-a8c1-0b42-22c9-fc9dee054571.png)
※ewords関数はgetEwordsSumに読み替えてください。
webpack-dev-server でビルドファイルが読み込まれない

webpack-dev-server を使おうと思ったら、なぜかビルドファイルがブラウザに反映されない。

まず気付いたのは、output に指定してるディレクトリに実ファイルが出力されてない。
が、これはそういうものらしく、webpack-dev-server でビルドされたファイルはメモリ上に（？）展開されてるらしい。

結局原因は config で、webpack-dev-server 用のパスを指定してあげないといけないことだった。
デフォルトでは `/` となっているため、output ディレクトリとして別のディレクトリを指定している場合は要設定。

例えば output で `dist/assets/scripts` を指定してる場合はこんな感じ。

```javascript
devServer: {
  contentBase: path.join(__dirname, "dist"),
  publicPath: '/assets/scripts/'
}
```
[CSS] absolute で 親要素(parent)との相対距離で位置を調整したい時に見るべきところ

`absolute` を使って ページからの絶対距離ではなく、親要素との相対距離で位置を調整したいときがあります。

`absolute` 以外の `position` を使っても相対位置の距離で調整できるんですが、 `absolute` 以外では、 **移動する前の位置に要素があったことになる** という減少があります。
そこに存在しないように位置調整したのに、続く要素がその要素が元々あった場所を避けて位置取りしてしまいます。

あ…ありのまま今起こった事を話すぜ！ 俺は要素の位置を調整したと思ったら、他の要素はそのままだった。 な…何を言っているのかわからねーと思うが(ry

みたいなことになります。

そんなときに気にするべきは、 **親要素** の `position` です。
親要素の `position` が `relative` で、子要素の `position` が `absolute` だったら、親要素の相対位置に移動します。
便利。
Google Tag Managerと連携できるConsent Manager 作りました

シンプルなConsent Managerというのを作りました、無償ですので使ってください。という話です。

## 2018年5月25日は、アドテクとユーザーの和解の日！？

[GDPR](https://ja.wikipedia.org/wiki/EU%E4%B8%80%E8%88%AC%E3%83%87%E3%83%BC%E3%82%BF%E4%BF%9D%E8%AD%B7%E8%A6%8F%E5%89%87)をご存知でしょうか？

これは、「EU一般データ保護規則」といって、ざっくりいうと、EU圏内でCookieデータとかを勝手に取ったりしたら、多額の罰金が課されるかもしれないという制度です。

これが、なんと **2018年5月25日**から施行（適用）されるのです。
私は、10年ほどWeb広告系に関わってきまして、まだ向こう岸ではありますが、とんでもなく大きな影響を予感させるニュースです。

まだEU圏でのサービスがなければ、日本企業には直接は関係ないのかもしれません。私も初めて聞いた時は、正直、少し過度（やりすぎ）な制度だと思ってしまっていました。（今となっては恥ずかしながら、です。）

でも、よく考えるとユーザーにとっては、**当たり前に必要なことではないかと（今までがおかしかっただけではないかと）気づいた**のです。

GDPRに適用させるということは、**「どんなCookieデータをどういう目的で使っていて、安全な場所に保存しています。要望があればいつでも開示するし、いつでも削除します。」**ということです。

本当に純粋にユーザーのためを想ってCookieを使っている企業もものすごく多くあるのです。
**「だったら開示しろよ」**、**「わかりました！！」**。というのは当然のことではないかと想ったわけです。

上記記事の中で以下のサイトを見つけました。普通「お問い合わせ」とかのメニューが、なんと***「SAY HELLO」。*** しかも、**「私たちはあなたからの連絡が欲しいです」**と。
<img width="1269" alt="Contact_-_CIVIC_UK_と_Markdown記法についてまとめてみた.png" src="https://qiita-image-store.s3.amazonaws.com/0/258028/1832210a-aa25-89ec-a386-a3c05c38c10e.png">

このスタンスって、すごく重要だと思うのです。ユーザーのことを考え、ユーザーの目線・気持ちで対話しようとすること。

このEUのGDPRは例えるなら、『喧嘩してるわけでもないしお互い、いろんな側面で仲の良いところもあるんだけど、なんかちょっとこじれている時がある２人の生徒（アドテクとユーザー）』をみかねて、『先生（行政）』が「もう、じゃあこうしましょう」という構図に見えたのです。「仲良くしようよ、もうお互い大人なんだから」という。

ということで、**和解の日**と読んでみました。


## ■そこで、ツールを作ってみた、というか作ってしまった・・・

と、そんなことを
ふと考えて、
少し反省して、
Consent Managerと言われる許可を取るオーバーレイ表示のものが有償なんだと知って（驚いて）、
気がついたら、作ってしまいました。今日の予定していた仕事そっちのけで。（ちょうど大きな開発が終わった切れ目だったので、完全に持って行かれました）本当にこの部分は自己嫌悪ですが。

<img width="1263" alt="日本語読みやすさ検定.png" src="https://qiita-image-store.s3.amazonaws.com/0/258028/fe457de1-5133-f656-ac4a-a637466eb921.png">


でも、ただ表示するだけだと、面白くないので・・・Google TagManagerと連携してみました。

せっかくなので、Google Tag Managerと連携して、許可した人にだけGoogle Analyticsタグを配信したり、リタゲタグを読み込ませたりを***とても簡単に***できるようにしてみたのです。
＊少し外れますが、少し応用すると、サイト内のアンケート結果に応じてタグの出しわけにも使えます・・・。この発想がこじらせる原因なわけでもありますが。

もちろん、他のタグマネツールでも使えると思います。GTMは、たまたまです。
連携といっても、DataLayerにプッシュするところだけなので２、３行しか依存してません。
もちろん、タグマネジメントツールなしでも使えます。

### ■ツールは、MITライセンスで無償開放です！多くの人に使われると嬉しいです。
ただ、勢いで作ったはいいけど、誰が使うか考えてなかったのです。そもそもEU関係ないしと思っている企業が大半かもしれません。
そこで、その不安をとりあえずGitHubにあげ、Qiitaに上げて気持ちを鎮めることにしました。

▼ツールはこちらから
https://github.com/esikm/PolicyBannerWithGTM/commits/master

あまり汚いソースコード見せるのは好きではないですが（あと下手な英語も）、今回は良いかな、と。
MITライセンスなので無償・商用利用可能、改変可能です、どんどん使ってください。必要そうな人がいたらお伝えしてみてください。
＊MITライセンスとは？　https://ja.osdn.net/projects/opensource/wiki/licenses%2FMIT_license

よりユーザーから理解を得るための企業の取り組みのひとつとして、こういう和解の対話が、日本でも広まると良いと思います。

また、***日本企業がこの個人情報データ保護の面で遅れているといわれているのも、悔しいですし***、微力ながら、その状況を改善することに繋がると良いな、と。

5.25に迫っているので、とりあえず間に合わせで使って捨ててもらえれば十分です。

必要としている人がいるといいですが。

以上、 **思いつきから、ツールを作って公開した**話でした。
ドメインをモデリングするには

調べたことをまとめておきます。
認識違いなどありましたらコメントいただけると幸いです。

---

## ドメインモデリングとは
システムに関する業務知識（ドメイン）を簡潔に整理(要約・モデル化)し、その関係性がわかるようにすること

---

### なんのためにやるの？
- ドメインに対する理解を深める
- メンバー内でドメインに対する認識を合わせる

---

### 具体的には何をやるの？
- 業務用語集を作る
- 業務用語の関係図を描く

---

## 業務用語集を作る

---

### まず業務を知る
1. マニュアルや利用者ガイドを読んでみる
2. 業務の一般的な知識を書籍などで勉強する
3. どんなデータがあるか画面やファイルを調べる
4. 業務経験者（ドメインエキスパート）と会話する

---

### 業務内容から名詞句を集める
- 業務内容を文章で書き、そこから重要そうな名詞句（ヒト、モノ、コト）を抜き出す
- 特にコトに注目するとそれぞれの複雑な関係を紐解きやすい

---

|分類|事例|
|:--|:--|
|ヒト|個人、企業、担当者など|
|モノ|商品、場所、権利、義務など|
|コト|予約、注文、キャンセルなど|

---

### 例
> アカウントに対して更新権限を持つユーザーは、アカウント配下にキャンペーン、その配下に広告グループ、その配下に広告とキーワードをそれぞれ登録できなければなりません。

---

 ↓

> **アカウント**に対して**更新権限を持つユーザー**は、**アカウント**配下に**キャンペーン**、その配下に**広告グループ**、その配下に**広告**と**キーワード**を**それぞれ登録**できなければなりません。

---

- ヒト
 - 更新権限を持つユーザー
- モノ
 - アカウント、キャンペーン、広告グループ、広告、キーワード
- コト
 - （キャンペーン|広告グループ|広告|キーワード）を登録する

---

## 業務用語の関係図を描く
- クラス図のように集約と汎化で関係付けていく
- 集約（A has-a B）
  - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/5514/cdca286b-f571-ac7b-9cd0-433edd0780d1.png)
- 汎化（A is-a B）
  - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/5514/73d8b467-4c1a-3d08-7660-2b0f02a2c91d.png)

---
### 例
※ただしこの図は正しくありません
￼![image.png](https://qiita-image-store.s3.amazonaws.com/0/5514/e419111b-f0a6-ab61-b925-4e7488a32e3c.png)

---

## 注意点
- 正しさを求めすぎない
  - キリがないため。最初は2時間以上かけない。
- 細かく書きすぎない
  - 大事なのは全体を網羅すること、一部に集中しすぎると全体が見えにくくなる。
- データモデルにはしない
  - DBやモノに注目しすぎるとデータモデルになってしまう。それよりも大きい枠組みで業務の関心ごとを捉える。（コトに注目するとやりやすい）

---

## ドメインモデリングのゴール
ない。
ドメインモデリングは変化し続ける業務ロジックを追って、常により良い認識（解答）を探し続けていく。

---

## DDDの次のステップ
- ユースケース図を作ったりロバストネス解析をやってドメインモデル図を精錬していく
- ドメインモデル図をそのままコードに落としていく。（ここも難しいらしい）

---

## まとめ
- ドメインモデリングとは、業務知識を要約し、関係性を明らかにすること
- 業務内容の名詞句（特にコト）に注目しながらドメインを洗い出す
- いっぺんに完璧を目指さず、常に改善し続ける

---

## 参考文献
- [現場で役立つシステム設計の原則](https://www.amazon.co.jp/dp/477419087X) 
- [ユースケース駆動開発実践ガイド](https://www.amazon.co.jp/dp/4798114456)
- [日本語のドメイン駆動設計 (Domain-Driven Design - DDD) 関連記事まとめ](http://create-something.hatenadiary.jp/entry/2018/04/24/213840)
Laravel Credentials Package (暗号化した認証情報をVCSに保存）

## 元の記事
[Laravel Credentials Package for Encrypted Application Secrets](https://laravel-news.com/laravel-encrypted-credentials)

## はじめに
この投稿は↑の記事を和訳したものです。

## 本文
GitHubなどの[VCSから認証情報などを削除する](https://help.github.com/articles/removing-sensitive-data-from-a-repository/)のは、VCSに対して開胸手術をするようなもので、どうにかして避けたいものです。その一方で
、機密情報をVCSで管理するのは、最新の注意を払って行うのであれば、変更履歴をトラックする場合などにとても便利です。

Laravel Credentials は[Marcel Pociot](https://github.com/mpociot)によって作成された、Laravelのプロジェクトにおいて、機密データを安全に管理するのを助ける新しいパッケージです。

## Laravel Credentialsの利点

* 認証情報は暗号化されているため、鍵なしでは誰も認証情報を読み取ることができません（もちろん、鍵をGitHubなどのVCSに保存しなければの話ですが）。
* 暗号化された認証情報がVCSに保存されているので、変更履歴を見る事ができる。
* コードの変更と一緒に更新された認証情報もデプロイする事が可能です。
* 機密情報が一箇所で管理できる。

認証情報は暗号化されていて読み取るためには鍵が必要なのですが、変更があった場合などにどのようにして認証情報を更新すればよいのでしょうか？

## Laravelの認証情報を編集する
IDやパスワードなどの認証情報を編集するには、Laravel Credentialsパッケージが提供する下記のartisan コマンドを実行する。

```bash
php artisan credentials:edit
```

認証情報が更新されると、新規に暗号化されたバージョンが認証情報ファイルに保存されます。デフォルトの状態では、ファイルは`config/credentials.php.enc`に保存されます。この認証情報ファイルはヘルパー関数を利用して読み取る事ができます。

## Laravelの認証情報を利用する
暗号化された認証情報にアクセスするには、ヘルパー関数である`credentials()`を利用する。

```php
$credential = credentials('api-password');
```

## パッケージをインストールする
Laravel Credentialsパッケージを利用するには、Composer経由で下記のようにインストールしてください。

```bash
composer require beyondcode/laravel-credentials
```

設定ファイルを作成したい場合には、以下のartisanコマンドを実行してください。

```bash
php artisan vendor:publish --provider="BeyondCode\Credentials\CredentialsServiceProvider" --tag="config"
```

## 詳しく知りたい方へ
Laravel Credentials パッケージについて詳しく知りたい方は、GitHubの[beyondcode/laravel-credentials](https://github.com/beyondcode/laravel-credentials) のソースコードをご覧になってください。

[Ansible Vault](https://docs.ansible.com/ansible/2.5/user_guide/vault.html)を使った事がある方なら、既に機密性の高いデータに対してファイルを暗号化する手法をご存知かもしれません。
2017.4.2f2で、AssetStore版のUnityAdsが、ビルドイン版をオフにしても、"defined multiple times"コンパイルエラー

AssetStore版のUnity Adsを使おうとすると、こんなコンパイルエラーに遭遇することがあります。

```
By the way, the compiler shows compile error with the message that is "Assets/Example.cs(8,9): error CS0433: The imported type `UnityEngine.Advertisements.Advertisement' is defined multiple times".
```

で、これの原因は「Unity EditorビルドインのUnity Ads」と「Asset Storeから入れたUnity Ads」とで衝突を起こしているからです。これを抑制するためには、ビルドインのUnity AdsをオフにしてあげればOKです。

詳細は、Unity Technologies Japanの「[Unity Ads導入時に「The imported type `UnityEngine.Advertisements.Advertisement' is defined multiple times」というエラーが表示される](https://helpdesk.unity3d.co.jp/hc/ja/articles/115005773427-Unity-Ads%E5%B0%8E%E5%85%A5%E6%99%82%E3%81%AB-The-imported-type-UnityEngine-Advertisements-Advertisement-is-defined-multiple-times-%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B)」を見てください。


で、普通は↑の通りやればコンパイルエラーは解消するんですが「`2017.4.2f2`」だとどうやら、ビルドインのUnity Adsをオフにしてもコンパイルエラーのままでダメっぽいです。

自分の手元で最小構成でも再現したし、UnityのIssue Trackerにこんなのがありました。

["THE IMPORTED TYPE `UNITYENGINE.ADVERTISEMENTS.(...)' IS DEFINED MULTIPLE TIMES" FOR ADS SDK ASSET STORE PACKAGE IN 2017.4.2F2](https://issuetracker.unity3d.com/issues/the-imported-type-unityengine-dot-advertisements-dot-dot-dot-dot-is-defined-multiple-times-for-ads-sdk-asset-store-package-in-2017-dot-4-2f2)



残念ながら、より新しいLTSの`2017.4.3f1`でも修正されなかったぽいです。

本稿執筆時には、Issueは「Fix in review」ってステータスなので、もうちょい待ちましょうか。
Git覚書

###特定のブランチからクローンする場合
$ git clone -b ブランチ名 [repositoryのアドレス]
###特定のバージョンに戻す場合
1, ローカルにターゲットブランチのレポジトリをクローンする
2, リモートgitにあるハッシュタグを[#hash]とすれば、
3, $ git checkout [#hash]
で、ローカルレポジトリがその時のバージョンになる。
Ubuntu18.04で複数ネットワーク+Static Routeの設定

[Ubuntu16.04で複数ネットワークの設定](https://qiita.com/devzooiiooz/items/256e41c9cfccd00fd593)
の18.04版。
Ubuntuは17からネットワーク設定が/etc/network/interfacesではなく/etc/netplanに変わった。

#環境
Ubuntu18.04(Windows Server2012 r2内のHyper-V上）
Hyper-Vの仮想スイッチマネージャーで複数のNICを設定
（NICが複数ある実サーバでも可）

#ネットワーク構成
IPアドレスとネットワークアドレス
eth0(NIC#1)に192.168.1.1/24(WAN側）
eth1(NIC#2)に10.10.0.1/16(内部側）
を割り当てる。

スタティックルートとしては以下のような構成とする。
10.0.0.0/8（つまり第一オクテットが１０の場合）はNIC#2のルータに
その他の場合(WAN:インターネット)はNIC#1を通る。
スタティックルートはroute addでもいけると思うが、
netplanで設定する方法としての一例。

```
INTERNET
|
192.168.1.254(デフォゲ・ルータ）
|
192.168.1.1/24(eth0,NIC#1)
Ubuntu18.04
10.10.0.1/16(eth1,NIC#2)
|
10.10.0.254(NIC#2側のルータ)
```
#ネットワークの確認
```sh:sh
$sudo lshw -short -class network
```
このような表示が出てくる

```sh:
H/W path        Device      Class      Description
==================================================
/1              eth0        network    Ethernet interface
/2              eth1        network    Ethernet interface
```
#/etc/netplan/
50-cloud-init.yamlというファイルがあるが、
「cloud-initはAWS EC2 などの cloud instance に対して、設定や拡張性を提供するためのパッケージです」
らしい。
参考：https://hiroki.jp/config-cloud-init

名前がそぐわない気がするので、これはこれでバックアップとし、
network.yamlファイルを作ってやる。
※netplanは/etc/netplanにある*.yamlファイルを読み込むので*.yaml_bakはスルーする。

```sh:/etc/netplan
sudo cp 50-cloud-init.yaml network.yaml #コピー
sudo mv 50-cloud-init.yaml 50-cloud-init.yaml_bak #バックアップ
```

以下は/etc/netplan/network.yamlで話を進める

```sh:
sudo pico /etc/netplan/network.yaml
```
ipアドレスはipv4のみとします。

```sh:/etc/netplan/network.yaml
network:
    version: 2
    renderer: networkd
    ethernets:
        eth0:
            addresses: [192.168.1.1/24]
            gateway4: 192.168.1.254
            nameservers:
                addresses: [192.168.1.254]
            dhcp4: no
            dhcp6: no
        eth1:
            addresses: [10.10.0.1/16]
            dhcp4: no
            dhcp6: no
            routes:
            - to: 10.0.0.0/8
              via: 10.10.0.254
```
注意点

１．デフォゲを明確にするため、eth0のgatewayのみ記載する。
２．yamlファイルなのでスタティック・ルーティングの記載は、インデントに気を付けること。インデントにtabは使わない。半角スペースで。
３．加えて、インデントを間違うとSyntaxエラーになる。
例えば routes:の次行の「- to:」はインデントするとNG。routes:と同じ階層にする。

```sh:
#以下はダメな例
routes:
  - to: 10.0.0.0/8
  via: 10.10.0.254
```

#設定の反映
書式チェックもしてくれる。

```sh:
sudo netplan apply
```
Webpack4 を使って webpack-dev-server のベーシック設定

# 経緯
本番用には `webpack-cli` でビルドして、開発環境では `webpack-dev-server` というあるあるなビルドの仕組みを作った時に、 `webpack-dev-server` では `dist` ができずにちょっと悩んだので、簡単に記載しました。

`webpack4` もまだあまり試していなかったので、ついでにと思ってやってみました。

# code

```package.json
{
  "name": "sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "rm -rf dist && NODE_ENV=development webpack-dev-server --open --config ./webpack.config.js --hot --inline",
    "build": "rm -rf dist && NODE_ENV=production  webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "copy-webpack-plugin": "^4.5.1",
    "webpack": "^4.8.3",
    "webpack-cli": "^2.1.3",
    "webpack-dev-server": "^3.1.4",
    "write-file-webpack-plugin": "^4.3.1"
  }
}

```


```webpack.config.js
const path              = require('path');
const webpack           = require('webpack');
const WriteFilePlugin   = require('write-file-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const NODE_ENV = process.env.NODE_ENV;


module.exports = {
	context: path.resolve( __dirname, './src'),

	mode : NODE_ENV || 'production',

	devServer: {
		port: 3000,
		contentBase: path.resolve( __dirname , './dist' )
	},

	entry: {
		bundle : [ './js/index.js' ]
	},

	output: {
		filename : '[name].js',
		path: path.resolve( __dirname , './dist/js' )
	},

	module: {
		rules: [
			{
				test: /\.jsx?$/,
				exclude: /node_modules/,
				use: [
					{
						loader: 'babel-loader',
						options: { presets: ['env'] }
					}
				]
			}
		]
	},

	resolve: {
		extensions: ['.js', '.jsx'],
	},

	plugins: [
		new WriteFilePlugin(),
		new CopyWebpackPlugin( [
			{ from: '*.html', to: path.resolve( __dirname , './dist' ) }
		]),
		new webpack.DefinePlugin({
			'NODE_ENV': JSON.stringify( NODE_ENV ),
		})
	]
}

```

## 今後
sass もコンパイルする設定を足したいので、今度余裕がある時にでも。
急にGitにCloneもPushもできなくなった話

先日まで使えていたGitへのPUSHができなくなった
それどころかCloneもできなくなった

え！このマシン、サブマシンだから超困る！！

となってすごくテンパったので、ひとまずエラー回避する方法を載せます。
**が、根本的な解決になっていない気がするので、そこらへんご注意を**

## 問題の様子

>fatal: unable to access 'https://github.com/XXXXXXX/XXXXXXXXX.git/': schannel: next InitializeSecurityContext failed: >Unknown error (0x80092012) - �����̊֐��͏ؖ����̎�����m�F�ł��܂���ł����B

<img width="717" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/85214/292e77d8-ec84-acc8-2029-6310c924825e.png">

## 対処療法的なもの

[参考](https://confluence.atlassian.com/fishkb/unable-to-clone-git-repository-due-to-self-signed-certificate-376838977.html)

>git config --global http.sslVerify false

参考サイトの下の方のものを実行すればいけるのかもしれませんが、サブマシンですし、わたしは諦めました...
おしえてえろいひと

## 備考

とりあえず英語なんてすっとばして[こちらのissueコメント](https://github.com/desktop/desktop/issues/2471#issuecomment-367140028)を初めに試したのですが、結局証明書がうんぬんのエラーに変わっただけでダメでした。
Objective-C のコードの Swift Interface を確認する



補完機能がないとコード書くのつらい体になっていますが
補完がうまくきかなかったりして Objective-C のコードを Swift から呼び出す時にために Swift でどうやって呼び出せばいいか分からない時があります。

そんな時はここ↓

![Screen Shot 2018-05-17 at 23.37.55.png](https://qiita-image-store.s3.amazonaws.com/0/27210/cf654cf8-94b1-2b24-1e33-78765316e8b8.png "Screen Shot 2018-05-17 at 23.37.55.png")

メニューを開いて、

![Screen Shot 2018-05-17 at 23.38.12.png](https://qiita-image-store.s3.amazonaws.com/0/27210/ff5ac9e2-d89d-f08e-ac4f-854b0568cc1a.png "Screen Shot 2018-05-17 at 23.38.12.png")

赤丸部分のボタンをクリックして→「Generated Interface」を選択。

![Screen Shot 2018-05-17 at 23.38.36.png](https://qiita-image-store.s3.amazonaws.com/0/27210/111923cc-b97a-e44a-25de-63ac5fd1e6a1.png "Screen Shot 2018-05-17 at 23.38.36.png")

超便利！
Seleniumで画面遷移した後の画面で要素が取得できない問題の解消

最近PythonでSeleniumを使い始めたんですが、
ちょっとハマったことがあったのでメモ程度に残しておきます。


## 元のコード
```login.py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("サイトのログインページ")

elem_search_word = driver.find_element_by_css_selector("IDのフォーム")
elem_search_word.send_keys(id) # IDを入力する

elem_search_word = driver.find_element_by_css_selector("PASSWORDのフォーム")
elem_search_word.send_keys(password) # パスワードを入力する
elem_search_btn = driver.find_element_by_css_selector("ログインボタン")
elem_search_btn.click()

elem_text = driver.find_element_by_css_selector("ログイン後のページの要素")
...

```

こんな感じで、
・サイトのログインページに飛んで、
・フォームにIDとPASSを自力で入力して
・ログインボタンを押してログイン後のページに飛んで
・ログイン後画面の要素を取得する
というプログラムを書いていました。


```
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"ログイン後ページの要素"}
```

ところが、このプログラムを実行すると上記のエラーが発生。
ちゃんとログイン後ページのCSSセレクタは合ってるのに見つからないと怒られてしまう。


## 原因を調査する

試しにCSSセレクタのところをXPathとかにしてみてもやはりダメだったので別の手段を取ることに。

```
driver.current_url
```
というメソッドを使うことでその時点でのURLを取得できるということを発見。


```login.py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("サイトのログインページ")

print(driver.current_url) // URLを確認する

elem_search_word = driver.find_element_by_css_selector("IDのフォーム")
elem_search_word.send_keys(id) # IDを入力する

elem_search_word = driver.find_element_by_css_selector("PASSWORDのフォーム")
elem_search_word.send_keys(password) # パスワードを入力する
elem_search_btn = driver.find_element_by_css_selector("ログインボタン")
elem_search_btn.click()

print(driver.current_url) // URLを確認する

elem_text = driver.find_element_by_css_selector("ログイン後のページの要素")
...

```

ということで、こんな感じでプログラムを書き直してちゃんとURLが合っているかを確認してみた。
そうすると、
1つ目は期待値通りログインページだったものの
2つ目も同じくログインページのままになっていた。(本当はログイン後のページであってほしかった)

この辺りで、画面が切り替わる前にログイン後ページ向けの処理が行われてしまっていることをようやく理解できた。

## 修正後のコード
```login.py
from selenium import webdriver
from time import sleep　// 新しくインポート

driver = webdriver.Chrome()

driver.get("サイトのログインページ")

elem_search_word = driver.find_element_by_css_selector("IDのフォーム")
elem_search_word.send_keys(id) # IDを入力する

elem_search_word = driver.find_element_by_css_selector("PASSWORDのフォーム")
elem_search_word.send_keys(password) # パスワードを入力する
elem_search_btn = driver.find_element_by_css_selector("ログインボタン")
elem_search_btn.click()

sleep(5) // 読み込みを待つために５秒間処理を止める

elem_text = driver.find_element_by_css_selector("ログイン後のページの要素")
...

```

画面が切り替わってから要素の読み込みを行えば問題ないだろうという仮説が立ったので、
sleep()を使うことで読み込みのための空き時間を作った。

こうすることで無事ログイン後ページを読み込んだ上で要素取得の処理が走り、
意図した動作をするようになった。
Rmarkdownに.Rprofileの内容を追加する

# はじめに

科学の再現性が改めて重視される世にあって、Rmarkdownの便利さもより強く認識される日々です。

例えば、@kohske さんが「再現可能性のすゝめ」というRmd本を執筆しました。
https://qiita.com/kohske/items/3e8c02e9598c6d230a47

ちなみにまだ買ってもいません…………。

このため、同書で言及されているかは知りませんが、Rmdを使って再現性を確保していくにあたって、問題となりうることの一つに

.Rprofile

があります。

これは、R起動時に実行したしスクリプトを書いておくところで、

- CRANミラーの選択
- ライブラリの読み込み
- メッセージの表示

などなど、いろいろなことができます。

.Rprofileをホームディレクトリに置いて、オレオレR環境を整備しておくと便利なのですが、Rmdのknit時にも読み込まれてしまうため、異なる環境で同じRmdファイルをknitしても同じ出力が得られるとは限りません。

しかし、.Rprofileをうまく使うと、Rmdファイルを作成する度に読み込むパッケージを羅列する必要がなくなるので便利です。

どうしたら、再現性を保ちつつ、.Rprofileを運用できるのでしょうか。

# working directoryに.Rprofileを置く

working directoryに.Rprofileを置くと、それはホームディレクトリ下のものよりも高い優先順位を持ちます。
RStudio上でプロジェクトを管理しているならば、プロジェクトディレクトリ = working directoryなので、そこに.Rprofileをコピーするといいでしょう。
ディレクトリを丸ごと別環境に移しても.Rprofileの内容が再現されます。

これで子chunkだけを実行する時も、必ず実行したいコードは.Rprofileに仕込めばOKですね!

# Rmd内に、.Rprofileをインポートする

発展的には、プロジェクトディレクトリに置いた.RprofileをRmdファイルにインポートすると、出力(htmlなど)で.Rprofileの内容も確認できて便利です。
これには少々工夫がいります。

`source('.Rprofile')` では、.Rprofile中のソースコードが出力に表示されないためです。

`child = '.Rprofile'` も.RprofileがRmdファイルではないがために愉快な出力になります。

## そこで下記のようにします

### .Rprofileの編集

冒頭に `## @knitr rprofile` を追記し、Rmdから.Rprofileを取り込めるようにしましょう([参考](https://qiita.com/yu-iskw/items/ad6e18b65ae33d90d00a
))。

```r:.Rprofile
print('Printed before knit, but not during knit') # if yout want this code to be printed, set eval = TRUE for rprofile chunk in Rprofile.Rmd
hello <- 'hello world' # Although nothing in thi chunk is printed, same codes are evaluated as .Rprofile, hence you can refer to object "hello" later.
```

繰り返しになりますが、プロジェクトディレクトリに置いておきます。

### .Rprofileを取り込むRmdファイルを作成

下記のように Rprofile.Rmd を作成しましょう。

~~~r:Rprofile.Rmd
```{r, include = FALSE}
knitr::read_chunk("script.R")
```　
↓ here is the content of .Rprofile
```{r rprofile eval = TRUE}
```　
↑ here is the content of .Rprofile
~~~

ここで何をしているかは @yu-iskw さんの

[Knitr で外部の R スクリプトの取り込む方法](https://qiita.com/yu-iskw/items/ad6e18b65ae33d90d00a)

を参考にしてください。

### メインのRmdからrprofile.Rmdを呼び出す

~~~r:main.Rmd
```{r child = 'Rprofile.Rmd'}
```　
~~~

### knitする

出力はこんな感じ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149890/80a6cdfc-5394-48a5-af72-4f36de2941e4.png)



ちなみに、Rmdを子chunkに分割した時、子chunkで `child = 'rprofile.Rmd'` を行う必要はありません。
そうせずとも、テスト用の子chunkをknitした時も、.Rprofileの読み込みは行われます。
.Rprofileの中身を見せる必要があるのは、親chunkに出力だけだと思います。


# Enjoy ([ソースコードはGitHub](https://github.com/atusy/reproducibleRmd))
glot.io上でGo言語を複数ファイルに分けてコンパイル


[glot.io](https://glot.io)という様々な言語のスニペットを実行・保存出来るサービスでGo言語を複数ファイルに分けた状態でコンパイルする方法についてまとめる。
Go言語で複数ファイルに分割する方法自体についての説明は省く。

# 同パッケージ(main)の場合

例: [Golang package test1](https://glot.io/snippets/f14byjjmyb)

## ファイル

glot.ioで複数ファイル(main.go、dio.go)を作成した場合、以下のディレクトリ構成になっている。

```
.
├── dio.go
└── main.go
```

同パッケージ(main)でコンパイルする場合の例

```go:main.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello World!")
    PackageTest()
}
```

```go:dio.go

func PackageTest() {
    fmt.Println("dio.go")
}
```

## glot.ioの設定

![WS000374.JPG.png](https://qiita-image-store.s3.amazonaws.com/0/136134/f0f5d175-9b23-fcec-fa84-f4a0573cfb85.png)

Gopherのアイコンをクリック

![WS000376.JPG.png](https://qiita-image-store.s3.amazonaws.com/0/136134/cee8853d-f31b-225d-a40d-e1a3eebc69b9.png)

Run Commandのチェックを入れて以下に変更

```shell-session
go run main.go dio.go
```
Runボタンを押す

# 別パッケージに分割する

例: [Golang package test2]()

## ファイル

dio.goを別パケージとする場合は以下のようなディレクトリ構成になればよい。

```
.
├── dio
│   └── dio.go
└── main.go
```

glot.ioの実行はDocker上(Goの場合ubuntuイメージ)で行われており、基本的なコマンド、シェルスクリプトも実行できる。そのため上記のディレクトリ構成でコンパイルするようにスクリプトを書いてあげればよい。

```shell-session:run.sh
#!/bin/bash

mkdir dio
mv dio.go dio

go run main.go
```

同パッケージ(main、dio)でコンパイルする場合の例

```go:main.go
package main

import (
    "fmt"
    "./dio"
)

func main() {
    fmt.Println("Hello World!")
    dio.PackageTest()
}
```

```go:dio.go
package dio
 
import (
    "fmt"
)
 
func PackageTest() {
    fmt.Println("dio.go")
}
```
## glot.ioの設定

![WS000375.JPG](https://qiita-image-store.s3.amazonaws.com/0/136134/2da76836-40a7-8a96-3325-42e39b57affe.jpeg)

Run Commandを以下の様に変更してRunボタンを押す。

```shell-session
bash ./run.sh
```
今更Zenfone2 LaserにカスタムROMを入れてみた

#Zenfone2 Laser カスタムROM化のまとめ


##何故書こうとおもったか
　カスタムROM化する情報は数々あれど一貫した流れがよくわからなかったので備忘録的な意味も含めてまとめます。
　残しておかないと一瞬で忘れそう。。。
　一番ハマったのはTWRP&SuperSUのインストールです。
　TWRPの役割とかそもそもboot.imgにパッチを当てるイメージを持ってなかったので、
　最初は参考サイトを読んでも意味不明でした。（mod_boot.imgとかで一気に入れ替えるもんだと思っていた。



##いざ、カスタムROM化への道

###●端末のUSBデバッグを有効化（abdで端末の操作を可能とするため）
　以下のサイトを参考に開発者向けオプションを表示し、USBデバッグを有効にしておく。

　参考：https://sqool.net/zenfone-2-laser-developer-option.html


###●Android SDK Platform-ToolsをPCにインストールし、PCでadbを使用可能にする
　以下のサイトを参考にAndroid SDK Platform-Toolsのダウンロードからインストールを行う。

　参考：https://www.orefolder.net/blog/2017/03/platform-tools/


###●アンロックブートローダーを端末にインストール
　DLサイト：https://www.asus.com/jp/Phone/ZenFone-2-Laser-ZE500KL/HelpDesk_Download/

　ASUSの公式サイトよりアンロックブートローダーをダウンロードする。
　<img src="https://qiita-image-store.s3.amazonaws.com/0/177083/b6b42a36-aae7-dc4b-37b4-0bb9699965f6.png" width=50%>

　ダウンロードしたapkを以下のadbコマンドで端末にインストールする。
　コマンド：adb install ダウンロードしたapkファイル名
　※このときUSBで接続しておくことを忘れないこと

　他にも方法(sdカード経由など)はありますが、とりあえずコマンドでインストールします。
　参考：http://www.adakoda.com/android/000218.html

##端末でアンロックブートローダーを起動し、アンロック
　端末から「Device Toolのロック解除」を選択し、アプリを起動。
　その後は案内通りに操作してアンロック。

　参考：https://gato.intaa.net/archives/5696

##TWRP(カスタムリカバリ)&SuperSU(ROOT化ツール)をインストール
　以下のサイトを参考にTWRPをインストールを行い、TWRPからSuperSuをインストールする。
　これでboot.imgにSuperSUのパッチがあたり、ROOT化されます。
　※確かにtwrp-3.0.2.0-Z00E-MM.imgとUPDATE-SuperSU-v2.65-20151226141550.zipでないとうまくいかないので注意

　参考：http://stylefreelife.com/gadget/smartphone/zenfone2-laserze500kl-mashmallow%E3%82%92root%E5%8C%96%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F-1285/

##TWRPで現在状態のバックアップ
　カスタムROMを入れる前に以下のサイトを参考に現在の状態をバックアップする。
　※フルバックアップすると当然のことながら現在使用分の容量を食うのでSDカードなどに余裕を持たせておいたほうがよいです。
　　カスタムROMインストール時に何か失敗したらリストアして下さい。
　参考：https://pckda.com/2017/08/twrpbackup


##カスタムROMとOpen GApps(Google関係のアプリ)のインストール
　今回は以下のサイトを参考にLineageOS 14.1とOpen GAppsを入れました。
　GAppsはARM64を入れるべきなのにARMを入れようとしてハマりました。。。
　参考：https://kimagure.blog/construct-remodeling/customrom-lineageos-14-1


##終わりに
　ここまでで終了です。
　スムースにいけばLineageOS 14.1が使えるようになってるはず。
Androidアプリでの連携認証でTwitter OAuth callback URLのホワイリスト化に対応する

# ※追記
コメントで教えてもらったのですが、ホワイトリストは
`yourapp://`
と書けば受け付けてくれました…
@yamasa さん、ありがとうございます

---
以下は古い内容となります

# やり方
* 認証するAndroidアプリが受け取れるリンクに、渡されたlocation.searchをくっつけてlocation.hrefで飛ばすページを作る
* そのURLをTwitterのホワイトリストに登録する
* そのURLを今まで通り認証時にパラメーターで渡す

# 実装例
コールバック先のページのJavaScript

````javascript
if (location.search === ""){
 //ただ閲覧されたときに移動するページ
 location.href="URL";
} else {
 //URLに?oauth_verifier=...があった時にアプリに飛ばす
 location.href="yourapp://path"+location.search;
}
````

アプリのマニフェストに設定するintent filter

````xml
<intent-filter>
 <action android:name="android.intent.action.VIEW" />
 <category android:name="android.intent.category.DEFAULT" />
 <category android:name="android.intent.category.BROWSABLE" />
 <data android:scheme="yourapp" />
</intent-filter>
````

# 説明
いままでコールバックURLは認証時に自由にパラメーターで渡すことができたため、Androidアプリで独自スキームを設定し、それを捕まえるようにしてoauth_verifierを受け取ることができました。しかし2018-06-12をもってホワイトリストに登録したURL以外を指定できなくなります。
しかし、ホワイトリストにはhttpsで始まるURL以外は入れさせてくれません。
なので、どこか（GitHub Pages等）に、アプリにリダイレクトするページを作りそのURLを設定しました。
もっといいやり方があったら教えて頂けるとありがたいです。
# 文献
[Sign in with Twitter users must whitelist callback URLs - Announcements - Twitter Developers](https://twittercommunity.com/t/sign-in-with-twitter-users-must-whitelist-callback-urls/105342)

# 更新履歴
* 実装例の追加
* 記事先頭に追記
Gitのremote add originでfatal: remote origin already exists.と出るとき

Gitでリポジトリを作ろうとして

```
git remote add origin <URL>
```

とうって次のエラーが出ると萎える．

```
fatal: remote origin already exists
```

すでに存在しますって言われてもいや，今作ったところですやん．

仕方がないので**set-url**でURLを変更したことにする．

```
git remote set-url origin <URL>
```

これ起きたり起きなかったりするんだけどなんなんですか?
1分でわかる（はず）のCNNの説明（実績あり）

最近の流行りに乗って、DeepLearningをかじってますが、知人（同様に初心者）から、CNNはなんでうまく行くのか分からないと言われて、自分なりの解釈を説明したところ、１分で概要が分かったと言われたので、気をよくしてQiitaにも投稿してみることにしました（個人的な解釈ですので、間違っていたらお手柔らかにご指摘ください）。

##　まず、Filter, 特徴量とは何か
まず、[この記事](https://qiita.com/icoxfog417/items/adbbf445d357c924b8fc)のとおり、DeepLearningが有名になる前から、画像認識は研究されており、そこでは、Filterというものを使って特徴量を認識していました。

+ 例えば、リンク先の通り、微分もFilterで表せます.-1, 0, 1というFilterを使えば、

```math
1 \times y(x+1) + (-1) \times y(x-1)
```
ってなりますので。

+ Filterを使って変換した結果は特徴量と呼ばれています。
+ DeepLearning以前の画像認識では、どのようなFilter使って特徴量を出せばうまく画像が認識できるかが色々考えられていました。

## CNN層=画像にFilterをかけるということ
次に、CNN層の定義とFilterの定義を少し見ればわかるとおり、CNN層=画像にFilterをかけているっていうことになります。

+ 上記のDeepLearning以前の画像認識の仕組みを真似したってことですね。
+ ただし、ここでは、人間がFilterを考えるんじゃなくって、データに合わせてFilterを自動的に作るようにしたと解釈できると思います。
+ ということで、CNNは、たまたま考えついたというよりは、誰かが、もともとあった画像認識の仕組みをdeep learningでやらせようと思って自然に思いついたものなんじゃないかなと思います。

## Pooling層について
CNNでは、Pooling層を用いて画像のサイズをどんどん小さくして行ってると思いますが、この解釈は以下の通りです。

+ これも画像処理では有名な話っぽいですが、普通に画像を間引いてサイズを小さくするとノイズが入ってしまったりしますが、Filterを適用しながら画像のサイズを小さくすると、画像の情報を減らさないで画像を縮小できます。詳細はGaussian Filterとかで検索してお調べいただければ出てくると思います。
+ なので、CNNでは、畳み込みをしながら画像のサイズをどんどん小さくしていってます。
+ もともとの画像のサイズに近い層は、細部を識別するのに使っていて、サイズを小さくしたほうの層は粗いパターンの識別をするのに使っているということだと思ってます。（細かいところは見れなくなるので）

## 最後に
既存の仕組みで、もともとは人間が試行錯誤で考えていたFilterの作成をデータに合わせて自動的に行わせるようにしたというのは、まさに人工知能っぽいな〜と思いました。以上、殴り書きで失礼しました。
ESXi 6.5 から ESXi 6.7 へのお引越しメモ


自宅メインサーバの[ProLiant DL380 Gen7](http://h50146.www5.hpe.com/products/software/oe/Linux/mainstream/product/hardware/pl_dl380g7/)から[ProLiant ML350p Gen8](http://h50146.www5.hpe.com/products/software/oe/Linux/mainstream/product/hardware/pl_ml350p_gen8/)へのリプレース時のメモです。

# いつもの
* 素人のメモだよ
* バージョンとか環境によって上手く行かなかったり、データが飛んだりするかも知れないよ
* バックアップはちゃんととってね!

# 対象
ESXi 6.5 → 6.7でやってますが、6系なら行けるんじゃないんでしょうか。たぶん。
Thin ProvisioningなVMのイメージを使ってるんでそんな人向けに書いてますが、Thick Provisioningな環境だともっと楽かもしれません。

大まかな流れとして

1. VMデータの取得
2. VMデータの移行
3. Thin ProvisioningなVMデータの処理
4. VMの登録

といった感じです。

# 準備編

## SSHアクセスの有効化
管理画面からESXiのsshアクセスを有効化しておきます。
Webからコンソールを表示することもできるので、必須ではありません。
でもみんな慣れた環境でやりたいよね ね?
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/a39c627f-3a78-89f2-1fe1-03ee57f21bc4.png)

オタクはすぐに鯖にWintermuteとかつける</sl>

## データの取得
の前にVMの電源は一旦落としましょう。
ESXiのWebUIからデータを落としてもいいんですが、フォルダ単位で落としてくることができないため、今回は[Cyberduck](https://cyberduck.io/)を使用しました。
SFTP接続ができれば何でもいいと思います。

VMのデータは
```/vmfs/volumes/[データストア名]/[VM名]```
としてフォルダが作られています。

なお、実際に使われている容量ではなく、VMに割り当てている容量でファイルが落ちてくるので、手元の容量や移行先の容量が小さい場合にはこのへんを参考に縮小するといいと思います。今回は試していないのでGoogle先生に相談してください。
[fdisk でパーティションのサイズを変更する](https://access.redhat.com/ja/articles/2211741)
[How to Shrink an ext2/3/4 File system with resize2fs](https://access.redhat.com/articles/1196333)

ではダウンロード開始です。
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/4763a30c-14be-6712-1776-48609af7088d.png)

おせぇ


試してないけどscpとかでも投げられるんじゃないんでしょうか。試してないけど。

# 移行編

## 確認
拾ってきたデータを見てみましょう
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/a74d88c4-f379-e7e8-5592-1ae0b0376b8f.png)
割当64GB分のVMデータだったので64GB分ふってきてます。無慈悲。

## 転送
先程と同じく
```/vmfs/volumes/[データストア名]/[VM名]```
で投げればよいです。
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/185bf85a-7cf7-b98d-e760-6aaf4501e4e9.png)

おせぇ!


## Thin Provisioningのお片付け

さて、データは入りました
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/67e51665-8d8e-177c-aa96-1c838e0fdc60.png)
が、そのまま64GB食ってます。つらい

なんで実際に使われている容量に減らしましょう
ここからコンソールでの作業が必要になるので、SSHを有効化するなりWebからコンソールを開きます

```
cd /vmfs/volumes/[データストア名]/[VM名]
ls -lha
```
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/76b78c63-5ff7-beb5-d80d-9191e212c401.png)

[VMware ESX および ESXi の仮想ディスクを拡張、縮小、および圧縮する (2092650)](https://kb.vmware.com/s/article/2092650)
を参考に処理を行います。
実際に容量を食っている **-flat**のほうではなく、ただのvmdkを対象にします。
```vmkfstools -K [VM名]_0.vmdk```
![image](https://qiita-image-store.s3.amazonaws.com/0/78832/a9d8ce8d-3f53-8413-4c4d-3b6bf0148aec.png)

Webから確認すると

![image](https://qiita-image-store.s3.amazonaws.com/0/78832/63c9a554-241b-06fc-bc0a-db379dce68c5.png)

64GBではなくなりました

## VMの登録
仮想マシンから仮想マシンの作成/登録で持ってきたVMを選ぶだけ

# おわり

たぶんちゃんと移行するならシステムの容量削ったりなんだりしたほうが移行しやすいんだろうなと思いました。
以上
BibTeXとBashで文献リストを作成する

# 背景
- 既存の文献管理ツールはいろいろありますが、どれを使えば良いのかわかりません。
- 文献管理をなるべくシンプルにやりたいです。

# 今まで試してきた文献管理の方法
- エクセルに、文献タイトルや著者名などをまとめていく。→けっこう大変です。
- 文献管理ツールを使う。
    - 僕が使ったことがあるのはReadCube →僕が使っていた数年前は起動が遅くて、ちょっとじれったかったです。

# BibTeX形式の文献データを取得する方法の例
## CiNiiの場合
1. 検索式(例：人工知能)を入力し検索結果を得る
- 最大件数（例：200件）表示する
- 表示した文献すべて、もしくは気になる文献を選択（例：すべて選択のチェックボックにチェック）
- BibTex形式で表示
- 実行
- 表示されたBibTex形式のデータをローカルPCに保存

## Google Scholarの場合
1. Googleアカウントにログイン
- Google Scholarのサイトで検索式を入力
- 気になる文献の☆をクリック
- マイライブラリのページに移る
- 文献を選択
- エクスポートボタンをクリックしてローカルPCに保存

## J-stageの場合
- デフォルトの機能では、ポチポチ手動でbibtexをダウンロードしていくしかない模様。

# Bashでパースする例
CiNiiからエクスポートした文献データ(data_file)があり、文献タイトルのリスト(title_list.txt)を作りたいときターミナル上で
```cat data_file | grep title | sed 's/title="//' | sed 's/",$//' > title_list.txt```

などと実行すると、タイトルのリストが得られます。

# 参考文献
- [各データベースからEndNote basicへのインポート方法]
(http://www.dl.itc.u-tokyo.ac.jp/gacos/faq/enw_import.html)
Docker Toolbox for windowsでdocker-compose upに失敗する

docker-compose up が上手くいかずに無駄な時間を過ごしたので、同じことで悩む人が現れないように記録しておきます。

# 環境
Windows 10 Home
Docker Toolbox for windows

# 解決法
プロジェクトのディレクトリに移動する際に、

```cmd:悪い例
$ cd c:/Users/UserName/projects/myproject
```
ではなく

```cmd:良い例
$ cd /c/Users/UserName/projects/myproject
```
のようにディレクトリを移動する。
その後普通にdocker-compose up する。

# 終わりに
なにやらファイルの権限まわりでエラーを吐いてたっぽいのですが、これだけですんなりいきました。
なぜこれで解決するのか詳しい方がいましたらご教授ください。
プログラミングの知識ゼロな僕が、簡単なAIを作る

ども、ケンくんです。
これから簡単なAIを作ろうと思います。ヾ(⌒▽⌒）ゞ

<h1>そもそもなぜAIを作りたいと思ったのか？</h1>AIやロボット等に興味があるし、面白そうだったので、作ってみようと思いました。あと、今頃作っておいた方が将来に役立つかもしれないと思ったからです。

<h1>そこで見つけたのが、Python</h1>僕はとあるネット記事を読んだのですが、そこには、AIの作成にはPythonが勧められていました。なので、これからはPythonを勉強しようかなぁ～て思います。まあ、他にもRubyやJava等で作られているAIもあるらしいんですが、一応Pythonで作ってみます。

<h1>最後に</h1>また、これからの記事を見て、何かアドバイス等がありましたら、コメントをよろしくお願いいたします。次からはプログラミング関連の事等を投稿しようかなぁ～と思います。
.



では、これから宜しくお願いします。m( _ _ )m
Really Simple CSV Importerを使ってSmart Custom Fieldsのチェックボックスをインポートする方法

Really Simple CSV Importerを使ってSmart Custom Fieldsのカスタムフィールド をインポートする際、基本はフィールド名そのままでインポート可能ですが、チェックボックスなど複数の値が入る場合は少し工夫が必要です。


#csvサンプル

カスタムフィールド名`humberger`のチェックボックスがあったとします。
csvのサンプルはこんな感じ。チェックボックスに焦点を当てたいので他の項目は割愛します。

| scf_humberger |
|:-----------------|
| チーズバーガー,ダブルチーズバーガー,ロースカツバーガー |
| ダブルチーズバーガー |
| ダブルチーズバーガー,ロースカツバーガー |

ポイントは
- カスタムフィールド名の頭に`scf_`を付ける。
- チェックボックスの値はカンマで区切る。

***`scf_`はcsvにだけ必要で、wordpressでカスタムフィールド を登録するときは必要ありませんのでご注意ください。***

#function.php側の処理

Really Simple CSV Importerで用意されている`really_simple_csv_importer_save_meta`フィルターを使って、インポートされた際に処理を走らせます。

```function.php
function really_simple_csv_importer_meta_filter_checkbox( $meta, $post, $is_update ) {
  foreach ($meta as $key => $value) {
    if (strpos($value, ',') !== false) {
      $_value = preg_split("/,+/", $value);
      $meta[$key] = $_value;
    }
  }
  return $meta;
}
add_filter( 'really_simple_csv_importer_save_meta','really_simple_csv_importer_meta_filter_checkbox', 5, 3 );
```

#処理結果

ちゃんとチェックボックスにチェックが入っています。
<img width="500" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/116185/169badd7-2c43-a09a-b85b-72873dbe862b.png">

ちなみにcsvはgoogleドキュメントが使いやすかった！形式指定ダウンロードでそのままcsv書き出しできて文字コードの問題もなし！複数人で編集できる！
GoogleHomeで扇風機のスイッチをオン/オフする

買ったはいいが、いまいち活用できていないGoogle Homeを何とか使えないか考えてみた。
職場の倉庫でパソコンのセットアップ作業を行う時があるが、この部屋が空調がイマイチで常に暑い。
対策として卓上扇風機を２つ置いているが、これを音声でオン・オフできないかトライしてみました。


今回はスマートコンセントを使って試してみました。
制御はIFTTTと連携を行いました。


#■使用した機器#
・GoogleHome
・Aitmexcnスマートプラグ スマートコンセント
・OAタップ（スマートプラグに接続し、2台の卓上扇風機の電源を接続）

<a target="_blank" href="//af.moshimo.com/af/c/click?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fitem.rakuten.co.jp%2Fbook%2F15142695%2F&amp;m=http%3A%2F%2Fm.rakuten.co.jp%2Fbook%2Fi%2F18832252%2F&amp;r_v=g00q0723.9tq3e7e7.g00q0723.9tq3fc4c" rel="nofollow"><img src="//thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/2263/0842776102263.jpg?_ex=128x128" alt="" style="border: none;" /><br />Google Home（グーグル ホーム）</a><img src="//i.moshimo.com/af/i/impression?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" alt="" width="1" height="1" style="border: 0px;" />

<a target="_blank" href="//af.moshimo.com/af/c/click?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fitem.rakuten.co.jp%2Fpify%2F10014805%2F&amp;m=http%3A%2F%2Fm.rakuten.co.jp%2Fpify%2Fi%2F10014805%2F&amp;r_v=g00sllm3.9tq3e318.g00sllm3.9tq3f26f" rel="nofollow"><img src="//thumbnail.image.rakuten.co.jp/@0_mall/pify/cabinet/moriguchi/513/vvvvvv.jpg?_ex=128x128" alt="" style="border: none;" /><br />Aitmexcnスマートプラグ　スマートコンセント GoogleホームIFTTT対応　無線リモコン ハブ不要　タイミング機能付き　どこでもコントロール　家電スイッチ Android/IOS対応 (2)</a><img src="//i.moshimo.com/af/i/impression?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" alt="" width="1" height="1" style="border: 0px;" />

<a target="_blank" href="//af.moshimo.com/af/c/click?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fitem.rakuten.co.jp%2Fmurauchi-denki%2F4953103095625%2F&amp;m=http%3A%2F%2Fm.rakuten.co.jp%2Fmurauchi-denki%2Fi%2F27927615%2F&amp;r_v=g00q02s3.9tq3e992.g00q02s3.9tq3ffe6" rel="nofollow"><img src="//thumbnail.image.rakuten.co.jp/@0_mall/murauchi-denki/cabinet/625/4953103095625.jpg?_ex=128x128" alt="" style="border: none;" /><br />ELECOM/エレコム 【簡易パッケージ】EU RoHs指令準拠 マグネット付抜け止めタップ 3P4口 3m T-ECOH3430NM 【まとめ買いに！法人様にお薦め！簡易パッケージ版OAタップ！】</a><img src="//i.moshimo.com/af/i/impression?a_id=1021037&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" alt="" width="1" height="1" style="border: 0px;" />

#まずはGoogleHomeのセッティング#
   Google Home Miniを買った。開封～セットアップまでを体験
   http://www.datacider.com/77520.php



#続いてスマートコンセントのセッティングとIFTTTの設定
Amazonで買ったスマートコンセントでコタツを操作したらめっちゃ便利だった【レビュー】
https://mettyaeeyan.com/smart-concent

スマートコンセントにＯＡタップと接続し、ＯＡタップに扇風機の電源を接続する。
「ねえ、グーグル。扇風機つけて」と話すと「扇風機つけます」というセリフの後に「ウイーン」と２台の扇風機が動き出す。
感動＆快適。

「ねえグーグル、扇風機消して」と言っても扇風機の音に自分の声がかき消されて若干認識が良くないのは気になりますが、これからもっと色々と活用していきます。
PythonでDynamoDBの例外処理をする。

# ソースコード

```python:Main.py
from botocore.exceptions import ClientError
if __name__ == '__main__':
    try:
        table = boto3.resource('dynamodb').Table('TableName')

        # DynamoDBからのエラーが発生するコードをここに書く

    except ClientError as e:
        print(e)
        print(e.response['Error']['Message']) # エラーメッセージ
        print(e.response['Error']['Code'])    # エラーコード（Exceptionの種類を示す文字列）
        print(e.response['ResponseMetadata']['RequestId'])
        print(e.response['ResponseMetadata']['HTTPStatusCode']) # ステータスコード
        print(e.response['ResponseMetadata']['HTTPHeaders']['server'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['date'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['content-type'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['content-length'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['connection'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['x-amzn-requestid'])
        print(e.response['ResponseMetadata']['HTTPHeaders']['x-amz-crc32'])
        print(e.response['ResponseMetadata']['RetryAttempts'])
```
※S3にもエラーメッセージ、エラーコード、ステータスコードは使用できます。
# 実行結果（例）
※接続情報などは*****でマスキングしています。

```
An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: An expression attribute value used in expression is not defined; attribute value: :val
Invalid UpdateExpression: An expression attribute value used in expression is not defined; attribute value: :val
ValidationException
****************
400
Server
Thu, 17 May 2018 03:58:39 GMT
application/x-amz-json-1.0
***
keep-alive
****************
*****
0
```
# この記事を書いた理由
HTTPStatusCodeを取得するためにネットで検索した際、
下記のStackoverflowに英語で例外処理が書いてありましたが、見つけにくかったので。
https://stackoverflow.com/questions/33068055/boto3-python-and-how-to-handle-errors

# 付録：EclipseでPythonを書く際の便利なショートカットキー
Ctrl + 1
※「F1」ではなく「1」
Eclipseでコンパイルエラーが発生した時、
そのエラー箇所にカーソルを当ててこのショートカットを使うと
根本原因のソースコードにカーソルが当たったり、
解決策が表示され、クリックすると自動で修正してくれたりします。
nested_form_fieldsを使って入力フォーム数を可変にする

has_manyで関連しているモデルをfields_forで作成する際に、
フォームの数を可変にしたくなりますよね。
例えば在庫モデルにいくつもの商品を登録したい時とか。

最初は追加ボタンを押した回数だけループ回して、fields_forを作成したりしてたんですが、
便利なgemがあったので備忘録として残しておきます。

``` :Gemfile
gem 'nested_form_fields'
```

上記を追加して「bundle update」を実行

``` javascript:application.js
//= require nested_form_fields
```

jsファイルには上記を追加しておきます。

これで下記のようにviewでfields_forの代わりに**nested_fields_for**が使えるようになります。
フィールドを追加する為の**add_nested_fields_link**や、
削除する為の**remove_nested_fields_link**も用意してあるので、
かなり簡単に可変なフィールドを作ることができました。

具体的な使い方は下記を参考にさせて頂きました。
https://www.virment.com/add_and_remove_rails_nested_form_dynamically/
副テーブルの関連レコードをリストにして主テーブルと結合してJSONで取得する方法

# やりたいこと
次のような２つのテーブルがあるとする。
###主テーブル(RegionTbl)

id |  regionName
---+--------
1  |  "Kansai"
2  |  "Tokai"
3  |  "Kyushu"

###副テーブル（PrefTbl)

id   | regionId  | prefName
-----+---------+---------
101  | 1       | "Kyoto"
102  | 1       | "Osaka"
103  | 2       | "Aichi"
104  | 2       | "Gifu"
105  | 1       | "Hyogo"

主テーブルのidと副テーブルのregionIdで２つのテーブルは紐付いているとする

ここで、以下のようなJSONを取り出したい。
```[
  {"id": 1, 
   "regionName": "Kansai",
   "preflist": [{"id": 101, "regionId": 1, "prefName": "Kyoto"},
                {"id": 102, "regionId": 1, "prefName": "Osaka"},
                {"id": 105, "regionId": 1, "prefName": "Hyogo"}]},
  {"id": 2,
   "regionName":  "Tokai",
   "preflist": [{"id": 103, "regionId": 2, "prefName": "Aichi"},
                {"id": 104, "regionId": 2, "prefName": "Gifu"}]},
   {"id": 3,
    "regionName": "Kyushu",
    "preflist: null}
]```

# SQL
以下のようなSQLを書けばよい
```WITH p AS (
  SELECT regionId, json_agg(PrefTbl) AS preflist FROM PrefTbl GROUP BY regionId
)
, v AS (
  SELECT r.*, p.preflist
  FROM RegionTbl r
  LEFT OUTER JOIN p ON r.id=p.regionId
)
SELECT json_agg(v) FROM v;```

# 前提
PostgreSQL 9.3以上（たぶん）
Excel から Web フォームに一括ペースト

## はじめに

Excel から Excel へなら、複数のセル（複数の項目）を一度にコピペすることができます。しかし Excel から Web フォーム上へデータをコピペしたい場合は、なにもしなければ１セル（１項目）ずつコピペしていくしかありません。

Web フォームに Excel（など）ワークシートから値をコピペしたい要件があるかもしれません。

そのようなときには~~運用を考え直していただく~~次のようなサンプルが役に立つかもしれません。

## サンプル

- 単独の項目だけをペーストしたいときのために、３列なければ普通のペーストにしています。`// Ignore less then 3.` の部分です。

- どの入力欄でペーストしても左上の欄からペーストしたような動きになります。

```html
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="description" content="">
    <meta name="author" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function () {
        $('.excel-receiver').on('paste', function (e) {
            var data = e.originalEvent.clipboardData.getData('Text');
            //var data = window.clipboardData.getData('Text'); //IE
            var elems = $('.excel-receiver');
            var n = 0;
            var max = elems.length;
            var rows = data.split('\n');
            for (var i = 0; i < rows.length; i++) {
                var fields = rows[i].split('\t');
                if (fields.length < 3) return; // Ignore less then 3.
                for (var j = 0; j < fields.length; j++) {
                    elems[n++].value = fields[j];
                    if (n >= max) {break;}
                }
                if (n >= max) {break;}
            }
            e.preventDefault();
        });
    });
    </script>
    <style type="text/css">
        input[type="text"].excel-receiver {
            width: 100%;
            -moz-box-sizing: border-box;
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }
        td {
            width: 100px;
        }
    </style>
</head>
<body>
    <table>
        <tr>
            <td><input class='excel-receiver' type='text' /></td>
            <td><input class='excel-receiver' type='text' /></td>
            <td><input class='excel-receiver' type='text' /></td>
        </tr>
        <tr>
            <td><input class='excel-receiver' type='text' /></td>
            <td><input class='excel-receiver' type='text' /></td>
            <td><input class='excel-receiver' type='text' /></td>
        </tr>
    </table>
</body>
</html>
```

## 免責

いろいろ使ってみるとわかると思いますが、セルの数と入力欄の数が一致しない場合、ユーザーがどのような操作の結果を期待するかが不明瞭であるというリスクがあります。テストデータの入力くらいにしか使えないバッドノウハウかもしれませんが、ま、ネタということで。
Cognos Analytics 11.0.11 新機能 - Portal Pages の機能

#概要
Cognos Analytics 11.0.11で、Portal Pagesの機能が新機能として紹介されていますが、何ができるのかというのを投稿します。

**Portal Pages in Cognos Analytics R11**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/portal-pages-in-cognos-analytics-r11/

**Cognos 10 Portal Page migration to IBM Cognos Analytics 11.0.11 My Portal Pages**
https://www.youtube.com/watch?v=IjTO23J1b64

#Cognos 10 BIでページの機能実装状態
ページを作成し、共有フォルダのPortal Pagesフォルダ配下に配置し、Cognos Connectionでタブに登録しています。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/4abaedea-dddd-f128-c2cd-ce9b905b8217.jpeg)

ページを実行してみると、こんな表示です。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/dc8cbd30-e19d-7292-d9e3-c574821c39c1.jpeg)

#Cognos Analytics 11.0.10まで
上記のCognos 10 BIから、コンテントストア全体をCognos Analytics 11.0.10にアップグレードした場合です。
Portal Pagesフォルダに、ページのエントリーがC10の時同様に存在します。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/f79ba563-746c-2648-978a-9398d4137217.jpeg)

実行してみると、C10と同じ表示になります。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/7920f93a-0bdf-8d12-c1f0-7ae6e2503221.jpeg)

#Cognos Analytics 11.0.11では
まず設定が必要なのですが、下記のURLにアクセスして、Name、Valueを画像の通り入力して、submitします。
10秒ほどで反映されるそうですが、submitした時に「undefined」と出てしまう場合は、IEブラウザの互換性設定にこのサイトを登録してください。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/d846d3b4-deac-dfbb-9fda-a37be909925a.jpeg)

このように「My portal pages」メニューが表示され、中にはタブに並んでいたページのエントリーが並んでいます。
元々C10で、タブに何を指定していたかはユーザーのプロファイルに情報として保管されていますので、コンテンツ全体を移行すると、ユーザー情報も移行されるので、タブの指定がこのように引き継がれます。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/bc42b6ba-ef19-73cd-4508-9f4da6335941.jpeg)

また、タブに登録していなかったページも、以下のように「Add to My portal pages」で追加登録できます。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/63a8d86c-10a9-f7ad-04cc-93041c53dd1c.jpeg)

「Share」でURLを取得できますので、特定のページに直接URLアクセスできるようになりました。
![008.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/7b7ceec3-77d7-089a-2bd0-5c9ba0077950.jpeg)

ページを表示した状態で「Set as home」で、ホームに指定する事もできます。
![009.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/67755a7d-d037-8e74-68a4-15828497a99a.jpeg)

という感じですね。
新規にページを作成や編集はできないので、「ページの機能復活」とまでは行きませんですが、今後完全復活することを期待したいです。