OmniAICreator/Qiita-1.07M huggingface dataset:
www-dataでssh

apacheからCGIでsshを実行したかった。CGIを実行してるのはもちろんapacheちゃんだよねー知ってるって！って調べたらwww-dataさんだった。(ubuntu 16.04 LTS)

誰ｗｗ

鍵とか作りたくても、su www-dataでなれないし、rootになってからsuしても
This account is currently not available.
って怒られるし、もうどうしたら・・・

と悶々としていたら、

https://qiita.com/Ouvill さんの記事
https://qiita.com/Ouvill/items/02faa51d04b76c60d942

にナイス情報が！

簡単に言うと、sudo -u www-data ssh-keygenなどとすればいいってことで、目からうろこです。

ありがとうございます。
FirestoreのデータをGoogle Cloud StorageへエクスポートしてローカルPCへ持ってくる


#### FirestoreのデータをGCSへエクスポートする

* US-CENTRAL1など一部のリージョンのみ可能
* ストレージもRegional含む一部のクラスのみ可能

```shell
$ gcloud alpha firestore export gs://BACKET_NAME/my-exports-folder/export-name1 --project PROJECT_NAME
```

#### GCSからローカルへコピーする

```shell
$ gsutil cp -r gs://BACKET_NAME/my-exports-folder/export-name1 .
```
【Nuxt.js】create-nuxt-appでNuxt.js(v2.0.0)を始める

まったく真っ白の状態からNuxt.jsで作ったサンプルアプリを動かすまでの記録です。

## 1. `yarn`のinstall
🚀`$ brew install yarn`

## 2. `create-nuxt-app`のinstall
Nuxt.jsのプロジェクトを対話形式で作成できるコマンドラインツールです。
https://github.com/nuxt-community/create-nuxt-app

サーバサイドとUIのframeworkを選べたり、最初から`axios`や`ESLint`をガッと入れてくれます。大変たすかる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/38442/05066d75-844a-b3a5-3324-ffeb368b0083.png)
🚀`$ yarn global add create-nuxt-app`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/38442/ebb2d478-dbcc-6076-cd2c-aca15f99a0a7.png)

## 3. Nuxt.jsプロジェクトの作成
🚀`$ create-nuxt-app NuxtSample`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/38442/5654e8a2-72ea-e840-4332-48245622a428.png)

## 4. Nuxt.jsプロジェクトの起動
🚀`$ cd NuxtSample`
🚀`$ yarn run dev`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/38442/e95f5264-85a7-c9a4-d993-289f9bf509c3.png)

🚀ブラウザで`http://127.0.0.1:3000/`にアクセス
<img width="1680" alt="スクリーンショット 2018-09-27 16.01.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/e2fbe4e5-f57d-b739-1827-73f7987c4d7f.png">

Nuxtのバージョンも`2.0.0`になっています。
<img width="873" alt="スクリーンショット 2018-09-27 16.13.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/c450d108-8c09-f1df-aff9-0a20ca616510.png">

## まとめ
Nuxt.jsプロジェクトの開発は`create-nuxt-app`で爆速スタート!!🚀

## 参考リンク
- npmから乗り換えてわかったYarnの4つのメリット  
https://qiita.com/tonkotsuboy_com/items/0242928ab32794d11f76
- Nuxt.js v2.0.0がリリースされたので触ってみた【変更点まとめ】  
http://studio-andy.hatenablog.com/entry/nuxt-v2
【Rider】一つのショートカットキーに複数の動作を割り当てる

# はじめに
Unity+C#に始まりそのままの流れでHTML,Sass,TypeScriptなどWebフロントエンドをRiderで書いてるsu10です。

タイトルの通り、Riderで一つのショートカットキーで複数の動作（例：フォーマット＋保存）を実行する方法がわからず調べたので、その備忘録です。

