OmniAICreator/Qiita-1.07M huggingface dataset:
php-phantomjsで取得したhtmlをphpQueryでスクレイピング

### 経緯
JSによるレンダリング後のhtmlをスクレイピングしたかったので、phantomjsを使用。
他のページはそういう感じではなく、phpQueryでスクレイピングしていた。
そのためこういう事になりました。

### 方法
理由はよくわからんが、いい感じになってくれないので、
DOMDocumentにしてからphpQueryに食わせないといけなかった。

```php
//phantomjsでhtmlをとってきて
$client = Client::getInstance();
$client->getEngine()->setPath(PHANTOMJS_PATH);
$request = $client->getMessageFactory()->createRequest();
$response = $client->getMessageFactory()->createResponse();
$request->setUrl($url);
$client->send($request, $response);
$html = $response->getContent();

//DOMDocumentにする
$dom = new DOMDocument;
@$dom->loadHTML($html); //$htmlになんらかのHTML的invalidがあるので、@をつける
$dom->saveHTML();

//そしてphpQueryでスクレイピングする
$doc = new phpQuery::newDocument($dom);
```

確認した環境は `PHP 7.1.16` です。
Homebrew CaskでPostgreSQLクライアントのPSequelをインストールする

- 環境
    - macOS High Sierra バージョン10.13.5
    - Homebrew 1.7.2
    - Homebrew-Cask 1.7.2

# Homebrewでインストール前の準備をする。
```sh
# アップデートする。
$ brew update
Updated 2 taps (homebrew/core, homebrew/cask).
==> New Formulae
libsignal-protocol-c
<省略>

# 異常がないか確認する。
$ brew doctor
Your system is ready to brew.

# どんなバージョンがあるか確認する。
$ brew search psequel
==> Casks
psequel

# Homebrew Caskのインストールが必要。。。
```