具体的には[create-react-app](https://github.com/facebook/create-react-app)を使ってRiderでTypeScriptを書いてたら`"Import sources within a group must be alphabetized"（importは辞書順に並べろ！）`のエラーが出たので`"Optimize imports"`+`"Reformat Code"`を一度にまとめてやりたい状況でした。

「rider keymap multiple」とかでググっても出てこなかったので、同じことで困っているUnity+Rider使いの助けになれば幸いです。

# やり方
例えば`"Reformat Code"`と`"Save All"`に同じショートカットキーを割り当てても警告が出る上に片方しか実行されないので、

0. `"Reformat Code"` → `"Save All"` の動作を続けて行うマクロを作成する
0. 作成したマクロに適当なショートカットキーを割り当てる

という手順で実現します。

詳細は[こちら](https://qiita.com/ntaoo/items/0af5f9b05a5f0093b670)にまとまっていたので以下に引用します。Intelij IDEAに関する記事ですが、Riderでも手順は同じでした。

>Edit -> Macros -> Start Macro Recording
Code -> Reformat Code
File -> Save all
Edit -> Macros -> Stop Macro Recording
マクロに名前をつける ("formatted save"とか)
Preferences -> Keymap
そのマクロを検索し、キーボードショートカットを追加する(CMD+Sなど。Save Allを上書きしてしまうと良い)。

# 参考
+ [IntelliJ IDEAでファイル保存時にcode formatする](https://qiita.com/sisidovski/items/bde2d844c3c73457923c)
+ [Intelij IDEAのMacroでコードのsave時に自動的にコードフォーマッティングする
](https://qiita.com/ntaoo/items/0af5f9b05a5f0093b670)
+ [エディタでのマクロの使用](https://pleiades.io/help/idea/using-macros-in-the-editor.html)
macOS Mojave で crontab -e できない

`crontab -e` で変更すると下記のような出力が出て設定できない。

```
crontab: installing new crontab
crontab: tmp/tmp.29978: Operation not permitted
crontab: edits left in /tmp/crontab.TTtm6Usm2O
```
- [Unable to add crontab entry in macOS Mojave |Apple Developer Forums](https://forums.developer.apple.com/thread/106320)

によると、"システム環境設定" の "セキュリティとプライバシー" で、"フルディスクアクセス" を Termnal や iTerm に許可する必要があるらしい。

許可したら問題なく設定できた。
Pythonでプログラミングを始めよう!　〜辞書の使い方〜

#辞書(dictionary)とは
辞書（dictionary）型とは、{}の中にkeyとvalueの組み合わせが含まれているデータのことです。

```python
{'キー１':'値１','キー2':'値2','キー3':'値3'}
```

#辞書型オブジェクトの作り方
括弧{}で囲んだ中に要素をカンマ「,]で区切って記述します。
要素はキーと値のペアで構成され,キーと値はコロン「:」で区切って記述します。

```python
x = {'名前':'山田', '年齢':25}
```

上記の例ではキーが「名前」で値が「山田」とキーが「年齢」で値が[25」の辞書型オブジェクトを作成しています。

#要素を参照する方法
辞書型オブジェクトは、[リスト型](https://qiita.com/fotome-developer/items/6d0c334684e78768b1ad)のように多くの要素を持つことが出来ます。

要素を取り出すためにはキーを使い、値を取得します。

```python
x = {'名前':'山田', '年齢':25}
y = x['名前']
print(y)
#山田
```

注意したいのは、要素へのアクセスの際は{}ではなく[]を使うということです。

上記だと、キーが存在しないエラーになってしまいます。
キーが存在しない場合に任意の値を返すにはget関数を使います。

```python
x = {'名前':'山田', '年齢':25}
y = x.get('性別','男')
print(y)
#男
```

#要素の追加
辞書型オブジェクトに、要素を追加してみましょう。
下記のコードでは、キーが「性別」で値が「男」の要素追加しています。

```python
x = {'名前':'山田', '年齢':25}
x['性別'] = '男'
print(x)
#{'名前':'山田', '年齢':25, '性別':'男'}
```

#要素の削除
要素を削除する場合、pop関数もしくはclear関数を使います。

個別に要素を削除するには、pop関数を使います。

```python
x = {'名前':'山田', '年齢':25}
x.pop('名前') #pop('要素のキー')
print(x)
#{'年齢':25}
```

全ての要素を削除するには、clear関数を使います。

```python
x = {'名前':'山田', '年齢':25}
x.clear()
print(x)
#{}
```

#要素を検索する

要素を検索する方法として、下記の３パターンが挙げられます。
1. キーで検索
2. 値で検索
3. キーと値の両方で検索する
それぞれの検索方法を説明していきます。

##辞書のキーの存在を確認、取得（検索）: in演算子
辞書に対してキーの存在を判定するにはin演算子を使います.
ちなみにPython2では使えたhas_key関数は,Python3では無くなっています。

```python
x = {'名前':'山田', '年齢':25}
print('名前' in x)
#True
print('キー' in x)
#False
```

## 辞書の値の存在を確認、取得(検索): in演算子, values関数
辞書に特定の値が含まれているかどうかを判定するには、in演算子と
辞書の全ての値のみを配列で返すvalues関数を使います。

```python
x = {'名前':'山田', '年齢':25}
print('山田' in x.values())
#True
print('名前' in x.values())
#False
```

## 辞書のキーと値の組み合わせで存在を確認、取得(検索): in演算子, items関数
辞書に特定のキーと値の組み合わせが含まれているかどうかを判定するには、
in演算子と辞書の全てのキーと値の組み合わせを返すitems関数を使います。

```python
x = {'名前':'山田', '年齢':25}
print(('名前','山田') in x.items())
#True
print(('名前','佐藤') in x.items())
#False
```

## For文を使っての繰り返し処理



## 辞書内包表記
辞書も[リスト(list)](https://qiita.com/fotome-developer/items/6d0c334684e78768b1ad)と同じように内包表記が使えます。

基本的な書き方は下記になります。

処理対象(配列などの部分)が、配列(リスト)の場合

```python
x = { str(i):i for i in 配列}
```
上記は、下記の処理を内包表記を使って書いたものになります。
例)

```python
list = ['a','b','c']
x = {}
for i in list:
    x[str(i)] = i

print(x)
#{'a':'a', 'b':'b', 'c':'c'}
```

処理対象(配列などの部分)が、辞書の場合

```python
x = { k:v for k,v in 辞書.items()}
```

例)

```python
x = {'名前1':'山田', '年齢1':25,'名前2':'佐藤', '年齢2':20}
y = {}
for k,v in x.items():
    y[k] = v

print(y)
#{'名前1': '山田', '年齢1': 25, '名前2': '佐藤', '年齢2': 20}
```

条件を満たす辞書の要素を抽出して、処理を適用するには
下記のようにします.

```python
x = {'名前1':'山田', '年齢1':25,'名前2':'佐藤', '年齢2':20}
y = { k:v for k,v in x.items() if '名前' in k }
print(y)
#{'名前1': '山田', '名前2': '佐藤'}
```

#まとめ
辞書の扱い方は、上記のほかにもいろいろとあります。
[公式ドキュメント](https://docs.python.jp/3/tutorial/datastructures.html#dictionaries)なども確認してみ下さい。

次回は、文字列操作について解説していきます！
pyファイルの実行が出来ずハマった件(input関数)

VS Codeでデバッグしている時は正しく動くのに、pyファイルをダブルクリックしたら動かないという事象に見舞われました。

結論としては、VS Code上では**Python 3.x**系が動いていて、ダブルクリックによる実行時には**2.x**が動いていたためでした。

よって、どちらのバージョンにも対応できるような方法を考えた話です。

# input関数の仕様が違う
Python 2.x系と3.x系ではinput関数の仕様が違います。

Python 2.xの場合、input関数を普通に呼んでしまうと、ユーザ入力値は数値として扱われます。

そのため、文字列を扱いたい場合には、

`raw_input`


という別の関数が用意されています。

3.x系になるとこの2つは`input`に統合されました。

以上の理由から、Python 2.x系と3.x系で処理を分けてあげる必要があります。


# 実行されているPythonのバージョンを取得

Pythonのバージョンを取得する方法は以下です。

```python:test.py
import sys

PYTHON_VERSION = sys.version_info.major #一応定数として入れておく
```

#バージョンを区別

今回はinput関数を使うので、関数をラッピングします。

```python:test.py
def char_input( text ):
    if PYTHON_VERSION == 2:
        return raw_input( text ) #Python 2.x
    else:
        return input( text ) #Python 3.x
```
これで、`char_input`関数を使えば、どちらのバージョンにでも対応できます。


#おわりに

これ、結構ハマりました・・・

最初try文でトラップして、調べていくうちに`input`が原因だと分かりました。

VS Codeのデバッガでは普通に動いていたのでおかしいなーと。

たまたま自分のＰＣに以前使っていたPython2.x系がインストールされていたためここに気づきましたが、

こういったバージョンの違いによる対応をしてあげるのが親切ですね。
LaravelでTestを書くときはWithFakerトレイトが便利

LaravelのTestでFakerを使いたい場合にはWithFakerトレイトを使うと便利です。


```php:ControllerTest.php
<?php

namespace Tests;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;

class ControllerTest extends TestCase {
    use WithFaker;

    public function() {
        $this->faker // fakerが使える
    }
}

```
jQueryでthis option:selectedを取得する

jQueryのon()メソッドで、イベントの呼び出しもとセレクトボックスのthisとoption:selectedを組み合わせて使いたかったのですが、書き方がわからなかったので調べました。

以下のように書くことで実現できました。

```
$("option:selected", this)
```

例

```
$(".select_prefecture").on('change', function (e) {
    prerectureName = $("option:selected", this).text();
}
```
CentOS7でのKubernetes クラスタ構築（worker編）

[こちら](https://qiita.com/Esfahan/items/256fdb78e6a40b7c3e1f)を参考にした、kubernetes worker nodeの設定です。

実行環境は次の通りです。

* CentOS 7.4
* kubernetes v1.5.2
* flanneld 0.7.1
* etcd 3.2.22
* Docker 1.13.1


## kubernetesのインストール

```
# vi /etc/hosts
10.44.59.76 worker1

yum -y install kubernetes docker flannel
```

##マスターの設定

```
# vi /etc/kubernetes/config
KUBE_MASTER="--master=http://10.44.59.239:8080"
```

##Kubeletの設定

* KUBELET_ADDRESS: worker nodeのIPアドレス
* KUBELET_HOSTNAME : worker nodeのホスト名
* KUBELET_API_SERVER : APIサーバーのIPアドレス（masterと同居)

```
# vi /etc/kubernetes/kubelet
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=10.44.59.76"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=worker1"

# location of the api-server
KUBELET_API_SERVER="--api-servers=http://10.44.59.239:8080"
```

##flannelの設定
master worker間の通信用にflannnelの設定を実施（etcdをインストールしたmasterのアドレス）

```
# vi /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://10.44.59.239:2379"
```


##サービスの起動

```
# systemctl start kubelet
# systemctl start flanneld
# systemctl start docker
# systemctl start kube-scheduler
# systemctl start kube-proxy

# systemctl enable kubelet
# systemctl enable flanneld
# systemctl enable docker
# systemctl enable kube-scheduler
# systemctl enable kube-proxy
```

##masterからworkerの起動状況を確認

```
# kubectl get nodes
NAME      STATUS    AGE
master    Ready     40m
worker1   Ready     2m
```

※参考
[CentOS7でのKubernetes クラスタ構築（master編）](https://qiita.com/m-eno/items/6caae931ea727f55f5c0)
CloundFunctions ローカルエミュレータ起動

必ず忘れるのでメモ

インストール

```
npm install -g @google-cloud/functions-emulator
```

起動

```
functions start
```

停止

```
functions stop
```

kill

```
functions kill
```

デプロイ（functionがあるディレクトリに移動した後）

```
functions deploy {function名} --trigger-http --local-path=~
```
CloudFormationでAWS::CloudWatch::Alarmのテンプレートの書き方で困ったこと

cloudwatch alarmのテンプレートを記述したのですが、AWSの説明であんまり理解できなかったので半分覚え書きで書いています。

cloudwatch alarmのリファレンス: `https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html`

# 困ったこと
- アラームの条件設定の対応がわからない
- カスタムメトリクスの書き方がわからない
- 各リソースのメトリクスの書き方がわからない

# アラームの条件設定の対応がわからない
## EvaluationPeriods
- 指定した [Threshold] の値とデータを比較する時間。
- Required: Yes
- Type: Integer

## Period
- 指定した統計を適用する期間。60 の倍数で、時間を秒単位で指定します。
- Required: Yes
- Type: Integer

## Threshold
- 指定した [Statistic] の値と比較する値。
- Required: Yes
- Type: Double

## ComparisonOperator
- 指定した Statistic および Threshold を比較するときに使用する算術演算。AWS CloudFormation は、1 番目のオペランドとして Statistic の値を使用します。
- 次の値を指定できます。GreaterThanOrEqualToThreshold(以上)、GreaterThanThreshold(超える)、LessThanThreshold(未満)、LessThanOrEqualToThreshold(以下)。
- Required: Yes
- Type: String
 
`[Period]分間に[Threshold]回[ComparisonOperator]の状態が[EvaluationPeriods]回続いたらアラートを出す`

# カスタムメトリクスの書き方がわからない
↓URLにかかれているとおり、filterを作って
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html
Dimensionsにarnを書く

# 各リソースのメトリクスの書き方がわからない
例としてElasticBeanstalkを出しますがS3、SQSなど必要に応じて書き換えてください

-  DimensionsにはEBのarn
- MetricNameはURLのを`https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/aeb-metricscollected.html`
- Namespaceは"AWS/リソース名"

下記のように書けばアラームがメトリクスが使えます。

```
      Dimensions:
        -
          Name: !Ref ElasticBeanstalkのarn
          Value: !Ref ElasticBeanstalkのarn
      MetricName: "ApplicationRequests5xx"
      Namespace: "AWS/ElasticBeanstalk"
```
Androidで広告IDを取得する


初めて広告IDを取得するコードを実装したのでメモ

## ドキュメント

公式

Advertising ID | Android Developers
http://www.androiddocs.com/google/play-services/id.html

## 実装

### app/build.gradleにplay-servicesを追加

以下を追加

```diff:app/build.gradle
dependencies {
+   implementation 'com.google.android.gms:play-services:12.0.1'
```

保存してsync

### 取得コード

コメントにもあるが、非同期で取得しないとIllegalStateExceptionが投げられてエラーになる。

```diff:MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

+		// 非同期で取得しないとIllegalStateExceptionが投げられる
+       Thread(Runnable {
+           Log.d("MainActivity", getAdvertiseId(this))
+       }).start()
    }
}

+fun getAdvertiseId(
+       context: Context) = +AdvertisingIdClient.getAdvertisingIdInfo(context).id.toString()
```

ログに `21bf674e-089f-4c82-8f4c-3945f78d4a83` と出た

## 備考
コルーチンで取る事もできるみたい

Module kotlinx-coroutines-play-services
https://github.com/Kotlin/kotlinx.coroutines/blob/7e392a92170c01a5a83f745a87bfdc9a112acfc0/integration/kotlinx-coroutines-play-services/README.md
AmazonLinux2の初期設定をコンソール画面から

AmazonLinux2のローンチ時に実行したいコマンドを
作成時のコンソール画面上から登録、実行するやりかた。

##やること
1. yumアップデート
2. タイムゾーン設定（JST）
3. 言語設定(日本語)
4. swap作成
5. 再起動

##スクリプト

```bash
#!/bin/bash

#パッケージ更新
yum -y update

#タイムゾーン設定
timedatectl set-timezone Asia/Tokyo

#言語設定
localectl set-locale LANG=ja_JP.utf8
localectl set-keymap jp106

#swap作成
dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
mkswap /mnt/swapfile
swapon /mnt/swapfile
chmod 0600 /mnt/swapfile
echo "/mnt/swapfile swap swap defaults 0 0" >> /etc/fstab

#再起動
reboot
```

##登録(赤枠に上記スクリプトをぶち込みます) → 後は順を追ってローンチまで
![userData.PNG](https://qiita-image-store.s3.amazonaws.com/0/54317/6b63630f-9193-8e49-f880-50c5e7073688.png)

## 備考

```bash
#設定できるタイムゾーンリスト
timedatectl list-timezones

#設定できる言語リスト
localectl list-locales
```
【OpenCV】BGR->HSVの変換をする際に元画像の色を見てマスクの値を指定したい。変換前後の色の見え方【Python3】

# はじめに
この記事は、「OpenCVにて、imread()で読み込んだ画像の色空間をBGRからHSVに変換した後、imshow()で表示する」といった処理をする前提で書いています。
「元画像とHSV変換後の画像を人間の目で見比べた際に、どのような色の違いが見て取れるか」ということに関して書いています。

# 動作環境
Python 3.7.0
VS Code: August 2018 (version 1.27)
opencv-python: 3.4.3.18

# OpenCVの知識（この記事を読む上で知っておいてほしいこと）
* 前提としてOpenCVのimread()で読み込んだ画像の色空間はBGRであるということ。(一応)
* OpenCVのHSV空間の値の範囲は下記のようであるということ。(下記URLより引用)

>H
>>0～180の範囲。Hueは本来0～360だがOpenCVではH/2の値を示す。181～255の範囲は0からの循環に回される。

>S
>>0～255の範囲。255がS=1.0に相当。

>V
>>0～255の範囲。255がV=1.0に相当。

[引用元]http://d.hatena.ne.jp/Kazzz/20130118/p1

*  Hの値と色相の対応関係はこちらのサイトの画像が分かりやすいです。

[参考]http://www.cellstat.net/color/3/


# 変換前後での色の比較
下記参考サイトのページ中央下部「(2) HSVによる色抽出」より引用すると、
>「BがH値、GがS値、RがV値になっています。よって、暗いところほど赤くなったりしているのがわかると思います。」

とあり、同時に同サイトの参考画像の土の部分は、元画像が茶色(黒)に対してHSV変換後の画像では緑になっている。

[参考]http://tecsingularity.com/opencv/colorextraction/

# 事象
ここで、例えば「橋の影は暗いのに緑になる！赤くない！(下図参考)」なんてことがあったので、これについて考えました。

↓橋の画像(RGB)
<img width="400" alt="橋の画像(RGB)" src="https://qiita-image-store.s3.amazonaws.com/0/205347/c1698b6f-0638-e9c5-db90-3d69ec7d53a5.png">

↓橋の画像(HSV変換後)
<img width="400" alt="橋の画像(HSV変換後)" src="https://qiita-image-store.s3.amazonaws.com/0/205347/a698e38d-8dff-446f-f634-c29b6ec55c87.png">

# ポイントは「黒い」か「暗い」か
~~「暗いと赤い」「黒いと緑」という仮説を立てました。
また、HSVのHの値と色の対応表(上記参考URL参照)より、赤の反対は水色と、緑に近いことがわかります。
更に、当然ですが、暗いの反対は明るい、黒の反対は白です。
つまり橋の影は、明るさに限らず影の下にある物の色が黒(HSVでいうとSが0に近い)で、影の明るさがまあまあ(HSVのVが180に近い)の場合は、「限りなく黒く、ほどほどに暗い」ため、「変換前後での色の比較」で挙げた「暗いところほど赤くなったりしている」ことを前提に考えると「限りなく緑で、ほどほどに赤い」ことになる。つまり緑。~~

### と、そう思った。

# 間違ってました。
そもそも、RGB空間では「明るいか暗いか」なんて知ったこっちゃないんですよね。
RGB空間では彩度(HSVのS)明度(HSVのV)など管理しておらず、「明るく見えるものは白に近い。暗く見えるものは黒に近い」ただそれだけ。その証拠に下の画像は、木の影の下にある道路は白に近いにも関わらず、HSV空間へ変換後の画像の同部分は緑になっています。

↓参考画像(RGB)
<img width="400" alt="shade_on_white_rgb.png" src="https://qiita-image-store.s3.amazonaws.com/0/205347/8f5d93be-071c-dd7a-6826-ead73371cec3.png">


↓参考画像(HSV変換後)
<img width="400" alt="shade_on_white_hsv.png" src="https://qiita-image-store.s3.amazonaws.com/0/205347/9aae0281-e909-ddd6-1edb-decee00c3346.png">


# 結論
### 明るさに限らず、RGB画像で明るく白く見えるところはHSVでは赤い。暗く黒く見えるところは緑。（あたり前田のクラッカー）
まあつまりは、RGBからHSVに変換した後、RGB画像の暗い部分と黒い部分の区別をするマスクを作成する際、色指定だけでは難しいねやっぱりということ。(あたり前田のクラッカー)

以上。
【Swift】コミュニティで教わった学ぶべきこと

現在僕は、udemyや自主制作でSwiftを学んでいますが、どれが最善の学習ルートが全くわかりません。

何せまだ1ヶ月の初心者ですから。

そこで、コミュニティ内で、

>swiftを学習している者です。現在は自分で簡単なアプリを作って実践経験を積んでいます。それ以外には、udemyで講座を受講しています。既にudemyでは２つのiOS講座を受講しており、Progateは初期に済ましています。僕の中では、このままアプリを数個作ったら、再びudemyで新たな技術を学ぼうと考えています。
しかし、iOSアプリを開発する現場に着くには、サーバー連携やAPI活用などの難しい技術の習得が不可欠に思えます。カメラを起動したり、ToDoリストを作れるだけでは、エンジニアとして働くのはまだ無理じゃないかと不安に思ってます。
そこで、iOSまたはSwiftを扱う人にお願いなのですが、初心者がiOSアプリエンジニアとして独立するために、これだけは身につけるべき技術は何なのか教えていただけないでしょうか？
もちろん技術は使える範囲が広いに越したことはありませんが、せめて仮のゴールを見定めないと、無限に続く道を歩くような感覚に陥りそうなので..。

という質問を投げかけたところ、運営メンバーから良いアドバイスをもらったので、備忘録として残しておきます。

## Swift学習者がmustするべきこと

・サーバー関連のAPI実装、通信
・エラーハンドリング
・複雑な画面遷移
・カスタムテーブル・コレクションビュー

## Swift学習者にwantしてほしいこと

・ローカルDB（Realmなど）の使用・URLから画像を取得する処理
・apiaryなどのモックAPIをしよう

## 理想的なこと

・TikTok、Spotifyなど、人気のアプリを真似ること
・MVVMなどのストラクチャを理解できれば、中級に到達？

## 最後に

・未知の技術や方法を最初はコピーしても、繰り返せば理解できるようになる
・少なくとも部分的な機能や特徴を真似ればOK
Laravel 開発環境構築 備忘録1  VM立ち上げとLaravelのインストール

Laravelでの開発環境をHomesteadで構築する備忘録。
VirtualBoxはインストール済みの前提。

## Laravel開発環境を整える

複数のプロジェクト管理と共有を考慮し、各ディレクトリごとにHomesteadをインストール。

### Homesteadのインストール

プロジェクトディレクトリを作成

```
$ cd my/projects/
$ mkdir project/
```

composer install

```
$ composer require laravel/homestead --dev
```


### homesteadの設定

Vagrantfile, Homesteadをmakeする

```
$ php vendor/bin/homestead make
```

Homestead.yamlを編集。


```
$ vim Homestead.yaml
```

foldersのmapは初期設定で作成したディレクトリとなっている。
あとでmyapiというディレクトリ名でlaravelをインストールすると想定し、sitesを変更。
また，node_modulesは同期しない。

```yaml:Homestead.yaml
folders:
    -
        map: /my/projects
        to: /home/vagrant/code
sites:
    -
        map: myapi.test
        to: /home/vagrant/code/myapi/public      
        type: "apache"
        options:
          rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
          rsync__exclude: ["node_modules"]
```        

### Host設定

```
$ sudo vim /private/etc/hosts
```

```:hosts
$ 192.168.10.10 myapi.test
```

### サーバ起動

準備が整ったので仮想サーバ起動。

```
$ vagrant up
```

sshで接続。

```
$ vagrant ssh
```

/home/vagrant/codeへ移動

```
$ cd /home/vagrant/code
```

ここでcomposerをダウンロードから、laravelインストール。

```
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
```

Install laravel.

```
$ php composer.phar create-project --prefer-dist laravel/laravel mytasklist
$ php artisan --version
Laravel Framework 5.7.6
```
これで最新版がインストールされた。

/home/vagrant/code/myapi/public が出来ているはずなので、ブラウザからアクセスしてみる。

```
myapi.test
```
-> OK!


**参考**
https://readouble.com/laravel/5.7/ja/installation.html
https://readouble.com/laravel/5.7/ja/homestead.html
機械学習論文読みメモ_140

[Unsupervised Real-to-Virtual Domain Unification for End-to-End Highway Driving](https://arxiv.org/abs/1801.03458)
visionベースのend to endな自動運転モデルは、理解が難しく、また性能も高くない。
一方、中間表現をもたせた場合は、例えばsemantic segmentationやobject detectionの
学習データが必要になり高コスト化してしまう。
また生の画像データはタスクに不必要な詳細情報がノイズとして乗ってくる。
加えてdomain adaptationの問題も存在している。
本論ではこれら問題に対応するための手法としてdomain unificationを提案する。
この手法は現実のデータをvirtual simulationのdomain上におけるcanonical representationへ
変換する。
この変換はunsupervisedに学習される。
これによりvirtual domainでシミュレーションにより得られるラベル情報活用しやすくできる。

[MINE: MUTUAL INFORMATION NEURAL ESTIMATION](https://arxiv.org/abs/1801.04062)
本論では高次元変数間の相互情報量はneural networkとstochastic gradient descentを
用いる事で計算可能である事を示す。
提案手法はMutual Information Neural Estimator (MINE)と呼ばれ、
サンプルサイズと次元数に対して線形スケールである。
MINEは一貫してbackpropagationが適用可能である。
MINEは相互情報量の下界をneural networkでモデル化し
その下界に関して最適化を行う。

[Concrete Dropout](https://arxiv.org/abs/1705.07832)
DropoutはCVやRLのタスクにおいて不確かさのある推定を行う場合に実用的なツールである。
しかし最適な性能を得るためにはそのdropout rateの調整が大切である。
しかしそうしたパラメータ探索は特にRLの文脈では大きなコストとなる。
本論ではdropoutの亜種としてConcrete dropoutを提案する。
Concrete dropoutはbayesian deep learningの研究成果を利用し
従来離散的なマスキングが行われるdropoutの連続化緩和を行う。
この緩和を行う事で、学習によってdropout rateを最適化する事が可能になる。
機械学習論文読みメモ_139

[Stabilizing Adversarial Nets With Prediction Methods](https://arxiv.org/abs/1705.07364)
Adversarial networkは多くの重要な問題を解くことができるが、学習が難しい問題がある。
この難しさは最適点が最小値ではなく、saddle pointsに関係している事にある。
Alternating stochastic gradient methodsを用いて最適化を行った場合、saddle pointsへ収束させる事
は難しい。
本論では新たな安定してsaddle pointsへ収束可能なstochastic gradient methodを提案する。
この手法では、adversarial netの交互最適化を行う際、各ステップでパラメータの更新後の
値を予測するprediction stepを取り入れる事で、片方のモデル更新に対応した大きさの更新ステップ
をもう片方のモデル更新に適用可能にする。
これによりsaddle pointから最適化パスが離れていかないように調整できる。

[Semantic Visual Localization](https://arxiv.org/abs/1712.05773)
ロバストな画像ベースのlocalizationは重要で実用的である。
特に難しいケースをうまく対応できるようになる事が重要である。
本論では、geometricとsemanticの双方を考慮した手法を提案し、
従来では対応不可能であった環境に対しても対応可能にした。
特にdescriptorを学習する生成モデルを提案する。
このモデルはsemantic completionタスクを通じて学習される。
これにより学習されたdescriptorは観測の一部がかけていてもロバストに
予測が可能である。
すなわち、同じシーンに対して視点が大きく変わった場合においても適切に
同じ構造を認識する事が可能になる。

[Learning with Imprinted Weights](https://arxiv.org/abs/1712.07136)
Few-shot learningの設定において、与えられた学習画像に基づき
直接CNNの最終レイヤーを設定する手法を提案する。
この手法は与えられた画像に対するactivationをスケールさせたものを
そのまま埋め込むため、weight imprintingと呼ぶ。
Weight imprintingを行うとはじめから良い分類性能を与え、
finetuneのための良い初期化として用いる事ができる。
機械学習論文読みメモ_138

[Meta-Learning and Universality: Deep Representations and Gradient Descent can Approvimate any Learning Algorithm](https://arxiv.org/abs/1710.11622)
Learning to learn、あるいはmeta-learningはデータから効率的に学習を行うために重要である。
従来手法で一般的なのは、recurrent modelとして学習データを入力、学習済みモデルのパラメータまたは新しいデータに対する予測結果を出力するものがある。
また他にも、効率的なfinutuningを実現するためのdeep representationを獲得させる手法も存在する。
本論ではこうしたmeta learningをuniversalityの観点から捉える。
ここでは、learning algorithm approximationという指標を導入し、
それに基づき、従来手法の表現能力を比較した。
この比較を通して、deep representationとSGDの組み合わせで十分に任意の
アルゴリズムを近似できる事を確認した。

[CycleGAN, a Master of Steganography](https://arxiv.org/abs/1712.02950)
CycleGANは２つの画像分布間の関係を学習可能な最新の成功モデルである。
本論ではCycleGANの持つ新たな特性について述べる。
それはCycleGANはsource imageに関する情報を生成された画像の中に隠す事である。
この情報を利用する事でCycleGANは再構成誤差を最小化する事ができる。
この事実を通して見ると、CycleGANは敵対的サンプルを生成できるモデルと考えられる。

[Learning Wasserstein Embeddings](https://arxiv.org/abs/1710.07457)
Wasserstein distanceは分布間の距離を求める指標として注目を集めてきた。
しかしながら未だ高い計算コストが課題である。
本論では近似手法を用い、その複雑さを和らげる事ができる。
提案手法はEuclidean distanceがWasserstein distanceを近似するような埋め込みを学習する。
ネットワークはsiamese architectureを採用し、特徴空間上の２サンプル間の距離が
Wasserstein距離に一致するように最適化を行う。
macOS Mojave にアップデートしたら capybara-webkit のビルドに失敗する

# cstddef

**※ [capybara-webkit v1.15.1](https://github.com/thoughtbot/capybara-webkit/commit/77fdac424cd6fdb5aa266b229a888cc58da8e95e) で下記の問題は修正されました。**

`cstddef` ヘッダファイルがないとか言われる。

Pull Request がある。

- [Target macOS minimum version 10.9 by emilyst · Pull Request #1073 · thoughtbot/capybara-webkit](https://github.com/thoughtbot/capybara-webkit/pull/1073)

Xcode 10 から古い OS 用の設定が使えなくなったのが原因らしい。
まだ、merge されていないので、この fork を使う。

```ruby
gem "capybara-webkit", git: "https://github.com/emilyst/capybara-webkit.git", ref: "9c9af833656f095667e8522004dae017d423d37d"
```

# qt

**※ 2019-09-13 現在、下記の方法は使えなくなっています。[capybara-webkit の wiki]
(https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit#macOS-mojave-1014) に案内があるのでこれに従いましょう。**

capybara-webkit には qt 5.5 が必要だが、現在 (2018-09-27) `brew install qt@5.5` は失敗する。

これも issue がある。

- [qt@5.5 fails to configure on MacOS Mojave 10.14 · Issue #32467 · Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core/issues/32467)

ひとまず `brew install qt@5.5 --force-bottle` とすれば、コンパイル済みのものがインストールされる。capybara-webkit のビルドもこれでできる。
`next/head` で定義した<head>タグの中身をテストする

Next.jsのpagesコンポーネント以下で、`next/head` で定義した<head>タグの中身をテストしたかった。

`Head`はReact.Componentなのでenzymeでmountしてjestでテストをした。
[next\.js/head\.js · zeit/next\.js](https://github.com/zeit/next.js/blob/4c6ec18d89150f0a8dcaf56bbc7a17d669be8342/lib/head.js)

対象のコンポーネント

```jsx
import React from "react"
import Head from 'next/head'

const App = () => (
    <Head>
        <title>阿部寛のホームページ</title>
    </Head>
)

export default class Page extends React.Component {
  render() {
      <App />
  }
}
```

テストコード

```jsx
import {mount} from 'enzyme';
import Page from './index'

describe('page /', () => {
  it('title in html header', ()=> {
    const component = mount(<Page />)
    const head = component.find('Head')

    const title = head.props()
        .children
        .find(el => el.type === 'title')
        .props
        .children

    expect(title).toEqual('阿部寛のホームページ')
  })
})
```

`mount()` して `find()` するとReactコンポーネントが手に入るので、素直にpropsを辿る。

コンポーネントを辿らなくていい場合は [Shallow Rendering](https://airbnb.io/enzyme/docs/api/shallow.html) で対象を浅く参照すればよくて、
今回の場合奥からtitleを引っ張り出さないといけないので `mount()` が良いらしい。

[Static Rendering](https://airbnb.io/enzyme/docs/api/render.html) でもよさそうなんだけど `<Head>` 中身を取得できなかったため `mount()` にした。理屈はわからない。

実行

```bash
$ jest
 PASS  src/app/pages/index.test.js
  page /
    ✓ title in html header (62ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.894s
Ran all test suites matching /index.test.js/i.
```
js の replace で capture 出力機能を disable したい

# やりたかったこと

```javascript
// ho--$&--ge を出力したい
'hogehoge'.replace(/geho/, '--$&--');

// result
// ho--geho--ge
```

`$&` は `$1` 等と同様に登録済みパターンであり、マッチした部分全体を出力する機能があります
そのため、このスクリプトを実行すると `ho--$&--ge` ではなく、`ho--geho--ge` と出力されてしまします

これを回避する方法を探したので、備忘録として記しておきます

# 方法1: $$を使う

```javascript
// ho--$&--ge を出力したい
'hogehoge'.replace(/geho/, '--$$&--');

// result
// ho--$&--ge
```

置換結果文字列を直接変更できる状況であれば単純に `$$` を使うことでエスケープすることができます

# 方法2: コールバックを使う

```javascript
// ho--$&--ge を出力したい
'hogehoge'.replace(/geho/, () => '--$&--');

// result
// ho--$&--ge
```

今回は置換結果文字列生成部分を外部モジュールで行なっていたため、こちらの方法で回避しました
コールバックの引数を無視した関数を引数として与えることで、全ての特殊文字を考慮しないで単純な文字列として置換することができます

# おまけ

[出力表記の特殊パターン一覧（コピペ）](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter)

| 記号 | 効果 |
|---|---
|  $$  | $を挿入します。 
|  $&  | マッチした部分文字列を挿入します。 
|  $`  | マッチした部分文字列の直前の文字列の部分を挿入します。 
|  $'  | マッチした部分文字列の直後の文字列の部分を挿入します。
|  $n  | n は 100以下の正の整数が入ります。第一引数が RegExp オブジェクトだった場合、n 番目の括弧でキャプチャされたサブマッチの文字列を挿入します。これは 1-でインデックスされるのにご注意ください。 |
Windows（Macも）で全角入力モードで半角スペースを入力したい場合は、shift + space

タイトルについて、これは今まで気付かずに、
毎回 氏名を書くとき、苗字と名前を区切る「半角スペース」は、
わざわざ半角入力モードに変更し入力していました泣

全角入力モードで、半角スペースを入力したい場合は、

　*Shift + Space*

で OK！:v:
cert-managerのingress-shimのyamlを書き間違えて証明書が発行されなかった

[cert-manager](https://cert-manager.readthedocs.io/en/latest/) + nginx-ingressで証明書が発行されないヘマをやらかしたので備忘。

その日は疲れててこんなyamlを書いてしまいました。


```yaml
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
  name: letsencrypt-staging
  namespace: mynamespace
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: email@example.com
    privateKeySecretRef:
      name: my-key-name 
    http01: {}
---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/issuer: letsencrypt-staging
    certmanager.k8s.io/acme-challenge-type: http01
  name: front-door
  namespace: mynamespace
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - backend:
          serviceName: my-backend-service
          servicePort: 8080
        path: /
  tls:
  - secretName: my-key-name  # <<< ※これがダメ
    hosts:
    - www.example.com

---
```

一見[ingress-shim](https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html)のドキュメントにあるようなシンプルなものですよね。

でもいつまで待っても証明書が発行できません。

## 原因

よく見たらingressの`spec.tls.secretName`が`Issuer`で指定したものと同じになってました。
そりゃ発行されないですよね。

ちなみにそのときのログにはこんなのが出てました。

#### Ingress Controllerのログ

```bash
$ kubectl logs -f -n <ingress-nginxのnamespace> <ingress controller Pod名>

W0927 00:00:00.805191      10 backend_ssl.go:48] Error obtaining X.509 certificate: Secret "mynamespace/my-key-name" contains no keypair or CA certificate
W0927 00:00:00.805358      10 controller.go:1058] Error getting SSL certificate "mynamespace/my-key-name": local SSL certificate mynamespace/my-key-name was not found. Using default certificate
```

#### CertManager Controllerのログ

```bash
$ kubectl logs -f -n <cert-managerのnamespace> <cert-manager controller Pod名>

I0927 00:00:00.100894       1 controller.go:171] certificates controller: syncing item 'mynamespace/my-key-name'
E0927 00:00:00.102084       1 controller.go:180] certificates controller: Re-queuing item "mynamespace/my-key-name" due to error processing: no data for "tls.crt" in secret 'mynamespace/my-key-name'

# 同じようなログが延々続く
```

## 解決方法

単純にingressの`spec.tls.secretName`を`Issuer`で指定したものとは違うものにすればOKです。

```yaml
apiVersion: extensions/v1beta1
kind: Ingress

# [...]

spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - backend:
          serviceName: my-backend-service
          servicePort: 8080
        path: /
  tls:
  - secretName: www.example.com.tls # <<<ここを修正
    hosts:
    - www.example.com

```

通常はあまり引っかからない問題と思いますが、ドキュメントからyamlをコピペして必要な箇所を直すってやるときについうっかり修正してしまうとこうなります。気をつけましょう(自戒)。

以上です。
jquery-validationで空白のみ入力も未入力とみなすカスタムメソッド作成

### jquery-validationのrequiredでは空白のみ入力が許容される

ある必須入力テキストエリアの入力チェックとして

```js:aaa.js
// コメント必須チェック設定
$('#xxxxForm').validate({
    errorClass: 'input-validation-error',
    rules: {
        xxxComment: {
            required: true
        }
    },
    messages: {
        xxxComment: {
            required: "コメントは必ず入力してください。"
        }
    }
});
```
のように*required*指定しただけでは、空白のみの入力はチェックにかからない。

### 空白のみ入力も未入力とみなすカスタムメソッド作成

空白のみの入力も未入力とみなすようにトリム後の文字数をチェックするjQuery.validatorのカスタムメソッドを定義、
*required*と合わせて指定するようにして対応。

```js:xxxxcommon.js

// jQuery.validatorのrequiredは空白のみを弾かないので対策用カスタムメソッドを定義
jQuery.validator.addMethod(
    "SpaceOnlyNg",
    function (val, elem) {
        return this.optional(elem) || val.trim().length > 0;
    },
    "必須入力です。" // デフォルトメッセージ
);

```

```js:aaa.js
// コメント必須チェック設定
$('#xxxxForm').validate({
    errorClass: 'input-validation-error',
    rules: {
        xxxComment: {
            required: true,
            SpaceOnlyNg: true
        }
    },
    messages: {
        xxxComment: {
            required: "コメントは必ず入力してください。",
            SpaceOnlyNg: "コメントは必ず入力してください。"
        }
    }
});
```
- addMethodは複数個所で使用できるように共通で読み込むjsに記述
- メッセージは呼び出しもとのmessagesで上書き指定可能
Chrome で SSH 接続してみた

# ０．はじめに

まあ、普通にターミナル開いて SSH してたんですが、ブラウザから SSH したいなぁ、と思い調べてみました。

で、
Chrome の拡張機能 (apps) に Secure Shell というのがありましたので、試してみました。

基本的には、こちらのページの手順まんまです…。

* [Chromium OS \(Chrome\)のSecure ShellでSSH Agentを使う](https://blog.c6h12o6.org/post/chromium-ssh-and-agent/)

感謝 ♪♪♪

# １．SSH Agent for Google Chrome
1. 以下のページから、 Chrome の拡張機能を追加します。
    * [SSH Agent for Google Chrome™ \- Chrome Web Store](https://chrome.google.com/webstore/detail/ssh-agent-for-google-chro/eechpbnaifiimgajnomdipfaamobdfha?gl=IN&hl=en-GB)
        * [chrome\-ssh\-agent/go/chrome at master · google/chrome\-ssh\-agent · GitHub](https://github.com/google/chrome-ssh-agent/tree/master/go/chrome)
1. 以下のページの手順に従って、鍵を追加します。
    * [Chromium OS \(Chrome\)のSecure ShellでSSH Agentを使う](https://blog.c6h12o6.org/post/chromium-ssh-and-agent/)
    * <img width="1280" alt="スクリーンショット 2018-09-27 10.53.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/161939/54ccc1de-caf0-4094-4753-a20712f41c8f.png">

# ２．Secure Shell App
1. 以下のページから、 Chrome Apps を追加します。
    * [Secure Shell App \- Chrome ウェブストア](https://chrome.google.com/webstore/detail/secure-shell-app/pnhechapfaindjhompbnflcldabbghjo?hl=ja)
    * <img width="1280" alt="スクリーンショット 2018-09-27 10.51.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/161939/88ce4aee-5df0-63c5-3d9d-70e5b0e37c2d.png">
1. 以下のページの手順に従って、接続を追加します。
    * [Chromium OS \(Chrome\)のSecure ShellでSSH Agentを使う](https://blog.c6h12o6.org/post/chromium-ssh-and-agent/)

# ３．Crosh Window
1. 以下のページから、 Chrome Apps を追加します。
    * [Crosh Window \- Chrome ウェブストア](https://chrome.google.com/webstore/detail/crosh-window/nhbmpbdladcchdhkemlojfjdknjadhmh/related)
        * [Google Chrome で SSH に接続する拡張機能/アプリ Secure Shell と Crosh Window \| Lonely Mobiler](https://loumo.jp/wp/archive/20160704120054/)
    * 
<font color="red"><b>※これは、Secure Shell App を便利に使うアプリみたいですが、私が追加した際は、「crosh はこのバージョンの Chrome ではサポートされていません」と出てきました…。</b></font>
    * <img width="735" alt="スクリーンショット 2018-09-27 13.47.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/161939/8aa26f6d-be0d-9ca3-c95d-6c54dc2ee428.png">

# ９９．ハマりポイント

* 鍵によっては、以下のメッセージが表示されて接続がうまくいかないものがあり、その辺色々調べたんですが、よくわかりませんでした…。とりあえず、作り直したりして対応しました。パスフレーズが空の場合とかが影響してたのか…？？？
    * `Permission denied (publickey).`
<br><br>
* あとハマりポイントというか、以下は、どうにかしたいポイントですかね。
    * Secure Shell App
        * SSH マウント出来ない。Chromebook じゃないとダメみたい…。
        * 日本語入力中に二重に表示される…。
    * Crosh Window
        * 動かない…。
    * 他
        * Chrome Apps のアイコンを Chrome の拡張機能の様にメニューに表示したい？？？

# ＸＸ．まとめ

まだまだガッツリ使ってないので、色々と問題があるかもしれません。
とりあえず、
今後使ってみて、改善できればいいなと思います。

参考になれば ♪♪♪
若手プログラマーが意識すべき５つのこと

#最初に
ある案件で30代後半のプログラマーのおっさんが言いました。
「仕様を決めるときはどれだけ開発で楽できるか考えてます。」
「何だかよくわからないエラーが出てます。」
「JavaDoc？Java API仕様のサイトってなんですか？」
「今日、39℃も熱があったけど頑張って出社したんです。（インフルエンザ）」

30歳過ぎるともうどうしようもないですが、20代ならまだ間に合います！

新人プログラマーのひとはこちらをどうぞ。
[新人プログラマーが意識すべき５つのこと](https://qiita.com/nyao/items/f0e58f69735060f903ca)

新人リーダーのひとはこちらをどうぞ。
[新人リーダーが意識すべき５つのこと](https://qiita.com/nyao/items/d3040a8e1116a47e3d97)


#若手プログラマーが意識すべき５つのこと

###１．複雑な処理は単体テストが重要
難しい処理や複雑な処理は、それだけで単体テストできるように切り出す。(メソッド化するとか)
後々の工程でその処理に問題があると、とってもめんどくさいことになる。

###２．ネットの情報は信じるな
ネットにあるサンプルコードの99%は、そのままでは動作しなかったり、セキュリティの問題があったり、何らかの問題がある。
参考にはなるが、信じてはいけない。ましてやそのままコピーして使ってはいけない。
最終的には仕様書やマニュアル、公式サイトを見ること。


###３．仕様書やマニュアル、公式サイトを100%信じてはいけない
仕様書やマニュアル、公式サイトだって間違いはあるし、メジャーなライブラリにもバグはある。


###４．エラー発生時に原因がわかるようなエラーログを出力する
「エラーが発生します。」
「どんなエラー？」
「ログによると予期せぬエラーです。」
なんてやりとりをしてはいけない！
またログ出力をする場合は無駄なエラーログは出力しない。同じエラーログを何回も出力しない。

###５．システムを使用するユーザーのことを考えて仕様を決める
仕様として曖昧な箇所があった場合は、ユーザーのことを考慮して仕様を考える。
仕様として決まっていても、使い勝手悪かったり、機能として不十分だったりした場合は仕様変更を提案する。


#最後に
最近またまたそのおっさんを使いませんかという提案があったそうです。
怖いですね。
CentOS7上に、Docker CentOS7、PostgreSQL 10.5コンテナを立てる

[こちら](https://mseeeen.msen.jp/activate-docker-and-start-centos7/)と[こちら](https://qiita.com/MasanoriIwakura/items/f644138ab528187e1c5b)を参考に、CentOS7上にCentOS7 DockerコンテナとPostgreSQL 10.5 Dockerコンテナを立ててみました。

#CentOS7.4環境へのDockerのインストール

```
# yum install -y yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum makecache fast

# yum install docker-ce
# systemctl start docker
# systemctl enable docker
```
#CentOS7イメージの取得
```
# docker pull centos:centos7
```
CentOS7上に、CentOS7 Dockerコンテナをtestcontainer という名前で起動する

```
# docker run --privileged -d --name testcontainer centos:centos7 /sbin/init
```

コンテナにログイン(shellに接続)

```
# docker exec -it testcontainer /bin/bash
```
ログアウト

```
exit
```

# Postgres10.5 Docker
イメージの取得と確認

``` 
# docker pull postgres:10.5
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED                                            SIZE
postgres            10.5                084ec18124c8        2 weeks ago   
``` 

PostgreSQLコンテナの起動

``` 
# docker run --name postgres -e POSTGRES_PASSWORD=XXXXX -d postgres:10.5
``` 

起動確認

``` 
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
dbc7be879fe8        postgres:10.5       "docker-entrypoint.s…"   12 seconds ago      Up 11 seconds  
``` 

PostgreSQLコンテナへのログイン

``` 
# docker exec -it postgres /bin/bash
``` 

PostgreSQLへのログイン、データベース一覧の表示

```
psql -U postgres
postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)
```

※参考情報
[Dockerコマンドまとめ](https://morizyun.github.io/docker/about-docker-command.html)
EUC環境で作られたPerlスクリプトでの文字化け対応

いまだに文字化けの修正依頼があるので忘れないようにメモしときます。

# CPANから日本語文字コード変換のモジュールをインストール

```
$ cpan
cpan> install Unicode::Japanese
```

# Shift_JISからEUC-JPへ文字コードを変換

```perl
# use Jcode; 
use Unicode::Japanese;

# Jcode::convert(\$value, "euc", "sjis");
# sjis -> utf8
$value = Unicode::Japanese->new($value, 'sjis')->get;
# utf8 -> euc
$value = Unicode::Japanese->new($value)->euc;
```
遊戯王カード「Augmented Reality」

みんなさんは遊戯王カードの動画を知っていると思います。
僕は子供の頃から遊戯王カードの動画を見ていました。
僕にとってキャラクターがカードから出てくるのはすごくかっこいいと思うています。子供の頃いつもいつか僕がそのようなゲームを作ることができるかと考えています。
今日はその夢に向かって一歩ARという技術を勉強していて、その技術を使ってキャラクターがカードから出てくるの機能をできました。
下の写真をご覧ください。
![DSCF3996.JPG](https://qiita-image-store.s3.amazonaws.com/0/286745/b74f4a06-6774-ec26-ba3e-ce3cd7606d60.jpeg)
使っているの技術はUNITYとVUFORIAで、後Ｃ＃言語も使います。
勉強するのために僕は取り扱うインターネットから無料3D Modelling（Dark Magician, Dark Magician Girl & Blue Eyes Ultimate Dragon）を使います。将来に3D Modelling　も勉強したいです。頑張ろう！
![123.jpg](https://qiita-image-store.s3.amazonaws.com/0/286745/2459405f-ef9a-028d-dc68-7d4c5202a31d.jpeg)
```Video : https://youtu.be/OYDM9U2-HUU```

まだ完璧ではありませんですが,
僕はこの新しいゲーム体験を達成するために勉強します
みんなと一緒に遊びたいと願っています。
言語モデルでのperplexityとcross entropyの関係

自然言語処理で言語モデルの話をするときによく出てくる`perplexity`。
他クラス分類問題で出てくる`cross entropy`。
この２つの関係性をまとめてみました。

## TL; DR

```math
perplexity = 2^{entropy}
```

なので、実はほとんど同じもの。

#### perplexityの数式

```math
PP(s) = \prod_{i=1}^NP(w_i)^{-\frac{1}{N}}
```

#### cross entropyの数式

```math
H(s) = \frac{1}{N}\sum_{i=1}^N\log P(w_i)
```

## 言語モデルって何？

文が与えられたときにその**流暢さ**を図るモデル。
つまり、

`今日の朝、カレーを食べた` -> 流暢！
`朝今日、食べたカレー` -> 流暢じゃない！

みたいなことをするモデルで、

>`かわいい`という形容詞のあとに`女の子`のような名詞が来るのはOKだけど、
> `食べる`のような動詞が来たらおかしい

のように、言語の**汎用的な性質**を表現しています。

### 数式にすると

数式として表現すると、言語モデルは文が与えられたときにその文が自然に発生する確率を計算します。
この確率が高い場合、その文は自然に発生しやすいので流暢であると言えます。
文（単語の列）を$s=\\{w_1, \cdots, w_N\\}$としましょう。この時言語モデルは確率$P(s)$を推定します。
多くの場合、ある単語$w_i$の発生確率をその単語の前後$s_{\backslash w_i}$から推定して、その積として全体の確率を計算します。

```math
\begin{align}
P(s)&=P(w_1, \cdots, w_N)\\
&=\prod_{i=1}^NP(w_i|s_{\backslash w_i})
\end{align}
```

こうすると、文の中に変な単語が出現するとその単語の発生確率$P(w_i)$が小さくなるので全体$P(s)$も小さくなるという仕組みです。
つまり、単語$w_i$の発生確率をそれ以外の単語$s_{\backslash w_i}$から推定するタスクが解けると言語モデルが作れます。

### いつ使うの？

言語モデルは自然言語処理で最も大切なモデルの一つで多くの場面で使えますが、いくつか象徴的なものを上げてみます。

1. 生成モデルでの候補文のランキン（流暢な出力をしたい！）
2. Skip-gram、CBoWのようなword embeddingの学習（言語の性質の情報を含むword embeddingsがほしい）
3. 大きなNeural Networkの初期化（アノテートされてないデータを大量に使って効率よく初期化したい）

## `cross entropy`

cross entropyは２つの確率分布の類似度を計算するもので、離散確率の場合は

```math
H(Q, P) = \sum_x Q(x)\log P(x)
```

となります。多クラス分類問題では$p(x)$を正解ラベル$q(x)$を推定確率として、cross entropyを最大化することで学習を行います。つまり、入力を$x$、ラベルを$t$とすると

```math
\textrm{argmax} \log P(t\ |\ x)
```

を最大化することになります。

上で、言語モデルを文中の単語$w_i$を周辺の単語$s_{\backslash w_i}$から推定するタスクに落としました。
これは、語彙の中から一つの単語を選ぶタスクなので多クラス分類タスクになります。
よって、ここでもcross entropyを最大化することで学習を行います。

```math
\textrm{argmax}\sum_{i=1}^N \log P(w_i| s_{\backslash w_i})
```

## `perplexity`

cross entropyは言語モデルの学習につかいました。対してperplexityは言語モデルの**評価**に使います。
言語モデルは、実際のデータに対してどれだけモデルが**流暢である**というかによって評価します。（データ内にある文は人間が実際に喋ったものなのでそれが**流暢の定義**なはずです）
つまり、$P(s)$が大きければ評価が高いのです。
この指標を数式に落としたものがperplexityで最もよく使われる言語モデルの評価尺度です。

```math
PP(s) = \prod_{i=1}^NP(w_i)^{-\frac{1}{N}}
```

## 関係性

cross entropyとperplexityの関係を探るために、perplexityの$\log$を取ってみると

```math
\begin{align}
\log PP(s) &= \log\prod_{i=1}^NP(w_i)^{-\frac{1}{N}}\\
&=\frac{1}{N}\sum_{i=1}^N\log P(w_i)
\end{align}
```
となります。ここで、最後の式は各単語に対するcross entropyの平均になっていることがわかります。
つまり、perplexityのlogがcross entropyになるのです。

言語モデルの話で

* なぜ学習にはcross entropyを使って評価にはperplexityを使うのか
* perplexityに対して最適化したらもっと良くなるのでは？

という声を聞いたことがあります。（あんまり多くは無いけど
結論から言うと、cross entropyに対して最適化するのとperplexityにたいして最適化することは同じことなのです。
AI-Q+LINE@の初期設定からサンプル応答まで

とある縁でAI-Qに触れる機会があったため、これから使いたい人向けに。

# AI-Qとは
木村情報技術株式会社が提供している、「IBM Watson日本語版」を用いたAIお問合せシステム。

# 概要
おおまかな流れとしては
**LINE@アカウント作成→messaging APIの有効化→AI-Qとのつなぎこみ**
である。
# LINE@関係設定
①下記リンクよりアカウントの作成を行う。この際**自分が自由に使えるLINEアカウント**を持っている必要があるので、登録時に設定したメールアドレスやパスワードを忘れていたら再設定なりしてみる。このLINEアカウントは普段使いのやつで良い。
https://entry-at.line.me/

②次に管理画面にログインする。ログイン時に求められるメールアドレスとパスワードは自分のLINEアカウントのもの。
https://admin-official.line.me/

③ログインした後先程作ったアカウントが表示されるのでクリックする。その後PC画面では左側にある設定（もしくはsetting）をクリック後出現する、Messaging APIと書いてある方のタブをクリック。そこからmessaging APIを有効化する。

④続いて自動応答を解除する。解除しないとAI-Qにつなぎこんだときに会話ができなくなってしまうので必ず解除する。
PC画面では左側にあるメッセージ(もしくはMessage)から自動応答メッセージ（もしくはAuto reply message）をクリック

⑤続いて下記リンクよりmessaging APIの管理画面へ飛ぶ
https://developers.line.me/

そこからプロバイダーリストを探し、最初に作ったLINE＠アカウントを探しクリック。下へスクロール
Channel secret
Channel access token（最初は空になっているので右のボタンで発行する）
が確認できるのでこの2つはどこかに控えておく。



以上でLINE＠まわりの設定は終わり。

# AI-Q設定

下記リンクより利用申込をする。その際LINE＠と連携したい旨伝える。
https://www.k-idea.jp/product/ai/ai-q.html
もしなんらかの事情でアカウントがあるならLINE＠と連携したい旨伝えるだけでよい。

この時先ほど控えたLINEの情報を聞かれると思うので答える。つなぎこみが完了したらwebhookURLが先方から送られるので、以下リンクでchannel secretとかを控えたページへ行く。
https://developers.line.me/

ここのwebhookを利用するを有効にし、webhookURLを編集にもらったURLをコピペする。
この時点で初期設定は完了する。

この段階ではサンプルの対話データがあるのでそれっぽい応答はできるようになっている。が自分で追加したい応答パターンがあるのならば、QA登録編集から登録してみる。

Excelファイルからも入力ができるので自前でデータセットがあるならフォーマットに合わせて加工してみるのもよいかと。
[Int:String]はUserDefaultsに入れると実行時エラー

掲題のとおりなのですが、[Int:String]とか[Date:String]とかは、UserDefaultsに保存できない。　逆は問題ないのに。
つまり、辞書のKey側の型に制限があって、Date、数値型、Bool、Arrayはダメみたいなんです。

回避策としては、

```swift
let dic = ["a",1]
UserDefaults.standard.set(Array(dic.keys),   forKey: "dicKeys")
UserDefaults.standard.set(Array(dic.values), forKey: "dicVals")
```
とかするくらいしか思いつかないです。　
もし、保存できない理由とか、よりより方法があれば是非教えてください。
PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その3(「座標軸」の実装編) 

#はじめに
以前に投稿した内容 ↓ をさらに拡張していきます．
[PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その2(「ファイルを開く」の実装編) ]("https://qiita.com/matsubaradaisuke/items/956b9ade4a74fcbb7521")
今回はビュー上に座標軸を配置していきます．

完成イメージは下図になります．
![プレゼンテーション1.png](https://qiita-image-store.s3.amazonaws.com/0/132299/9b6fbe6e-41fa-c8eb-bb72-91b5a6eacf7c.png)
#環境
OS: windows10
OpenFOAM v4.0
python 3.6.4
pyqt5-5.9.2
vtk-8.0.0
numpy

#ファイル構成
case/
　├ ViewAxis.py　(本プログラム)
　├ open_file.png
　├ quit.png




座標軸を作成するときは，vtkライブラリの次のクラスについて勉強する必要があります．

vtkAxesActor
vtkOrientationMarkerWidget

vtkAxesActorは，単純に座標軸に関するactorであり，
vtkOrientationMarkerWidgetを介してQVTKRenderWindowInteractor
に配置するようです．
おそらく，AxesActorから直接vtkRendererに配置することも可能だと
思われます．


#座標軸の実装

それでは，座標軸を設定していきます．
[前回]("https://qiita.com/matsubaradaisuke/items/956b9ade4a74fcbb7521")のクラス「MyForm」に以下の関数を追加していきます．

```py3:ViewAxis.py
	def setupAxes(self):

		axesActor = vtk.vtkAxesActor()	#軸用のactorを用意

		self.axesWidget = vtk.vtkOrientationMarkerWidget()
		self.axesWidget.SetOrientationMarker(axesActor)
		self.axesWidget.SetInteractor(self.widget)

		self.axesWidget.EnabledOn() 	#有効化
		self.axesWidget.InteractiveOn() #接続開始
		self.widget.Render()	
	
```

そして最後に，初期化時にこの関数を追加して終了です．

```py3:ViewAxis.py

	def __init__(self, parent=None):
		QWidget.__init__(self, parent)
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)

		self.reader = vtk.vtkOpenFOAMReader()
		self.filter2 = vtk.vtkGeometryFilter()
		self.mapper = vtk.vtkCompositePolyDataMapper2()
		self.actor = vtk.vtkActor()

		self.widget = QVTKRenderWindowInteractor(self)
		self.widget.Initialize()
		##背景色の設定
		self.ren = vtk.vtkRenderer()
		self.widget.GetRenderWindow().AddRenderer(self.ren)
		self.widget.Start()
		self.widget.show()

		self.setCentralWidget(self.widget)
		#UIのインスタンスを介してアイコンと実体(関数)をつなげる
		self.ui.actionOpenFile.triggered.connect(self.openFile)
		self.ui.actionResetFile.triggered.connect(self.resetFile)
		self.setupInitView()
		self.setupAxes()　#<--------これ！

```

#使い方
座標軸周りをドラッグすることで，移動も可能です．
![プレゼンテーション２.png](https://qiita-image-store.s3.amazonaws.com/0/132299/37a639af-5d50-1319-023b-8c270d589de1.png)


#まとめ
view画面に座標軸を追加しました．
次回こそ，メッシュ表示切替やview方向の切り替えあたりをまとめようと思います
ずんだの縦読み問題 Ruby編

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">忙しくてついったいじれない<br>さみしい<br>つらい</p>&mdash; ずんだまる(仮) (@edamametsubu318) <a href="https://twitter.com/edamametsubu318/status/1045153621334142976?ref_src=twsrc%5Etfw">2018年9月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

縦読みだ。

## Ruby
```ruby
tweet = <<-EOS
忙しくてついったいじれない
さみしい
つらい
EOS
puts tweet.each_line.map{|e|e[0]}.join

# => 忙さつ
```

* [ずんだ問題まとめ - Qiita](https://qiita.com/tbpgr/items/3a4169b370f1a317ece0)
RxJS6 Cold ObservableとHot Observable

## Observableとストリーム

Angular6を利用しているとObservableが頻繁に出てきます。しかし、これは比較的イメージしづらいと思われます。

Observableとはバリュー(Value)やイベント(Event)のストリームとよく解説されています。

しかし、ストリームを川の流れのようにイメージすると、その後の理解を阻害する場合があります。

というのは、川は自然に流れ続けるイメージですので、Observableを定義しただけで、その流れが発生していると誤解しがちだからです。

そこでまず、Observableには、Cold ObservableとHot Observableの違いがあることを理解する必要があります。

前者のCold Observableは、定義しただけでは流れは発生しません。

受け手側で、subscribeを実行した時のみ、その流れは発生します。

その一方、Hot Observableでは、受け手側の状況に拘わらず、その流れが発生します。

これは通常の川のイメージと同様です。

こうした違いを明確にしておく必要があります。


ビデオ解説(日本語）
https://youtu.be/WsOqyG3_nnA

ビデオ解説(英語）
https://youtu.be/ufntWfqCJ4g


--------------------

## Cold Observable

まず、Cold Observableについて見てみましょう。

Observableは、イベントやバリューのストリームです。

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/rxjs6/ColdObservable01.png" width= "640" >



しかし、Observableを定義しただけでは、まだ流れは発生していません。

それは受け手側、すなわちリスナーが、Subscribeを実行していないからです。

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/rxjs6/ColdObservable11.png" width= "640" >



受け手側がFishについてのSubscribeを実行しました。魚が現れてきました。

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/rxjs6/ColdObservable21.png" width= "640" >



ここで受け手側が、Unsubscriveを実行しました。魚の流れは消失しました。

--------------------

## Hot Observable

次は、Hot Observableについてです。


  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/rxjs6/HotObservable01.png" width= "640" >

Hot Observableの場合は、受け手側の状態、すなわち、Subscribeを実行しているか否かに拘わらず、その流れは発生しています。


この典型的な例は、キーボード・イベントやマウス・イベントです。

--------------------


  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/rxjs6/HotObservable11.png" width= "640" >

ここで受け手側が、Subscribeを実行すると、その情報をほぼ同時に共有することができるようになります。


## _Reference_

- "Observable", 
<http://reactivex.io/documentation/observable.html>

- "Reactive Programming with RxJS 5: Untangle Your Asynchronous JavaScript Code", 2018/2/15,Sergi Mansilla
<https://www.amazon.co.jp/Reactive-Programming-RxJS-Asynchronous-JavaScript/dp/1680502476/ref=sr_1_7?ie=UTF8&qid=1537063252&sr=8-7&keywords=reactive+programming>

- "Angular6 から始める RxJS6 入門", 
<https://qiita.com/MasanobuAkiba/items/a5026bd37603cc29e9e7>

- "Comprehensive Guide to Higher-Order RxJs Mapping Operators: switchMap, mergeMap, concatMap (and exhaustMap)", 
<https://blog.angular-university.io/rxjs-higher-order-mapping/>

- "Angular 5, Angular 6 Custom Library: Step-by-step guide", 
<https://www.udemy.com/angular5-custom-library-the-definitive-step-by-step-guide/>

- "Angular 5, Angular 6用 カスタムライブラリの作成: 完全ステップ・バイ・ステップ・ガイド", 
<https://www.udemy.com/angular5-l/>
windowsで文字化けしないzipを, macで作成

2021/08/29追記: 
Catalina以降の修正を私のブログ内:
https://keitasumiya.net/blog/2018/windows-ok-zip_by_mac/
にて追記しました. 
といっても, リンク元の方の記事の修正を追加しただけです. 

---

基本は
- [mac標準機能でWindows互換のZIPファイルを作成する方法【日本語対応】](http://fanblogs.jp/macyarounanoka/archive/274/0)
をみればすべて書いてあります. すばらしい. 

以下は個人的な備忘録で特に価値はない. 

# terminalで実行
## 設定

- この方の[code](https://github.com/macyarounanoka/mac-zip-windows/blob/master/windowszip)をコピー
- `cd /usr/local/bin`で移動
- `vi windowszip`し, 先のcodeをペースト
- `/usr/local/bin/windowszip`が作成される
- `chmod +x windowszip`で実行権限を与える
- 念の為, `sudo ln -s windowszip /usr/local/bin/windowszip`でシンボリックリンクを作成

terminalで実行するならこれだけでOK

## 使い方

```
windowszip 『zipしたいファイルやディレクトリ』
```
で同名のzipが作成される. 
`.DS_store`も作成されない

# finderのサービスから実行
## 設定

上記に続いて下記を行う

- `Automator`を開く
- `サービス`を選択して`選択` 
- (mojaveなら`クイックアクション`を選択して`選択`)
- `ユーティリティ`の`シェルスクリプトを実行`をつかんで, `ワークフローを作成するには、ここにアクションまたはファイルをドラッグしてください`の場所にドラッグ
- `"サービス"は次の選択項目を受け取る: `は`ファイルまたはフォルダ`を指定
- `検索対象`は`Finder.app`を指定
- `シェルスクリプトを実行`の`入力の引き渡し方法`は`引数として`を指定
- `シェルスクリプトを実行`のシェルの内容は下記にする

```shell
for f in "$@"
do
	/usr/local/bin/windowszip "$f"
done
```

- `cmd + s`で保存する. 保存名は`windowszip.workflow`にする

設定完了. 

## 使い方

- `Finder`上で『zipしたいファイルやディレクトリ』を右クリック
- `サービス`の`windowszip`を選択
- 『zipしたいファイルやディレクトリ』と同名のzipが作成される
- `.DS_store`も作成されない



# 参照
- [mac標準機能でWindows互換のZIPファイルを作成する方法【日本語対応】](http://fanblogs.jp/macyarounanoka/archive/274/0)
- [Macで自作コマンドを使う方法](https://qiita.com/HiDARi/items/a1fca8ab45bdd762ae52)
- [シンボリックリンク設定方法](https://qiita.com/0084ken/items/6f39498c86fb592b2baf)