[`brew doctor` で警告が出たら対処する。](https://qiita.com/ponsuke0531/items/76009a93f99912f6f3a4#homebrew)

# Homebrew Cask をインストールする。
Homebrew Caskとは・・・GUI系のアプリも管理してくれるバッケージマネージャ。
[今はもうインストールしなくてもHomebrewに入っているから大丈夫。](https://qiita.com/ponsuke0531/items/73f540391aa3827130d8)

> HomebrewはMac用のパッケージマネージャー。ターミナルで使うものなんかをいろいろインストールできたりするわけですが、Homebrew CaskはHomebrewでアプリ（GUI）も管理してしまおうというやつです。
> [Homebrew Caskで楽々インストール | 株式会社 エヴォワークス -EVOWORX-](https://www.evoworx.co.jp/blog/homebrew-cask/)

```sh
# メッセージなど表示されずに終わるけれどOK
$ brew tap caskroom/cask
```


# PSequelをインストールする。
```sh
$ brew cask install psequel
==> Satisfying dependencies
==> Downloading http://www.psequel.com/download?version=1.5.3
==> Downloading from https://www.dropbox.com/s/z1jsw0r4prk1qg1/PSequel.1.5.3.app.zip?dl=1
######################################################################## 100.0%
==> Verifying checksum for Cask psequel
==> Installing Cask psequel
==> Moving App 'PSequel.app' to '/Applications/PSequel.app'.
🍺  psequel was successfully installed!
```

インストールされた。
![スクリーンショット 2018-08-25 15.24.01.png](https://qiita-image-store.s3.amazonaws.com/0/159761/1a48e671-3fef-b25b-fa88-f88cb55641a1.png)
Vue.js初学者が迷う、HTMLの仕様やSEO（Googlebot）のことを調べてみた。

Vue.jsを使用するにあたり、ディレクティブやコンポーネントがHTMLの仕様的どうなのか？JavaScriptメインのサイトは、Googlebotに認識されるのか？等、気になったことを調べました。

## ディレクティブとかコンポーネントって、使っていいの？
```vue

<template>
  <div>
    <input @click="count++" :class="{'is-active': isActive}"></input>
      <ul>
        <li v-for="message in messages">{{message}}</li>
      </ul>
    <my-component></my-component>
  </div>
</template>
```

こんなHTMLキモい！W3C Markup Validation Serviceでもエラーがでる！キモい！

でも、大丈夫((´^ω^))

### template要素は標準タグ
```vue

<template></template>
```
https://developer.mozilla.org/ja/docs/Web/HTML/Element/template

### : や @ は属性名に利用可能な文字
Vue.js公式より

> : や @ は属性名に利用可能な文字です。
> すべての Vue.js のサポートしているブラウザで、正しくパースすることができます。
> 加えて、最終的に描画されるマークアップにそれらは現れません。

```vue

<div @click="count++" :class="{'is-active': isActive}">
```
w3c Markup Validation Serviceには、非標準の有効な属性のerrorを非表示にする機能がある。
<img width="780" alt="スクリーンショット 2018-08-28 22.46.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/90339/305e07b1-f601-09ae-f970-e0dad2844f21.png">

### Vueコンポーネントで使われるカスタム要素は、Web Componentsの規格
```vue

<my-component></my-component>
```

w3c Web Components リポジトリ
https://github.com/w3c/webcomponents/

WHATWGのカスタム要素の定義
https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements

Vue.jsのコンポーネントは、w3c Web componentsを参考に作られているので、標準規格に近い仕様を安全に使用することができる。（IE9以上）

カスタム要素との関係
https://jp.vuejs.org/v2/guide/#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E8%A6%81%E7%B4%A0%E3%81%A8%E3%81%AE%E9%96%A2%E4%BF%82

## JavaScriptのサイトって、SEO的に大丈夫なの？
大丈夫((´^ω^))

Googlebotは、Chrome 41（M41）に基づくウェブ レンダリング サービス（WRS）が使用されている。
https://developers.google.com/search/docs/guides/rendering

一部制限はあるが、Chrome 41で使用可能なJSはレンダリングされる。
モバイルフレンドリーで、レンダリングされたソースコードを確認できる。
https://search.google.com/test/mobile-friendly?hl=ja

ただし、Chrome 41は2015年ごろのバージョンなので、モダンJSで使えない機能がある。

caniuseやヘッドレスブラウザで、レンダリングの検証ができる。
https://caniuse.com/#compare=chrome+41
https://github.com/GoogleChromeLabs/puppeteer-examples

babel等でES5にトランスパイルされていれば、だいたいOK。

ただしただし！

**title や description、OG情報系はJavaScriptで書き換えても、FacebookやTwitterが認識してくれないので、直接HTMLに書く必要がある。**

## HTML Validationって、どうやってやればいいの？
レンダリングされたDOMツリーは、ヘッドレスブラウザを利用して出力することができる。

Puppeteer
https://github.com/GoogleChrome/puppeteer

Googleが開発しているため、安心◎。

## まとめ
- ディレクティブやコンポーネントは、HTMLの仕様内で使われている。
  - レンダリングされるDOMツリーには反映されない。
- GooglebotはJavaScriptをレンダリングして評価する。
  - 公式のツールで検証することができる。
  - ただし、レンダリング能力はGoogle Chrome v41程度なので、気をつける。
- ヘッドレスブラウザのPuppeteerを使って、レンダリングされるDOMツリーを出力することができる。
VirtualBoxにCentOS7インストールする--SSH接続まで

社内環境にはプロキシー経由でインタネットをアクセスすることが多いです。
いろいろなアプリがインストール・利用するときに、プロキシーの設定でハマってしまって、数時間をかかって解決できなかった問題が、家に帰って、自分のパソコンで数分で解決したことがありますでしょうか。
今回はあえて自分のパソコンにプロキシーが必要な環境を作成してみます。

#　バージョン情報  
今回に使用する主なソフトウェアバージョンは以下の通りです。  

|       |       バージョン |備考|
|:-----------------|:------------------:|:------------------:|
| HOST OS|Window 10 バージョン2004(OSビルド19041.208)|
| VirtualBox|6.1.6|2020/05/03最新版|
| Guest OS|CentOS 7.8(2003)|
|プロキシーサーバー|squid|[Windows Sub System for Linux(ubuntu)にインストール済み](https://qiita.com/okcoder/items/9285f2e460a9c5330996)|

# 事前準備
## ホストオンリーネットワークアダプタの設定の確認
ホストオンリーネットワークアダプタはGuestOSとHostOSの間しか通信できないアダプタです。
GuestOSがHostOSのみ通信させ、HostOSに起動したJmeterのプロキシー機能を経由で外部と通信させます。

次の手順で設定を確認します。
VirtualBoxを起動し、メニュー「ファイル」⇒「ホストネットワークマネージャー」を開き、ホストオンリーネットワークアダプタが存在し、DHCPサーバーが有効になっていることを確認します。
存在しなかったら、 作成してDHCPを有効かします。
## CentOSイメージダウンロード
[CentOS](https://www.centos.org/download/)ホームページから[Minimal ISO](http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2003.iso)をダウンロードします。

# 仮想マシン作成
次の手順で仮想マシンを作成します。
1. VirtualBoxメニュー「仮想マシン」⇒「新規」を選択します。
2. 「名前とオペレーティングシステム」画面で、「名前」に「CentOS7-2003」を入力し、「次へ」をクリックします。
3. 「メモリーサイズ」画面はそのままで「次へ」をクリックします。
4. 「ハードディスク」画面はそのままで「作成」をクリックします。
5. 「ハードディスクのファイルタイプ」画面はそのままで「次へ」をクリックします。
6. 「物理ハードディスクにあるストレージ」画面はそのままで「次へ」をクリックします。
7. 「ファイルの場所とサイズ」画面はそのままで「作成」をクリックします。
作成された仮想マシン「CentOS7-2003」が仮想マシン一覧に表示されます。

# 仮想マシン設定
次の手順で仮想マシンを設定します。
1. 仮想マシン一覧から「CentOS7-2003」を選択し、「設定」メニューをクリックします。
2. 「ストレージ」をクリックし、「コントローラー：IDE」の「空」を選択して、「光学ドライブ」右側のアイコンより先ほどダウンロードしたCentOS-7-x86_64-Minimal-2003.isoファイルを選択します。
3. 「ネットワーク」をクリックし、「アダプター１」タブの割り当てを「NAT」から「**ホストオンリーアダプター**」に変更します。
4. 「OK」をクリックし設定を完了します。

# CentOSインストール
次の手順で仮想マシンを設定します。
1. 仮想マシン一覧から「CentOS7-1804」を選択し、「起動」メニューをクリックします。
2. 矢印キーで「Install CentOS 7」を選択し、「Enter」キーを押します。
3. 「言語選択」画面で「日本語」、「日本語（日本）」を選択し、「続行」をクリックします。
4. 「キーボード」が「**日本語**」になっていることを確認します。
5. 「インストール先」をクリックし、そのまま「完了」をクリックします。
6. 「ネットワークとホスト名」をクリックし、**「Ethernet(enp0s3)」の右側をクリックし「ON」に変更**します。IPアドレスが表示されましたら、**「設定」をクリックし、「全般」タブの「この接続が利用可能になったときは自動的に接続する」をチェック**し「保存」をクリックします。続いて「完了」をクリックします。「ネットワークとホスト名」の下に、「有線(enp0s3)が接続されました」が表示されることを確認します。
7. 「インストールの開始」をクリックして、インストールを開始します。
8. 「ユーザーの設定」画面で「ROOTパスワード」をクリックし、「rootパスワード」と「確認」に「password」を入力し、「完了」を二回クリックします。
　(ここで「このユーザーを管理者にする」をチェックすると、後続の```usermod -g wheel user```コマンド実行が要らなくなります)
9. 同じ画面で「ユーザーの作成」をクリックし、「フルネーム」と「ユーザー名称」に「user」を入力し、「パスワード」と「パスワードの確認」に「pwd」を入力して、「完了」を二回クリックします。ここで「user」というユーザーを作成します。
10. 「完了しました！」が表示されましたら、「再起動」をクリックしてインストールを完了します。


# CentOS初期設定
CentOSが起動したら、「root」でログインします。
1. IPを確認します

```
ip a
```
ここで確認されたIPでSSHが接続できるになります。続いてrootユーザーでいくつの設定をします。

2.プロキシー設定

```
echo export http_proxy=http://192.168.56.1:3128>/etc/profile.d/proxy.sh
echo export https_proxy=http://192.168.56.1:3128>>/etc/profile.d/proxy.sh
source /etc/profile.d/proxy.sh
#結果確認
curl www.google.co.jp
```

3.「user」ユーザーを「wheel」グループに追加
「user」がsudoできるため

```
usermod -g wheel user
```

4.システム更新

```
yum -y update
```

今日はここでおしまい。
macのターミナルで月表示のカレンダーを表示する

標準で`cal`というコマンドが入っているので、それを実行する。

デフォルトでは当月のカレンダーを表示する。

```bash
$ cal
      8月 2018         
日 月 火 水 木 金 土  
          1  2  3  4  
 5  6  7  8  9 10 11  
12 13 14 15 16 17 18  
19 20 21 22 23 24 25  
26 27 28 29 30 31  
```

よく使いそうな引数はこんな感じ。

- 前月/当月/翌月のカレンダーを表示する
  - `cal -3`
- 任意の年月のカレンダーを表示する
  - `cal 8 2019` (2019年8月のカレンダーを表示)
CentOSにpyenvとAnacondaを入れてローカルからJupyterにアクセスするまで

真っ新な状態からの構築で割と大変だったので忘れないように備忘録
簡潔でお世話になった記事をひたすらまとめただけの記事

# 1. pyenvの導入
https://qiita.com/ksugawara61/items/ba9a51ebfdaf8d1a1b48

# 2. Anacondaの導入
Anacondaは**pyenvを使って**入れるので、この記事が参考になる
https://qiita.com/wslife/items/219b2558e1066eaaed07

# 3. Jupyterの設定
リモート上のJupyterにアクセスするために、ポートやパスワードの設定が必要
https://qiita.com/syo_cream/items/05553b41277523a131fd

# 4. ローカルからアクセス
リモート上で

```
jupyter notebook
```
を実行した後、ローカルのブラウザに**[リモートのアドレス]:[3で指定したポート]**にアクセスすれば、Jupyterのパスワード入力画面に辿り着く。
リモートのコンソールではThe Jupyter Notebook is running at: にドメインが指定されているが、ローカルからではリモートのDNSに繋がらない場合は当然名前解決出来ないので、その時はIPアドレスで指定してアクセスする。
php-master-changes 2018-08-28

# 2018-08-28
## dstogov: Removed redundand code
- https://github.com/php/php-src/commit/57e2b7d53b1d5de0a2eed6596faa9398b4dffc1c
- ext/opcache で active_op_array をバックアップして何もしないでまた戻すという一見すると謎のコードがあったのを削除

## remicollet: bump to 7.2.11-dev
- https://github.com/php/php-src/commit/7353dae815c5b35d91f9233470d7f12f113033bf
- 7.2 系のバージョン番号を PHP 7.2.11 へ
- 7.2.10 は 9/13 予定のもよう

## dstogov: Revert "Removed redundand code"
- https://github.com/php/php-src/commit/4151a3fa647c809fadc4f2cf651454a4a89ec917
- 謎コードは必要なコードだったのか revert
- オーバーライド前の元のコンパイル処理（accelerator_orig_compile_file()）呼んだ時に変わる想定かな

## cmb69: [ci skip] Update NEWS wrt. php-7.3.0beta3 tagging
- https://github.com/php/php-src/commit/ce201df40fa90d05d9c452f7439de084c1f0ae2a
- 7.3.0 beta3 にタグ打って NEWS の更新

## cmb69: Fix SKIPIF conditions
- https://github.com/php/php-src/commit/441b6a6f5e7e19276d10485434c610278a781261
- mb_convert_encoding() を呼ぶテストが ext/mbstring なしでも実行されるようになっていたので、その場合はスキップするよう修正

## weltling: Fixed bug [#76803](https://bugs.php.net/bug.php?id=76803) ftruncate changes file pointer
- https://github.com/php/php-src/commit/7728160784785771d1933f5f0a8c4d7a735470b0
- Windows で ftruncate() がファイルポインタを変更する挙動になっていたのを修正
- [別のバグ](https://bugs.php.net/bug.php?id=76422)の regression らしい

## dstogov: Removed incorrect efree() (run_time_cache(s) are usually allocated in CG(arena)).
- https://github.com/php/php-src/commit/684354be728d7e48657aad48af458869075df051
- ext/opcache で CG(arena) にある oparray->run_time_cache を efree() していた問題の修正
i18n対応AngularアプリケーションをFirebase Hostingで公開するときの設定

## 前提

以下の記事の構成でi18n対応AngularアプリケーションをFirebase Hostingに公開したい。
https://qiita.com/daikiojm/items/c7aebeae30c86d48d0c8

## 設定

firebase.jsonを次のように設定する。

```json:firebase.json
{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "redirects": [
      {
        "source" : "/",
        "destination" : "/en",
        "type" : 301
      }
    ],
    "rewrites": [
      {
        "source": "/ja/**",
        "destination": "/ja/index.html"
      },
      {
        "source": "/en/**",
        "destination": "/en/index.html"
      }
    ]
  }
}
```

- public
  - ここに設定したパス以下のファイルがデプロイされるので、今回の場合en/jaどちらのディレクトリもデプロイされる
-　 redirects
  - デフォルトの言語をenにしたいので`/`にアクセスした際に`/en`にリダイレクトするように設定
- 　redirects
  - `/ja|en/**`にマッチするアクセスがあった際に対応するindex.htmlを表示するように設定

## 参考

https://firebase.google.com/docs/hosting/url-redirects-rewrites?hl=ja
[Git]git push したら Repository not found.

## 事象
リポジトリが無い…だと？

```bash:GitBash
$ git push
Enter passphrase for key '/c/Users/********/.ssh/id_rsa':
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

## 原因

結論としては私のgitのアカウントが read 権限しかなかったことがわかりました。(ちなみにこれがリポジトリへの初pushでした。)
**なら権限のエラーってわかるエラーメッセージ出してくれｗｗ**

`Please make sure you have the correct access rights and the repository exists.` とも出ていますが、もし個人でしか git 使ったことない人はリポジトリにアクセスができている時点でさらに細かい権限が分かれていることまで考えは及びにくいかと思いました。(Organization特有の権限設定のようなので。)

権限を write に変えてもらって、無事 push はできました。

## 参考
https://help.github.com/articles/repository-permission-levels-for-an-organization/

私のアカウントは当該リポジトリに於いては Read permissions だったらしいです。

## 教訓
こういうこともあるので、もし同じエラーを見かけた際は一度リポジトリ管理者に自分の権限を確認してみると解決できるかもしれません。
RubyMineのLiveEditでpowで起動したアプリのJSをデバッグする

powで起動したRailsアプリのJSをRubyMineでデバッグする方法。

# こちらの機能の利用方法

https://pleiades.io/help/ruby/live-editing.html

# 事前準備

- LiveEditとデバッガーの設定
    - 最新のRubyMineはデフォルトでインストールされている
- Chromeに `JetBrains IDE Support` をインストールする

## LiveEditとデバッガーの設定

#### インストール状態

- `⌘,` → Plugins → 検索欄に`LiveEdit` でインストール状態を確認
    - インストールされていない場合は`Install JetBrains plugin` からインストール
    - チェックがついて有効になっていることを確認する

#### Live Editの設定

- `⌘,`　→　 Build, Execution, Deployment → Debugger →　LiveEdit を開く
- 以下の項目にチェックを入れる
    - Update application in Chrome
    - Highlight current element in browser on caret change

#### デバッガの設定

- RubyMineでデバッグしたいerbファイルを開く
- ツールメニューのRun → Edit Configurations... をクリック
- 表示されるウィンドウで+をクリックし、JavaScript Debugを選択
- 以下のように設定する

<img width="1072" alt="スクリーンショット 2018-08-28 23.51.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/90680/7a0d49ff-69c8-1283-6564-821ccb1923f9.png">

|項目|設定値|
|:---|:---|
|name|任意の名前|
|URL|powのURL|

Remote URLs of local filesにデバッグしたいアプリケーションのファイルが表示されてること

## Chromeに `JetBrains IDE Support` をインストールする

[Chrome拡張のページ](https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji?hl=ja)からインストールする

# デバッグの仕方

- powを起動して、プロセスが起動していることを確認する
    - powは一定時間アクセスがないと自動で停止するため、ウェブページにアクセスするなどして叩き起こす
- RubyMineのツールメニューRunからDebug...をクリックする
    - 表示される項目から上で作成したJavaScript Debugの名前を選択する
- ブラウザからデバッグしたいウェブページを表示する
- RubyMineのデバッグコンソールから、`Scripts`タブを表示する
- powのURLでフォルダメニューが表示されるので、クリックして展開する
- デバッグしたerbファイルをクリックし、デバッグポイントを置く
- 再度ウェブページを開き直す
- デバッグポイントで止まることを確認する
React/React-native/create-react-app/Jestのライセンス境界（BSD->MIT）の一覧

## はじめに

最近、久しぶりにReact環境を構築しました。
( https://qiita.com/YuukiMiyoshi/items/d7041a1031ca3f928f7a )

Reactにはライセンス問題があったので、一応Facebookとしては解決したとのスタンスとは思いながら気になったので調べてみました。

知りたかったのは、ライセンス変更の発表後にリリースされたものは良いとして、バージョンダウンした際にどうなるかという点。
**結論からいうと、問題になりそうです。**

## 確認方法

Githubにアップされているfacebook製のソフトウェアのうち、下記４つにおいてLICENSEファイルをVersion毎にチェックしました。

* React
* React-native
* create-react-app
* Jest

## 結果

どのソフトウェアも、特定のバージョンでBSD+αとMITライセンスとの境界があります。
ライセンスの変わり目は次表のとおりです。

| License | React | React-native | Create-react-app | Jest |
|:-:|:-:|:-:|:-:|:-:|
| MIT | v15.6.2 | v0.55.0 | v1.0.15 | v21.2.0 |
| BSD + α | v15.6.1 | v0.54.4 | v1.0.13 | v21.1.0 |

互換性の都合などで古いバージョンを使用する際は注意したほうがよいかもしれません。

## 最後に

私はライセンスの専門家ではないので、責任が発生するような用途で使用する際はしかるべき方法で確認をとってください。
Qt環境の種類(PyQt5/PyQt4/PySide)に依存しないコードを書くためのパッケージqtpy

Pythonの主なQt biding パッケージは、[PyQt5, PyQt4](https://www.riverbankcomputing.com/software/pyqt/intro), [PySide](https://wiki.qt.io/PySide)があり、自分の環境のQtにあわせて`import PyQt5`などと書いてしまうと、別のQt環境をもつユーザーが使えません。``qtpy``パッケージはこの問題を解決してくれる抽象レイヤーです。
``from PyQt5.QtWidgets import QWidget`` などと書くところを``from qtpy.QtWidgets import QWidget``とすれば、PyQt5, PyQt4, PySideのいずれでも動くコードが書けます。
[qtpy](https://github.com/spyder-ide/qtpy)は、Spyderが内部で使用しており、Spyder IDEプロジェクトの一部で活発にメンテされています。
Keynoteで発表者ノートを見ながら発表する

Keynoteで発表者向けのメモなどを残せる
「発表者ノート」を自分だけが見ながら発表することができる。

## 手順

(1).画面上部に並んでいるメニュー（「ファイル」「編集」「挿入」など）
から「再生」→「発表者ディスプレイをカスタマイズ」を選択

(2).発表ディスプレイが表示される。「発表者ディスプレイをカスタマイズ」内で「発表者ノート」をクリックすると、発表者のノートを表示させることができる（聴衆が見ているプロジェクター等には表示されない）。また、「次のスライド」などの項目もある。

*これらの要素は全て、ドラッグアンドドロップでサイズを変更、位置の調整が可能。

## 発表者 ディスプレイが有効になっていない場合

(1).「Keynote」→「環境設定」をクリック

(2).「スライドショー」→「表示時」→「発表者 ディスプレイを有効にする」のチェックを入れる。

## 参考
[Keynoteでプレゼンするなら知らなきゃ損！便利すぎる機能6選]
(https://ferret-plus.com/8076)
node.js + babel + webpack でCUIプログラミングしたかった

# 説明すること
以下のことがしたかったので個人メモ
* Node.jsで単にコンソールで実行するプログラムを記述するためのwebpack.config.js
* .babelrcでstage-2のjavascriptを利用

個人メモなので、設定だけ記載

# Webpack
``` webpack.config.js
var path = require('path');
module.exports = {
    mode: 'development',
    target: 'node',
    devtool: 'source-map',
    entry: [path.join(__dirname, '/src/index.js')],
    output: {
        path: `${__dirname}/dist`,
        filename: 'main.js'
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader'
            }
        }]
    }
};
```
targetにちゃんとnodeを指定してあげないと動かなかった。
https://webpack.js.org/concepts/targets/

# Bable
``` .babelrc
{
    "presets": [
        ["env", {
            "targets": {
                "node": "current"
            }
        }],
        ["stage-2"]
    ],
    "env": {
        "development": {
            "sourceMaps": "inline",
            "plugins": ["source-map-support"]
        }
    }
}
```
presetsにちゃんとstage-2を渡してあげる。
express使い方

前提：nodejs,npmが使える状態であること。

##express環境構築
#####1.workspaceを作りたい場所の一段上で実行

```
express -e testsite
```
#####2.必要なものを自動インストール(たぶん、ejsやfsも勝手に生成される?)

```
cd testsite && npm install
```

#####3.実行できるか確かめる

```
node ./bin/www
```
※上記を実行後に、http://localhost:3000/ へアクセス

##expressの基本工程
あるurlをたたいた時に、"出力されるejsファイル"と"その引数"を決定していく工程。

#####1.testsite/app.jsにルーティングを書く。（似たようなものがある所に書けば管理しやすい）

```
var maincontentsRouter = require('./routes/maincontents');
var gamecontentsRouter = require('./routes/gamecontents');
app.use('/maincontents',maincontentsRouter);
app.use('/gamecontents',gamecontentsRouter);
```
※ここでは、urlとjsの関連付けを行っている。（.jsは省略してよい）

#####2.testsite/routes/にmaincontents.jsを作成し、以下のように編集

```js:maincontens.js
var express = require('express');
var router = express.Router();
var fs = require('fs');
var ejs = require('ejs');
var maincontents = fs.readFileSync('./views/maincontents.ejs', 'utf8');
/* GET page. */
router.get('/', function(req, res, next) {
        res.render('template', 
        {
            title: 'main contents title',
	    content:ejs.render(maincontents,{
        })
        }
    );
});
module.exports = router;
```
※ここではejsファイルを読み込んでいる。testsite/routes/に置かれているjsファイルは、ejsの読み込みと読み込み時に渡す変数内の値の決定が主な役割。

#####3.testsite/routes/にgamecontents.jsを作成し,上記を参考に編集。
※mainをgameに置換するだけ。

#####4.testsite/views/template.ejsを作る。
```ejs:template.ejs
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<html>
    <head>
    <title><%= title %></title>
</head>
<body>
<a href="/maincontents">home</a>
<a href="/gamecontents">game</a>
<p><%-content %></p>
</body>
</html>
```
#####5.testsite/views/maincontents.ejsを作る。
```ejs:maincontents.ejs
<p>main contents</p>
```

#####6.testsite/views/gamecontents.ejsを作る。
```ejs:maincontents.ejs
<p>game contents</p>
```

######7.node bin/wwwで実行して確認してみる。
これで動けばok
EditTextに対してOnKeyListenerをセットしたらキーボード操作ができなくなった

# 事象
EditTextにOnKeyListenerをセットして、キーボードのEnterキーまたは端末の戻るボタンをクリックした際にViewModelで定義した入力完了処理を呼び出す実装をしていました。
しかし、実際にアプリを動かしてみるとEditTextで文字入力を始めようとしたところキーボードが全く反応しませんでした。

# 問題
下記が実際のコードです。

```kotlin:SampleFragment.kt
EditText(context).apply {
    setOnKeyListener { _, keyCode, keyEvent ->
        if ((keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) ||
            (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK)
        ) viewModel.onCompleteEdit()
        return@setOnKeyListener true
    }
}
```
上記コードでは`setOnKeyListener(View.OnKeyListener)`の戻り値が常に`true`になっています。

ここからは理解が合っているか不安な部分ではありますが、、、
この実装のままだと全てのキーイベントをリスナー側で消費することになり、実際にそのキーが押された際の動作までイベントが届かないようになってしまいます。

# 解決策
if文に入れた条件以外のキーイベントは消費したくないので、if文に入った時とそれ以外で返却する値を変えました。

```kotlin:SampleFragment.kt
EditText(context).apply {
    setOnKeyListener { _, keyCode, keyEvent ->
        if ((keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) ||
            (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK)
        ) {
            viewModel.onCompleteEdit()
            return@setOnKeyListener true
        }
        return@setOnKeyListener false
    }
}
```
上記の実装で無事にキーボードが反応するようになりました。

# おまけ
このコードを書いていた時はエミュレータで開発していたのですが、エミュレータでは動いていたので実機で触るまで気付きませんでした。
実機とエミュレータだとキーボードの仕様が違うのでしょうか。
少し調べてみたところ、そもそも`View.OnKeyListener`はハードウェアキーボードに対するイベントを通知するものであって、ソフトウェアキーボードのイベントが必ずしも通知されるとは限らないみたいです。
https://developer.android.com/reference/android/view/View.OnKeyListener
Laravel + Laradockで環境構築から認証処理が動くところまで一気にやる

# TL;DR

[Laravel](http://laravel.jp/)でWebアプリケーション開発する環境を[Laradock](http://laradock.io/)使って作ったけど、大小ちょいちょいつまずくところもあったので、次からノンストップでいけるようにまとめておく

# 環境

Mac OS X 10.13.6

# 準備

[Docker CE for Mac](https://store.docker.com/editions/community/docker-ce-desktop-mac)をDL&インストールして、`docker`、`docker-compose`コマンドが使えるようにしておく

Docker IDが必要なので作っておく

# 想定するゴール

プロジェクト名は`sample`ということで

```
work
├── laradock
└── sample
```

* PHP 7
* Laravel 5.6
* MySQL 5.7
* Nginx(+php-fpm)

こんな感じで、localhostで最低限の認証処理が動くWebアプリが確認できるところ

# スタート

まずはプロジェクト用ディレクトリ作成から`workspace`のコンテナ動かすところまで

```sh
# on local
$ mkdir work && cd work
$ git clone https://github.com/laradock/laradock.git
$ cd laradock
$ cp env-example .env
$ docker-compose up -d workspace
```

`workspace`コンテナ上でLaravelプロジェクトを作成する

```sh
# on local
$ docker-compose exec --user=laradock workspace bash
# on workspace container
$ composer create-project laravel/laravel sample
$ exit
```

`.env`を2箇所書き換える

```sh
# on local
$ vim .env 
```

```
APP_CODE_PATH_HOST=../
MYSQL_VERSION=latest
↓
APP_CODE_PATH_HOST=../sample
MYSQL_VERSION=5.7
```

書き換えたら一度`workspace`のコンテナは落として、新たに`nginx`や`mysql`と一緒に起動する

```sh
# on local
$ docker-compose down
$ docker-compose up -d workspace nginx mysql
```

立ち上がったらlocalhost動いてるはずなので、ブラウザからアクセスして一度動作確認する

<img width="1335" alt="スクリーンショット 2018-08-28 22.05.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/138022/2ea6cdc3-c686-a336-9151-932bcbd632bf.png">

Laravelの画面が確認できたら一旦OKで、このままだとこのページしか操作できないので、認証周りを動かす

まずLaravelプロジェクト側の`.env`の設定が、デフォルトだと[Homestead](https://laravel.com/docs/5.6/homestead)ってLaravel用のVagrant環境を使った想定になっているので、Laradockで動くように一部変更する必要がある

```sh
$ vim ../sample/.env
```

```
DB_HOST=127.0.0.1
DB_DATABASE=homestead
DB_USERNAME=homestead
↓
DB_HOST=mysql
DB_DATABASE=default
DB_USERNAME=default
```

あと認証のページと必要なテーブルを作成するため、`workspace`のコンテナ上でコマンド実行する

```sh
# on local
$ docker-compose exec --user=laradock workspace bash
# on workspace container
$ php artisan make:auth
$ php artisan migrate
$ exit
```

これでもう一度ブラウザからlocalhostにアクセスして確認する

<img width="1335" alt="スクリーンショット 2018-08-28 22.10.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/138022/0705eadb-611e-111e-a1dd-12f1ebefdc4d.png">

右上に`LOGIN`と`REGISTER`のリンクが出現しているはず

これでもう`REGISTER`からアカウント登録して、`LOGIN`からログインするってところまで動かせるようになっているはずなので、ゴールである

# ハマりどころ

まず、デフォルトでそのまま立ち上げるとmysqlは8系が入るが、8系だと`migrate`でエラーになる

[この辺](https://github.com/laradock/laradock/issues/1392)の話だと思われるが、8系全然触ったことないし、情報量的にもまだ5系の方が安心感あるし、ってことで5.7を明示的に指定するようにした

あとLaradockのmysqlはデフォルトで`~/.laradock/data`ってところにデータを永続化してたりするので、知らずに up/down 繰り返してると「データ消えてないな〜？」なんてハマる（`.env`に`DATA_PATH_HOST`って設定値でちゃんと書いてある）

他にも途中で「データベース名変えよう〜」とか脇道逸れながらやってたら結構ちょこちょこハマったので、気をつけたほうがいいというか、まずはここまで動かせること確認してから細かいところ見直すほうがいいと思った（ので記事書いた）
情報処理安全確保支援士（旧：セキュリティスペシャリスト）対策・勉強法　その2

[以前の投稿](https://qiita.com/ma320/items/20a666f127e755c11e9c)で過去問を1回分解き、ある程度自分の学習方針が見えてきた。
そこで、本投稿では購入した試験対策本や、具体的な学習方法を記載する。


#試験対策本
・参考書
[情報処理教科書 情報処理安全確保支援士 2018年版](https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB-2018%E5%B9%B4%E7%89%88-%E4%B8%8A%E5%8E%9F-%E5%AD%9D%E4%B9%8B/dp/4798154180)

知識全般の参考書としてこちらを購入
問題を解きながらこの参考書で理解を深める予定。
分厚いから普段は持ち歩かない。

・試験テクニック用
[ポケットスタディ 情報処理安全確保支援士](https://www.amazon.co.jp/%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93-%E6%9D%91%E5%B1%B1%E7%9B%B4%E7%B4%80/dp/479804931X/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=ETDBXN8YMRJRGECTY4A5)

こちらは試験テクニック用として、通勤や合間にチョコチョコ読む予定。
試験の文章をそのまま使っているようなので、試験になれることができるかなと目論んでいる。

・午後対策
[情報処理安全確保支援士「専門知識+午後問題」の重点対策](https://www.amazon.co.jp/2018-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB%E3%80%8C%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98-%E5%8D%88%E5%BE%8C%E5%95%8F%E9%A1%8C%E3%80%8D%E3%81%AE%E9%87%8D%E7%82%B9%E5%AF%BE%E7%AD%96-%E5%B0%82%E9%96%80%E5%88%86%E9%87%8E%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%89%E5%A5%BD-%E5%BA%B7%E4%B9%8B/dp/4865751130/ref=pd_sbs_14_2?_encoding=UTF8&pd_rd_i=4865751130&pd_rd_r=31e9ab95-a780-11e8-940b-2b2f15882de0&pd_rd_w=6HOcK&pd_rd_wg=OWlFg&pf_rd_i=desktop-dp-sims&pf_rd_m=AN1VRQENFRJN5&pf_rd_p=cda7018a-662b-401f-9c16-bd4ec317039e&pf_rd_r=76EMAVCSNJ8R6S6Z9AMA&pf_rd_s=desktop-dp-sims&pf_rd_t=40701&psc=1&refRID=76EMAVCSNJ8R6S6Z9AMA)

午後の重点対策用として購入予定。
ちなみに応用情報でも購入。
ただ、私はすぐ答えを見てわかった気になるアホなので、1問ずつしっかり考えて抜くとして、最低2回転を目指したい。


#学習方法
・午前I
応用情報の午前の過去問、直近5回分をひたすら解く。
実施時期は9/10の週から開始
問題ごと丸暗記する予定。
3回転したい。

・午前II
基礎学習と位置づけ、過去問道場を5回分を2回転する。
技術を理解し、回答が説明できるようにする。
技術がわからなければ、参考書を読む、ネットで調べるなどで説明できるまで理解する。
これを9/10の週までに終わらせる。

更に、ポケットスタディの午前部分を読破する。

・午後I、午後II
重点対策の本をメインに行う。
2回転目指す。

さらに、問題を解く際には、以下を行う
　①設問のポイントとなる箇所に印をつける
　②設問のポイントとなる箇所と対応する問題文の記述に印をつける
　③添削時に①と②が合っていたか確認し、違った場合は何故違うのかを確認する。

まずは時間配分関係なしに、上記①～③を行い問題を解く。
ある程度慣れてきたら、問題を解く際は午後Iなら1h（実際は1.5h）、午後IIなら1.5h（実際は2h）と実際の試験時間より短い時間設定をして解く。
これで、出題者の意図をミスリードせず、かつ時間を意識して回答できるようになるのでは、と思う。


#学習時間
平日と休日で試験対策を分けて行おうと思う。
これは、平日と休日で使える時間が違うため、平日はある程度細切れで勉強できる内容を行いたいと考えたためである。

・平日
朝の通勤：往復1h
出勤前の会社近くのカフェ：1h
仕事終了後自宅：3h

⇒午前I、午前IIの対策時間にあてる。
　9月後半からは午後問題の時間にもあてる。

・休日
自宅やカフェで勉強：6～8h

⇒午後I、午後IIの対策時間にあてる

平日：7*4=35日*5=175h
休日：7*2=16日*6=96h
合計：271h
※バッファで平日7日削り、休日も2日削ったため、実際は300hくらい取れるかもしれない。


#次回更新
学習計画を立てたが、結構詰め込みすぎじゃね？と思っている。
想定通り進められるか不安である。

試験勉強中に時間があるかわからないが、進捗状況をアップ出来たらしたいと思う。

とにかく勉強頑張る。
0と0以外の連続区間を見つける

#はじめに
こんなデータのときにゼロやゼロ以外の値となるindexのそれぞれの山の始まりと終わりを知りたいときがある。（私はよくある）

![Unknown-2.png](https://qiita-image-store.s3.amazonaws.com/0/121131/c56e7d2a-cf21-d601-7686-2a972b6ba4d1.png)

もっと早くていい方法とか、実は関数あるよとかありそうなのだけど、色々と使いまわしたい自分のためにのんびり作ったものを置いておく。


#使用例
実際に使うとこんな感じ

```python:
data = [12,11,0,0,0,11,12,13,14,12,13,0,0,0,0,0,20,17,16,14,16,0,0,1,1,0,0,10,11,0]
a = np.array(data)
find_zero = False #ゼロを探すときはTrue
res = start_end_index(a, find_zero)
```

```python:
#結果
#区間の始まりのindex
>>> print(res[0])
[0, 5, 16, 23, 27]

#区間の終わりのindex
>>> print(res[1])
[1, 10, 20, 24, 28]

#たとえばひと山の合計値を出すなら
for i in range(len(res[0])):
    print(sum(a[res[0][i]:res[1][i]+1]))
```

#関数

```python:start_end_index

def start_end_index(a, find_zero):
    if find_zero == True:
        index = list(np.where(a == 0))[0]
    else:
        index = list(np.where(a != 0))[0]
    start = []
    end = []
    
    for i in range(len(index)-1):
        print(index[i], index[i+1])
        if (i == 0):
            start.append(index[0])

        if index[i+1] - index[i] > 1:
            end.append(index[i])
            start.append(index[i+1])

        if (i+1 == len(index)-1):
            end.append(index[i+1])
    
    return start,end
```
unityでイージング関数を使っていい感じに敵の発生数を増やしていく

某部活突発アドベントカレンダー n日目です。

unityで制限時間付きのシューティングゲームを作っていたとき敵の出現率が常に一定でマンネリ感があったのでいい感じにしようとした時の話です。
~~書く時間がなかったので乱筆です。すみません。~~
時間が出来たらいろいろ書き直します...

# Before
最初行なっていた敵の出現率の制御方法です。

- まず0~1の間で適当な閾値を決めておく
- そして一定時間おきに0~1の乱数を生成
- 乱数が閾値以下なら敵を生成（instantiate）

というような感じで行なっていたので常に一定の量の敵が出現し続けるという状態でした。最初にも書いたようにこれだと緩急がなくマンネリ化するので閾値を時間経過と共に変化させていくことにしました。

# After
一定の割合で増加していっても面白くないので、閾値を変化させるのにイージング関数を使用します。イージング関数については[ここ](https://easings.net)とかを見てください。僕は普段AfterEffetcsを使って動画を作っているのでかなり馴染み深いヤツです。Blender等DCCツールでアニメーションを付けるときやunityのtimelineやue4のSequencerでも同じようなものがあるので知っている方も多いと思います。

<img src="https://qiita-image-store.s3.amazonaws.com/0/281965/d0409977-09c1-1ef7-85ec-6d65e7e7a08f.jpeg" width=40%>
イージング関数はグラフが曲線なため、出力される値の変化に緩急をつけることができます。横軸を時間、縦軸を閾値として使用することで閾値の変化に緩急が付きます。そして以下のようにイージング関数をスクリプトとして実装します。このメソッドは引数で現在の経過時間を渡すと対応する閾値を返してくれます。
イージング関数のスクリプトに関しては[ここ](https://github.com/fogleman/ease/blob/master/ease.go)を参考にしました。様々なイージング関数があるのでいろいろなのを試してみるといいかもしれません。

```c#:Easing(t)
private float Easing(float t) {
	t /= 180; //この場合は制限時間が180秒のゲームを想定
	t *= 2;
	if (t < 1) {
		return 0.5f * t * t * t;
	} else {
		t -= 2;
		return 0.5f * (t * t * t + 2);
	}
}

```
あとはこのメソッドで返ってきた閾値を使用して以下の`isSpawn()`のように敵の生成判定メソッドを作りました。`Mathf.Lerp (0.03f, 0.6f, threshold);` ではイージング関数から取得した閾値が小さかったり大きかったりすると敵が全く出てこなかったり、逆に多すぎたりしたので閾値を0.03~0.6の間で線形補間しました(この調整はフィーリング)。

```c#:isSpawn()
private bool isSpawn () {
    //currentTimeは現在の経過時間
    float threshold = Easing(currentTime);
    //閾値が小さかったり大きかったりするとゲームバランスが悪いので調整
    threshold = Mathf.Lerp (0.03f, 0.6f, threshold);
    float ramdom = Random.Range (0, 1);
    if (ramdom <= threshold) {
        return true;
    }
    return false;
}
```

# おわり
雑ですがイージング関数を使っていい感じに敵の発生数を増やしていった話でした。
Windiff.exeをやってみた。比較の「インラインで表示」を印刷したい。

#Windiff.exeをやってみた。「インラインで表示」を印刷したい。
(参考)MicrosoftもWindiff.exeを作ってた件について
http://april.fool.jp/blogs/2013/11/microsoft%E3%82%82windiff-exe%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%9F%E4%BB%B6%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

①(管理者権限で)以下のフォルダーにインストールした
「
C:\Program Files (x86)\Support Tools
」

Options＞Show Identical Lines(同一線:google翻訳より)

②printしてみた。

#winmergeの比較印刷
(参考)Winmerge portable にDiffコンテキストがない
https://qiita.com/mrrclb48z/items/2c24b9d7f505f8a2e384

##winmergeの小技
(参考)#2145 Diff pane always empty 
https://sourceforge.net/p/winmerge/bugs/2145/

#Vscodeの比較印刷を探しています。
「Vscodeの表示(V)＞コマンド パレット(C)＞インラインで表示」の印刷方法を探しています。
よろしくお願いします。
型の種類についてまとめた

## JSの型の種類
* 基本型とオブジェクト型の２つに分かれる
* その中で基本型は以下の通り
    * 文字列型
    * 数値型
    * ブーリアン型
    * null型
    * undefined型


###動的型言語と静的型言語について
* 動的型言語とは、変数に対して任意の型を代入できる言語のこと
    * 'hello'（文字列型）や23（数値型）など任意のものを代入できる
* 静的型言語とは、変数に代入できる値やオブジェクト参照を制限するもののこと
* JSは動的型言語のため、**変数**に対しての型はない一方、**値**に対しての型がある。
* その値に対しての型を判定する演算子が**typeof演算子**
* console.log(typeof 37); => number(数値型)
<br>
<br>


##文字列
* typeof演算子で **string**
* クォーテーションで囲む
* 改行やタブなど特殊な文字列に対してはエスケープシーケンスを使う
* Stringクラス（文字列クラス）があり、文字列値から文字列オブジェクトへの暗黙の型変換が起きる
* 明示的な型変換を行う場合はString関数を使う



```js:js
//1.クォーテーションで囲み宣言
const str = 'hello world';


//2.typeof演算子で 'string'
console.log(typeof str);
//string  


//3.エスケープシーケンス（バックスラッシュを使う）
const str2 = 'hello\\world';
//"hello\world"


//4.文字列オブジェクトのプロパティにアクセスできる(メソッドを使える)
console.log(str.length);
//11 (スペースを含む)


//5.文字列オブジェクトのtypepf演算の結果はオブジェクトである
const str3 = new Object('hello world');
str == str3; //型変換を含まず比較
//true
str === str3;//型変換を含んで比較。stringとobject
//false


//6.String関数で明示的に型変換
var str4 = String(47);
console.log(typeof str4);
//string
```

5において、基本的には文字列値と文字列オブジェクトを混同して紛らわしくなるため、明示的に文字列オブジェクトを生成することはない。

また同値比較に関して

* [==]　　型変換を含まず比較する
* [===]　　型変換をして比較する

ことはよく出てくるので覚えておく。


## 数値型
* typeof演算子で **number**
* 64ビットの浮動小数点数で表せられる
* 数値クラス
* NaN (Not a Number)

```js:js
//1.宣言
const num = 30;


//2.typeof演算子で 'nember'
console.log(typeof num);
//num  


//3.数値オブジェクトのプロパティにアクセスできる(メソッドを使える)
console.log(tyoeof num.toString);
//string


//3.不動小数点は数値は近似値になる
（0.1 ＋ 0.2） == 0.3;
//false
(10/3 - 3) == 1/3;
//false


//4.Number関数呼び出し
const num1 = Number('30');
console.log(typeof num1);
//number
 

//5.NaN
NaN + 1;//NaN
NaN * 1;//NaN
NaN == 1;//false
NaN == NaN;//false
NaN > 1;//false

//isNaN関数で判定する
isNaN(NaN);//true

//NaNは型判定でオブジェクトを返す。
const nanobj = new Number(NaN);
console.log(typeof nanobj);
//object
```
5番でNaNはどの演算でもNaNを返し、どの同値比較、比較演算でもfalseを返す。
また、値の型はオブジェクトを返す。



##ブーリアン型
* 真偽値を取る
* tureとfalseはリテラル値

```js:js
//1.宣言
const flag = true;
console.log(flag); //true
console.log(!flag); //false


//2.typeof演算子で 'boolean'
console.log(typeof flag);
//boolean


//3.ブーリアンオブジェクト
console.log(typeof flag.toString);
//stirng


//4.ブーリアン関数
const tval = Boolean(true);
tval == true;
//true
```


##null型
* オブジェクト参照との関係で意味を持ち、「なにも参照していない」という意味
* typeof演算でなぜかobjectを返す。これはバグのようなもの
* nullクラスはない


```js:js
//1.値の型はオブジェクト
console.log(typeof null);
//object


//nullクラスはない
console.log(null.toString);
//typeError
```


##undefined型
* 値はundefinedのひとつだけ
* 明示的に値を代入していない変数の初期値、未定義値
* typeof演算の結果もundefined
* リテラル値ではなく、定義済みのグローバル変数である
    * null値がリテラル値なのは、const x = null; のように代入する必要があるため
* undefined値が現れる場所は以下の通り
    * 未定義の変数の値
    * 存在しないプロパティの値
    * 実引数を与えず関数の呼び出し
    * Return文がない関数の返り値
    * Void演算子の評価結果 

```js:js
//1.undefinedは定義済みのグローバル変数である。代入なしで現れる。
const a;
console.log(a);
//undefined


//undefinedクラスはない
console.log(undefined.toString);
//typeError
```


##オブジェクト型
* 基本型以外はオブジェクト型だと考えて良い
* 関数はオブジェクト型だと考えても問題はないが、typeof演算の結果は　**function**を返す
* 関数型という型があるかどうかは議論が分かれる部分である

```js:js
function fn(){};
console.log(typeof fn)
//function
```
NetBeansでリモートの開発環境のファイルを編集する

## なにするの

NetBeansで、リモートにあるPHPのソースをローカルのNetBeansで編集できるようにする。
今回はSFTPで。

## 手順

####「ファイル」→「新規プロジェクト」

これは普通にいつも通り

#### リモート・サーバからの...を選んで「次」

![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/22d1e0c1-8b96-0bda-617b-b197b453ee35.png)

#### プロジェクト名を記入して

その他は自分の環境に合わせて「次」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/246b4b36-d607-1560-4598-cbcd00f4e44b.png)


#### 「リモート接続」の「管理」をクリックしてリモートの情報登録

![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/60bb4264-555d-404b-fa5d-345a227a69a0.png)

管理画面の「追加」をクリックすると、以下でるので接続名は適当につけて、接続型を選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/fe577455-2853-7b2f-e2c7-6797ffea1be8.png)

赤枠の部分を入力。「接続をテスト」をクリックすれば、接続確認できる
入力完了したら「OK」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/1b2b0074-6865-d834-bd4c-de969c052943.png)

諸事情あっていろいろ隠してるけど、[プロジェクトURL]と[アップロードディレクトリ]を入力、「リモート接続」の部分は、さっき登録したやつを選択して「次」。
アップロードディレクトリは、さっき入力したやつでOKなら「/」でいいと思う。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/1625afff-21c7-48a9-5277-af8477580741.png)

操作したいディレクトリだけ選んで「終了」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/9b2f6af7-2279-e67d-8c81-30e31b66ac23.png)

これで、ファイルがダウンロードされる（時間かかる）

#### 途中でリモートに接続してもいいかって警告でるよ

「OK」する

## ファイルを編集してアップロードしたかったら

デフォルトでは保存したら自動でアップロードされる。
変更したかったら、プロジェクトを右クリック→「プロパティ」から、「実行構成」のここを変えるっぽい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/3e5c131c-698d-7bb5-42ae-2682b61ec0d3.png)


## リモートの変更をダウンロードしたかったら

ダウンロードしたいファイル、またはディレクトリを右クリック→「ダウンロード」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197235/aadfc892-257b-4e50-629d-e22e17685790.png)


## おわり

そのうちリモートデバックに関してもまとめたい

## 追記

上記方法でリモートからファイルをダウンロードすると時間が結構かかるので、ダウンロードは`rsync`を使用したほうがよさそうな気がします。
[rsyncで、リモートとローカルのディレクトリを同期](https://qiita.com/crarrry/items/21fec46888e8b744346a)

## 更に追記
上記方法ではなく、

**`rsync` でローカルにソース持ってくる**
↓
**「既存のプロジェクト作成」でプロジェクト作成**
↓
**設定の途中でリモートサーバとかパスを指定（保存時に自動でアップロードする設定も）**

これで、アップロードはNetBeansの機能で保存時に自動で行われ、
リモートがもし更新（git pullした時とか）されたときは`rsync`で持ってくる方法で落ち着きました。
メールのデコード処理の流れ

# メール本文のデコード処理の流れ
受信したメールのメッセージには、Content-Transfer-EncodingヘッダとContent-typeヘッダが記載されています。 
デコード処理の流れとしては、まずContent-Transfer-Encodingヘッダを見てデコードし、次にContent-typeヘッダのcharsetを見て更にデコードします。

## Content-Transfer-Encodingの種類
- base64
- quoted-printable
- その他（7bit, 8bit, binary）

早い話、base64とquoted-printableの場合のみそれぞれの方式でデコードし、その他の場合は何もしなくて良いです。

## charsetの種類
- iso-2022-jp
- utf-8
- その他

iso-2022-jpとutf-8の場合はそれぞれの方式でデコードします。その他と書きましたが、例えば中国のフリーメールとか使うとISO-8859-1とかあります。
<a href="http://www-01.ibm.com/support/docview.wss?uid=swg22000213">charsetが無い場合もあるようです。</a>その場合、メール body部に使用されている文字コードを推測して変換するなどの対応が必要です。
以下の例ではその他を適当にasciiでデコードしています。

## コード例
以上の流れをpythonで書くと、次のようになります。

```python
def decode_msg(msg, cte, charset):
    """ メール本文をデコードする
    * msg
      - メール本文（バイナリ形式）
    * cte(Content-Transfer-Encoding)
      - "base64"
      - "quoted-printable"
      - それ以外は、そのまま
    * charset(文字コード)
      - "utf-8"
      - "iso-2022-jp"
      - それ以外は、"ascii"とみなす
    """
    import quopri
    import base64

    if cte == "base64":
        b = base64.b64decode(msg)
    elif cte == "quoted-printable":
        b = quopri.decodestring(msg, header=False)
    else:
        b = msg
    if charset == "iso-2022-jp":
        return b.decode("iso-2022-jp", "ignore")
    elif charset == "utf-8":
        return b.decode("utf-8", "ignore")
    else:
        return b.decode("ascii", "ignore")
```


# SubjectヘッダやFromヘッダのデコード処理の流れ
Subjectヘッダ（件名）やFromヘッダ（送信元）は本文とは別でエンコーディングされています。どのような形で送られてくるかというと、

```python
?[文字コード]?[Content-Transfer-Encoding]?[メッセージ]
```

という形になっています（基本は）。
結構ややこしく、例を以下に列挙します。

## 文字コードがUTF-8で、Base64変換されている場合
```python
b"From: =?UTF-8?B?44CQQVdTIOOCp...?="
```

## 文字コードがiso-2022-jpで、Base64変換されている場合
```python
b"From: =?iso-2022-jp?B?GyRCMlRG...?="
```

## 文字コードがUTF-8で、quoted-printable変換されている場合
```python
b"Subject: =?UTF-8?Q?=E3=80=90=E3=83=A4=E3=..."
```

## ただのバイナリ（ascii）
```python
b"From: "tanaka@example.com" <yamada@example.com>"
```

## 文字コードがiso-2022-jpで、Base64変換されているが、2つ目の送信元はただのバイナリ
```python
b"From: =?iso-2022-jp?B?GyRCPF...==?= <tanaka@example.com>"
```

## 複数行に跨っている（folding）
```python
b"From: =?iso-2022-jp?B?GyRCQmdOUxsGyhCTktFGyRCM3Q8MDJxGyhC...?=
=?iso-2022-jp?B?GyRCPFIhQg...==?= <tanaka@example.com>"
```

全てに対応させるには気合が必要です。
と思ったら、Linuxコマンドで一撃でデコードできるっぽいです。
https://qiita.com/sheepland/items/2065ffcc7ec8c03145cc


# 備考
日本ではiso-2022-jp（JIS）がいまだに根強く使われています（大手新聞社やIT企業のメールでも使われています）。調べた感じ、ガラケーがまだ現役だからが主な理由のようです。

果たして自分がメールを送信するときにiso-2022-jpを選ぶかUTF-8を選ぶか悩みどころですが、ガラケーを気にしないのであればUTF-8で良いと思います。
LCDディスプレイのHelloWorld

少し時間ができたので、以前購入してまだ使っていないLCDディスプレイがあったので、テストしてみた。

素人には、'どれ' と 'なに' をつなげるのか？とか、抵抗はいらないの？など不安だらけ。
3.3vのwifiモジュールに9vの電池を直でつなげて、wifiモジュールを飛ばしたばっかりだから、なおさら疑心暗鬼。

でも今回はあっさり簡単だった...ほっ。

##LCDディスプレイ
2004 LCD ディスプレイ モジュール IIC/I2C/TWI
<a href="https://www.amazon.co.jp/gp/product/B073H1LG5X/ref=as_li_ss_il?ie=UTF8&psc=1&linkCode=li2&tag=aruki1108-22&linkId=e5456f86c59eb9df28e4da13a4631e8b&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B073H1LG5X&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aruki1108-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aruki1108-22&language=ja_JP&l=li2&o=9&a=B073H1LG5X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

##ライブラリのダウンロードとArduino-IDEへインストール
Arduino-LiquidCrystal-I2C-library

```
https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
```

##Arduino MEGAと接続

|ディスプレイ側|GND|VCC|SDA|SCL|
|:---:|:---:|:---:|:---:|:---:|
|接続|↓|↓|↓|↓|
|Arduino側|GND|5V|デジタル20ピン|デジタル21ピン|

##ソース

同包されているサンプルソースをほぼ利用。

`LiquidCrystal_I2C lcd(0x27, 16, 2);`
この部分だけ、ディスプレイに合わせて設定(20桁 - 4行)
`LiquidCrystal_I2C lcd(0x27, 20, 4);`

アドレスの`0x27`はそのままだけど、Amazonの説明には`0x3F`のどちらかと書いてあった。

```
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);

void setup()
{
  // initialize the LCD
  lcd.begin();

  // Turn on the blacklight and print a message.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
  // Do nothing here...
}
```

##結果
![IMG_3281.JPG](https://qiita-image-store.s3.amazonaws.com/0/271873/20e59772-ceb9-ec42-d48f-d92a347e68a0.jpeg)
SAP Cloud Connector for Linux

# 0. はじめに
ここ最近、SAP Cloud PlatformというPaaSを触る機会が多い筆者です。

SAP Cloud Platform というクラウド環境とオンプレミス環境で動作するSAPシステム等々を接続する為のコネクターである
SAP Cloud Connector をRedhat Enterprise Linux 7.4にインストールしてみました。

ちなみに、Connectorという名ながら、GlobalIPを持つ必要がなく、オンプレミス側から貼るSSL/TLSトンネルの中で様々な通信が行われる仕様です。よって、Cloud Connecotorが導入されたサーバが直接もしくはプロキシを通してインターネットに出れてさえいれば接続できます。

#1. 環境情報
```shell-session
# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.4 (Maipo)
```

#2. 前提条件確認
以下のサイトで導入環境の前提条件を確認します。
ハードウェア、OS、JAVAバージョン等に条件があります。

[SAP Cloud Platform Connectivity - Prerequisites](https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/e23f776e4d594fdbaeeb1196d47bbcc0.html)


#3. 導入作業
##3.1 メディアダウンロード
以下のサイトからメディアをダウンロードする。（2018/06/28現在の最新版を利用する）

[SAP Development Tools](https://tools.hana.ondemand.com/#cloud)

* sapjvm-8.1.042-linux-x64.rpm
* sapcc-2.11.1-linux-x64.zip

##3.2 JVMインストール
SAP Cloud Connectorに対応するJVMはOracleJVMとSAPJVMの2つがある。
今回はSAP製品ということで、親和性の高そうなSAPJVM8を選択する。

```shell-session
# rpm -ivh sapjvm-8.1.042-linux-x64.rpm
# rpm -qa | grep jvm
sapjvm_8-1.042-1.x86_64
```

※ちなみに、SAPJVM = SERVER用途の安定性とモニタリング機能が強化されているそうな。


##3.3 SAP Cloud Connector インストール

```shell-session
# rpm -ivh com.sap.scc-ui-2.11.1-2.x86_64.rpm
# rpm -qa|grep scc
com.sap.scc-ui-2.11.1-2.x86_64
```

##3.4 接続確認
インストール後、自動的に起動するので、接続確認をする。
~~UserNameがケースセンシティブなところにはまったのは内緒の話。~~

`https://<hostname>:8443`へアクセスすると以下の画面が表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/208873/b3f96c78-f900-b761-7396-e6061892e848.png )

##3.5 初期設定
`Administrator`のパスワードを設定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/208873/6725f7c0-41f6-b798-867e-45674559339c.png)


完了！

#4. 起動停止
* 起動

```shell-session
# service scc_daemon start
```

*停止

```shell-session
# service scc_daemon stop
```
...RHEL7にインストールしたんだから`systemctl`で制御できるようにしてほしかった...(ﾎﾞｿｯ
Agile Japan 2018 基調講演『モブプログラミングと”フロー”の力』を聞く

# これはなに

[Agile Japan 2018 基調講演](https://agilejapan-osaka.connpass.com/event/96746/)でモブプロの講演があって聞いた。
モブプロってよく聞くようになったけど、なにがいいんだろうと思っていたので、とても良質なインプットになった。
ホットなウチに自分の中でざっとまとめておく。

# 自分のなかでの勝手な超訳

- 俺たちは必要なものと作るのに、必要なスキルと知識をもったメンバーを別々の部屋に閉じ込めて個別のアウトプットをして組み合わせているが、それがうまくいくとおもうのかい？　俺たちは実際、筋の良くない物を大量につくっている。
- ゆっくりでも正しいものを作るほうが価値がある
- モブプロ
    - 割り込みなし、シングルタスク、待ち時間なし、1つのことに集中するという最強のフロー
    - チームメンバー感の知識、スキルもリアルタイム同期

# Agile Japan 2018基調講演 1『モブプログラミングと”フロー”の力』のメモ

- モブプログラミングは、同じ仕事を同じ時間に同じ場所で同じコンピューターですること。
    - 知識もスキルもバラバラのメンバーがあつまって
- 典型的なプラクティス
    - ドライバーナビゲーター
    - ドライバー
        - インプットするひと
    - ナビゲーター
        - 考える人
    - チームがプログラミングする
        - 周りが考え、アイディアをシェアして、コードとしてインプットしていく
- どこでもできる
    - リモートでも
- 生産性はあがるのか？
    - しらんけど、うまくいんだって。
- モブプログラミング
    - ばらばらで作業してもアウトプット量は増える。だけどはゴミみたいなアウトプットがふえる。本来一緒に仕事するべき人たちがバラバラに仕事している。
    - もっと役立つ物ができる。
    - 品質が高い物ができる
    - モブプログラミングはチームの頭の中をインテグレーションする
    - 一個のことに集中すればいろんな問題は解消する
- キューイングの問題が最大の問題
    - 質問がかえってくるまでの時間
        - 返ってくるまでにほかのことをやる。マルチタスクになる。コンテクストスイッチが発生する。
        - 「在庫」（しかかり中のタスク）は少ないほどよい
- モブプロでキューがなく、待ちもなく、割り込みがなく、マルチタスクがない理想の状態に近づくことができる
- モブプログラミングは強制しないほうがよい。モブプログラミングしたくなるように
- QA
    - メトリックスある？
        - 個人でとれることとおなじようにとれる
        - リードタイムが典型的。一つのタスクの開始から終了までの時間をはかる
        - 安易なメジャメントには抵抗すべき。計測することが目的になってしまう。

## よくわかってないこと

- プログラミング以外のタスクは？
    - 設計はモブでできそうだけど、テストとかドキュメントとか、リリース、デプロイとかなんでもモブがいい
- ビジネスサイドに白い目でみられたときに、定量的に計れるなにかで効果を提示するのとか、モブプロの意欲なくなるんだけど。

## 関連記事
https://takaking22.com/2018/agilejapan2018-mobprogramming/
.ssh/configの設定でエラー: ssh_exchange_identification: Connection closed by remote host

`.ssh/config` の設定次第で表題のエラーが出ることがある。

# エラー
```bash
ssh_exchange_identification: Connection closed by remote host
```

# 問題のある設定
```bash
Host 4t_Bastion
  HostName xx.xx.xx.xxx
  User ubuntu
  IdentityFile ~/.ssh/secret_key
```

# 対策
頭が数字から始まるHost名を指定していると同エラーが発生する。なのでHost名を `4t_Bastion` => `test_Bastion` に変更。

```bash
Host test_Bastion
  HostName xx.xx.xx.xxx
  User ubuntu
  IdentityFile ~/.ssh/secret_key
```

# 環境
- macOS High Sierra
- ubuntu: `16.4 LTS`
React + create-react-app + yarn + nodejs @ CentOS7 の環境構築（2018年版）

## はじめに

CentOS7へのReact開発環境インストールメモです。

2018年08月末現在の内容です。

**作業環境**
CentOS Linux release 7.5.1804 (Core)
VirtualBox(5.2.16r123759)(ホストオンリーアダプタ経由で接続)

nodejsはバージョン管理ツール無しでのセットアップです。

最後の「Reactアプリケーションの作成＆起動」以外はrootで作業しています。

## Nodeのバージョンを決める

導入するNodeのバージョンを決めるために、create-react-appの要件を確認します。
https://github.com/facebook/create-react-app
「Creating an App」の部分を参照すると

> Node >= 6

とのこと。
（当然create-react-appで用意されるReactも上記条件で動作するはずです）

Nodeの2018/08/28現在のバージョンとサポート状況を確認します。
https://github.com/nodejs/Release#release-schedule

> 6系
6.14.4(15-Aug-2018)
End-of-life: April 2019

> 8系
8.11.4(15-Aug-2018)
End-of-life: December 2019

> 10系
10.9.0(15-Aug-2018)
End-of-life: April 2021

モジュールの互換性など考慮する必要がありますが今回は10系を使用します。

## インストール

### Nodejsをインストール

公式サイトを参考にしてNode.jsをインストールします。
https://nodejs.org/en/download/package-manager/#enterprise-linux-and-fedora

CentOSなので「Enterprise Linux and Fedora」を見て、10系なので次のスクリプトを実行。
私はrootで作業していたので、公式のまま次のスクリプトを実行したところエラーが発生してしまいました。

```{shell}
(失敗したコマンド)
curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -

> Your distribution, identified as "centos-release-7-5.1804.4.el7.centos.x86_64", is not currently supported, please contact NodeSource at https://github.com/nodesource/distributions/issues if you think this is incorrect or would like your distribution to be considered for support
```

rootでsudoを実施したのが原因でしたが、見当違いのエラーメッセージが出てしまい混乱します、、、

sudoを外して、

```{shell}
curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
```

を実行すると正しくリポジトリに追加されました。

つづいて、`yum install` を実行してNodejsをインストールします。

```{shell}
yum -y install nodejs
```

### Yarnのインストール

最近は起動のサジェストがYarnになっているそうなので、
(https://qiita.com/sho7/items/bb564e22a096eaea9877)
次のコマンドでインストールします。

```{shell}
npm install yarn -g
```

### Create-react-appをインストール

次のコマンドでインストールします。

```{shell}
npm install create-react-app -g
```

## 環境設定

### 待ち受けポートの解放

(仮想環境利用時など、reactサーバに外部から接続する場合)CentOS7ではポート開放しないとデフォルトの待ち受けである3000でページ表示できません。

次のコマンドでポートを開けます。

```{shell}
# ポートを開放
firewall-cmd --add-port=3000/tcp --zone=public --permanent

# firewallをリロード
firewall-cmd --reload
```

## Reactアプリケーションの作成＆起動

プロジェクトを作成したいフォルダまで移動し、次のコマンドで雛形を作成します。

```{shell}
create-react-app my-app
```

次の手順でアプリケーションを起動します。

```{shell}
cd my-app
yarn start
```

サーバが起動した旨のメッセージが出力されれば、http://サーバのアドレス:3000/ でReactの初期画面が表示されます。

ご参照いただきありがとうございました。
Gradle4.9で依存ライブラリを含む単一で実行可能なjarを生成する

メモ

# 問題

今までこれを使ってオールインワンのJARを生成していた。

- gradleをつかって依存ライブラリを含む単一で実行可能なjarを生成する https://qiita.com/mychaelstyle/items/9338f558903ac0c14bc3

---

しかしGradleを4.9にしたら依存先ファイルが入っていないJarが出来上がるようになった。
compileをimplementationにしたりしたので、
```from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }```
という記述を
```from configurations.implementation.collect { it.isDirectory() ? it : zipTree(it) }```
に変えたところ、次のように怒られるようになった

```
C:\～～>gradlew

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\～～\build.gradle' line: 129

* What went wrong:
A problem occurred evaluating root project '～'.
> Resolving configuration 'implementation' directly is not allowed

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s
```

なお名前が間違っている場合は
```> Configuration with name ':api' not found.```
のように言われるので、明確に内部でブロッキングされているようだ。

エラー文で探してもIssueしか出てこなかったので調べた。

# 策

ここにGradle3.3から ```Configuration.isCanBeResolved()``` が追加されたとある。

- Gradle 3.4-rc-1: "Resolving configuration 'apiElements' directly is not allowed" #31 https://github.com/jeremylong/dependency-check-gradle/issues/31

つまりConfigurationごとにcollectできるか否かが違うと。

---

なので解決可能なConfigurationの中から依存先Jarの一覧が得られないか探してみた。
ここによると ```configurations``` はCollectionだそうなので、次のコードで1個1個調べた。

- https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ConfigurationContainer.html

```gradle
configurations.stream().forEach {
	println "################### " + it
	if (it.canBeResolved) {
		it.collect {
			println it.isDirectory() ? it : zipTree(it)
		}
	}
}
```

```:得られたConfigurationの一覧
configuration ':annotationProcessor'
configuration ':api'
configuration ':apiElements'
configuration ':archives'
configuration ':compile'
configuration ':compileClasspath'
configuration ':compileOnly'
configuration ':default'
configuration ':implementation'
configuration ':junitPlatform'
configuration ':runtime'
configuration ':runtimeClasspath'
configuration ':runtimeElements'
configuration ':runtimeOnly'
configuration ':testAnnotationProcessor'
configuration ':testCompile'
configuration ':testCompileClasspath'
configuration ':testCompileOnly'
configuration ':testImplementation'
configuration ':testRuntime'
configuration ':testRuntimeClasspath'
configuration ':testRuntimeOnly'
```

このうち、 ```compileClasspath``` がなんかそれっぽい気がしたので、これを使ってみる。

# 結論

結果、次のコードで以前のように依存先が全部入ったJarが出来上がった。

```from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }```
Amazon Linux WorkSpaces でマカーがつまづいたこと: (1) シェルのスタートアップの設定は .bashrc に書く

Mac でターミナルアプリを開くと ~/.bash_profile が読み込まれます。

対して、Amazon WorkSpaces (というより Linux デスクトップ全般) では、ターミナルアプリを開くと ~/.bashrc が読み込まれます。

Mac と同じ感覚で ~/.bash_profile にせっせと設定を書き足していたのですが、なんにも起こらないので、私の頭には？のマークが :thinking:

初期状態から ~/.bash_profile が意味ありげに存在[^1]していたのでひっかかってしまいましたが、~/.bash_profile ではなく ~/.bashrc を使うことにします。

[^1]: 少し解説。~/.bash_profile はログインシェルのスタートアップで読み込まれるスクリプトです。ただし、WorkSpaces クライアントからのリモートログインでは ~/.bash_profile ではなく ~/.profile が読み込まれます。このことが、WorkSpaces での ~/.bash_profile の扱いをややこしくしています。私の意見としては、ユーザーのホームディレクトリの初期状態では Ubuntu と同じように ~/.bash_profile ではなく ~/.profile を作っておくか、いっそ ~/.bash_profile も ~/.profile も作らないかのどちらかの方がわかりやすいと思います。