OmniAICreator/Qiita-1.07M huggingface dataset:
Macにもともと入ってるPHP7.1にxdebugを入れる方法（2018年7月版）

## はじめに

### 愛用のhomebrew/phpリポジトリは廃止されたようです。。。

[How to setup XDebug for PHP7 on Mac?
](https://stackoverflow.com/questions/32291215/how-to-setup-xdebug-for-php7-on-mac/35094956)

上記リンクにもあるように、現時点だとxdebugはpeclで入れるのがベストプラクティスっぽいです。

### PHPはMacにもともと入ってるものを使います

```
/usr/bin/php
```

## 1. pearをインストール

xdebugはpeclコマンドで入るのですが、その前にpeclコマンドをインストールする必要があります。pearをインストールするとpeclがついでに入ってくるみたいなので今回はpearコマンドをインストールしてみます。

```
curl -O https://pear.php.net/go-pear.phar
php -d detect_unicode=0 go-pear.phar
sudo php /usr/lib/php/ install-pear-nozlib.phar
```

.bash_profileあたりに下記を記述してパスを通します

```
export PATH=$PATH:$HOME/pear/bin/
```

## 2. SIPをオフ

peclで/usr/lib配下をいじることになるのでmac os のSIPをリカバリーモードのターミナルから一時的にオフにします

```
csrutil disable
```

## 3. xdebugをインストール

```
pecl install xdebug
```

`/etc/php.ini`に設定を追記

```
zend_extension=/usr/lib/php/extensions/no-debug-non-zts-20160303/xdebug.so
```

下記コマンドでxdebugがインストールされているか確認

```
php -i | grep xdebug
```


## 4. csrutilをオンする

もう一度リカバリーモードに入ってSIPをオンにしておきます

```
csrutil enable
```

## さいごに

上記のやり方でうまくいかないときはコメントください
できる範囲内でサポートしますm(_ _)m
PHPでcurlを使えない場合の対処法

## 概要
PHPのコード内でcurlを使うときに、つまずいたのでメモ程度に。
そもそも、PHPには他の言語同様、色々パッケージが存在しているので、その関数が定義されているのかどうかを適宜確認して使うことが必要。
## 動作環境
```shell-session:~
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"

$ nginx -v
nginx version: nginx/1.14.0

$ php -v
PHP 7.1.19-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jul  9 2018 13:12:24) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.1.19-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
```
## 解決方法
いたってシンプル。
php-curlのパッケージを追加すればイイだけ。

```shell-session:~
$  sudo apt-get install php7.1-curl
```

以下のコマンドで、自分のPC/サーバーに入っているphpのモジュール一覧を取得することができる。

```shell-session:~
$  php -m
[PHP Modules]
calendar
Core
ctype
curl  #curlが存在することを確認！
date
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
json
libxml
openssl
pcntl
pcre
PDO
pdo_pgsql
pgsql
Phar
posix
readline
Reflection
session
shmop
sockets
SPL
standard
sysvmsg
sysvsem
sysvshm
tokenizer
Zend OPcache
zlib

[Zend Modules]
Zend OPcache
```

ちなみにphpinfo()内にもcurlの項目ができているのを確認できる。
<img width="952" alt="スクリーンショット 2018-07-23 11.49.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/264708/68300933-6935-8c23-7bf9-a8836512d21d.png">

## 実用例
以下のテスト用のコードを実行してみると、きちんとphp-curlがインストールされている場合、yahooの画面が表示されるはずである。

```curl.php
<?php
  $url = "https://www.yahoo.co.jp/";
  $conn = curl_init(); #cURLセッションの初期化
  curl_setopt($conn, CURLOPT_URL, $url); #取得するURLを指定
  curl_setopt($conn, CURLOPT_RETURNTRANSFER, true); #実行結果を文字列で返す。
  $res =  curl_exec($conn);
  var_dump($res);
  curl_close($conn); #セッションの終了
?>
```
curlコマンドは、APIを叩くときに有効なので、PHPでも実装できるようにしたい。
5分でロリポップ！を無料SSL化する手順

- タイトル通りです。
- [公式ページ](https://lolipop.jp/manual/user/ssl-free-order/)にも、SSL化するHow toは書かれているのですが、それだけだと**httpからhttpsへのリダイレクトができません**。
- なので、そこまでサクッと行きます。

## 1. ロリポップの管理ページでSSL化申請。
- ここまでは[公式ページ](https://lolipop.jp/manual/user/ssl-free-order/)に書かれています。
- マイページの**セキュリティ**と書かれたタブをクリックします。
- 「SSLで保護されていないドメイン」のタブを開き、SSL化したいドメインを選択して、SSL設定のボタンを押します。
- ５分くらいで有効かされるので、その間にhttpsリダイレクト設定をしましょう。

## 2. HTTPSリダイレクト設定
- ftpを使うので、なんらかのFTPクライアントソフトを使ってください。（私はMacでサイバーダック使ってます）
- 対象となるドメインのルートディレクトリへ行って、以下のような`.htaccess`をおいてください。

```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
```

- ちなみによくwordpressの`.htaccess`に描く場合はこう描くといいらしいです

```
# BEGIN WordPress

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
```

- 以上です！
1分でわかる論理削除 -メリットとデメリットを考える-

# 対象読者
以下のような疑問を持つ若手ITエンジニアの方々
・論理削除フラグを見たことはあるけど、何のためにあるのかよく分かっていない

# 論理削除とは何か
**テーブルから特定の行を"論理的に"削除すること**
そのまんま過ぎますね。
物理削除の意味が理解できれば、論理削除の意味もわかってくると思います。

|削除方式|意味|
|:--|:--|
|物理削除|ハードディスクなどの記憶媒体から当該行のデータを削除すること|
|論理削除|当該行が削除されたことをデータとして表現することで**削除されたものとみなす**こと<br>（＝データは記憶媒体に残ったまま）|

"削除されたことをデータとして表現する"ための手段として使用されるのが**論理削除フラグ**です。

## 論理削除フラグの具体例
商品テーブル

|商品ID|商品名|価格|論理削除フラグ|
|:----|:-----|--:|:------------|
|1|みかん|60|false|
|2|りんご|150|false|
|3|バナナ|140|true|

論理削除されたデータは、システムの利用者から見ると「存在しない」ことにするのが一般的です。
例えば、ユーザーがシステムの画面から商品の一覧を確認する場合、発行されるSQLは以下のようになります。

```sql
SELECT product_name, price
FROM products
WHERE is_deleted = FALSE
```

検索条件に論理削除フラグをFALSEにすることで、論理削除されたデータ（is_deleted=TRUE）は表示されなくなります。

## 論理削除フラグの名称・型
論理削除フラグの名称や型は現場によってまちまちです。
一般的には、**削除されるデータがTRUEや1などの肯定的な値をとります**。
反対に、削除されていないデータにはFALSEや0が入ります。

||例|
|:--|:--|
|命名|is_deleted, delete_flg, etc.|
|データ型|boolean, int, varchar, etc.|

#なぜ論理削除が必要なのか
様々な理由が考えられますが、以下のようなケースが多いと思います。

- ユーザーからその存在を隠蔽したいが、データとしては残しておきたい
（例えば、業務事情により当該データを使用禁止にしたいが、一時的なのですぐに元に戻せるようにしたい場合）
- 誤って削除した場合に備え、すぐにデータを復元できるようにしておきたい

#なぜ論理削除は嫌がられるか
- バグを生み出す原因になる (例：WHERE句への論理削除フラグの付け忘れ)
- データ量増大やそれに伴う検索性能の劣化　※論理削除データが多い場合

#論理削除という設計方式は悪か？
ケースバイケース
業務要件を踏まえて要検討。ただ、従来の慣習に合わせた「とりあえず論理削除フラグ」はやめましょう。

#論理削除フラグの代替案
このあたりはもう少し調査が必要だと思っていますが、1案だけあげておきます。

- 削除時、削除用テーブルにINSERTする（トリガーを使う）
- (Coming soon...)

#最後に
当記事では論理削除の概要をとりあげました。少しでも理解が深まったのであれば幸いです。
TweetDeckのNotifications欄で特定の人からのLike通知を非表示にする

TweetDeckは便利。でも若干かゆいところに手が届かない事がある。

私の別アカウントのフォロワーに、私のツイートを大量にLikeしてくる人がいる。
TweetDeckでは公式のように同じ人によるLikeをまとめてくれたりしないので、
突然Notifications欄が、その人のアイコンのLikeしましたの通知で埋め尽くされる事になる。
私のツイートに反応してくれるのはありがたい事だが、どちらかを正直に言ってしまうと、鬱陶しい。

TweetDeckのカラムごとの設定で「この人からのLikeは除外」というような機能があればよかったのだが、ない。
別にTwitterの機能でMuteしたりBlockしたりまでしたくはないので、単に非表示にできればいいのだが。

カスタムスタイルシートで解決する事にした。

ブラウザプラグインの[Stylus](https://github.com/openstyles/stylus/wiki)を使う。
Chromeを使っている人は、[ここ](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne)からインストール。

次に、ミュートするためのキーとなる文字列を探す。
TweetDeckの画面でChromeの開発者ツールを開き、インスペクタでnotificationsのカラム内の
非表示にしたい人からのLike通知の部分を探り、&lt;article&gt;というタグを探す。
![Selection_059.png](https://qiita-image-store.s3.amazonaws.com/0/148579/95e3e670-2de1-9127-525f-d640ec36ee3a.png)

その中の、data-keyという属性値が重要となる。Like通知の場合、data-keyは以下のような書式となる。
`favorite_00000000_1111111111`
これがどうやら

- favorite : Likeしました通知
- 00000000 : LikeしたアカウントのID値
- 1111111111 : LikeされたツイートのID値

という意味のようである。したがって、
**article要素のうち、data-key属性が"favorite_00000000_"で始まるもの**
を非表示とすれば、やりたい事が実現できると考えられる。

StylusでCSSを書く。
TweetDeckの画面で右上のStylusのアイコンをクリックし、

![Selection_063.png](https://qiita-image-store.s3.amazonaws.com/0/148579/6241b6d1-5cdf-c2cf-61b7-e39402397aa9.png)

"Write style for:"のところで"tweetdeck"あたりをクリックすると、
tweetdeck.twitter.com 以下で有効なカスタムスタイルシートが書ける。

![Selection_064.png](https://qiita-image-store.s3.amazonaws.com/0/148579/c13a00ea-3dc8-b7e2-8a37-f7be9fc5dc5c.png)

右側に書く内容はこう。00000000は先程調べたアカウントのID値に置き換えること。

```
article[data-key^=favorite_00000000_] {
    display:none;
}
```
書いたら左側の[Save]をクリックし、閉じる。

以上。
これでその人からのLike通知は非表示となるはず。


ちなみにfavoriteの部分は、retweetだったりfavorited_retweetだったりfollowだったりmentionだったり
色々あるようなので、必要に応じて調べて使ってみるとよいでしょう。
IntuneでPCの構成を設定する - Wi-Fi の手動設定の制限

# 概要
Intuneで管理しているWindows 10 端末で、接続できる無線LANを特定のプロファイルにのみにしたいことがあります。
今回はこの設定をIntuneを利用してやってみたいと思います。

# PCへプロファイルの設定
IntuneにはWifiのプロファイルを配布する機能とWifiをMDMなどから配布したもののみに制限する（ユーザが自分でWifiを選択して設定できないようにする）機能の２つが実装されています。
しかし後者のWifiの手動設定の項目はDocsのIntuneの説明を見ると

[Wi-Fi の手動設定] - ユーザーが独自に Wi-Fi 接続を構成できるようにするか、Wi-Fi プロファイルで構成された接続のみを使用できるようにするかを制御します (Windows 10 Mobile のみ)。
https://docs.microsoft.com/ja-jp/intune/device-restrictions-windows-10#cellular-and-connectivity

となっています。一方で、CSPではこの項目は1607から利用可能になっています.
https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-wifi#wifi-allowmanualwificonfiguration

PC、今回は確実に動作する明示的にCSPの設定を行いたいと思います。

# 環境
　Windows 10 Enterprise Edition Ver. 1803

# 手順
カスタムCSPを作成します。

1. Azure ポータルにサインインします。
2. [Microsoft Intune] を選択します。
3. [デバイス構成]、[プロファイル]、[プロファイルの作成] の順に選択します。
4. プロファイル作成ブレードでカスタム プロファイルの名前と説明を入力します。
5. [プラットフォーム] ドロップダウン リストで、カスタム設定を適用するデバイス プラットフォームでWindows 10 以降を選択します。
6. [プロファイルの種類] ドロップダウン リストで、[カスタム] を選択します。
7. OMA-URIのカスタム設定ブレードで[追加]を選択します。

![キャプチャ110.JPG](https://qiita-image-store.s3.amazonaws.com/0/262585/621c57c6-a768-7bc4-c5a7-882d7f31fcae.jpeg)
8. 行の編集ブレードで名前と説明を入力します。
9. OMA-URIに以下の内容を入力します

```text:XML
./Vendor/MSFT/Policy/Config/wifi/AllowManualWiFiConfiguration
```

10.データ型に[整数]、値に[0]を入れます。

![キャプチャ111.JPG](https://qiita-image-store.s3.amazonaws.com/0/262585/369ae8e1-719c-4dec-6709-4edb8511295c.jpeg)
11.OKおよび保存ボタンを選択しプロファイルを作成します。

その後作成したプロファイルに適用するユーザーを割り当てて配布します。
配布が完了しCSPが適用されると、ネットワークの設定のWifi一覧に表示される項目が変更され、事前に設定されたWifiプロファイルしか表示されなくなります。以下は同じ場所に置いた2台のPCのWifiの表示です。制限が入った端末はあらかじめ設定が反映されたネットワークしか表示されなくなります。

![スクリーンショット (2).png](https://qiita-image-store.s3.amazonaws.com/0/262585/f3383599-fa7f-8655-cdc5-55a13011b051.png)
Intuneで制限がかかってない端末

![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/262585/13934679-d0cd-b9b1-2920-e379f4f7a486.png)
Intuneで制限がかかっている端末

#注意事項
WINDOWS 10用のデバイス構成プロファイルの機能の制限には[Wifiの手動設定]の項目があります。この項目の設定を[ブロック]にしておくと今回の設定は競合でエラーになります。ご注意ください
![キャプチャ004.PNG](https://qiita-image-store.s3.amazonaws.com/0/262585/08470105-4832-5e1f-7940-245cf490a61a.png)
ここが設定されているとエラーになる。この設定はPCには反映されない（2018/7/27現在）。


#まとめ
Intuneを利用してユーザーがWifiを追加できないようにする設定を紹介しました。
ご意見などありましたらお寄せください。
Cognos Analytics で Apache JMeter を使った負荷テストシナリオ作成

#概要
Cognos 10 BIでは、JMeterを用いた負荷テストは、開発元が書いたこの記事のサンプルスクリプトを用いて簡単に実行する事ができました。
**IBM Cognos BI 10.2.1.x JMeter Stability Package**
https://www.ibm.com/developerworks/library/ba-pp-performance-load_testing-page692/index.html

しかしながら、このサンプルスクリプトはCognos Analyticsには全く使えません。

困ったものだと思って、散々調べていたところ、このスレッドで「できたぜ！」という人がスクリプトを公開していたので、使ってみたところCognos Analytics 11.0.11の環境で使用できました！

**Anyone succesfully configured JMeter for Cognos 11 performance testing yet?**
https://developer.ibm.com/answers/questions/369655/anyone-succesfully-configured-jmeter-for-cognos-11.html

これは朗報という事で、さっそく自分の環境でやってみた結果を投稿しましたので是非ご活用下さい。

#手順
自分の環境では「apache-jmeter-3.3」を使用しています。

apache-jmeter-3.3\apache-jmeter-3.3\bin\user.properties を開き、以下の一行をファイルの一番下に追加します。

CookieManager.save.cookies=true

先のサイトの一番下にある「cognos-11-test-planjmx.zip 」をダウンロードし解凍します。

JMeterを起動。
　apache-jmeter-3.3\apache-jmeter-3.3\bin\jmeter.bat を右クリックで管理者実行。

「開く」から解凍した「Cognos 11 Test Plan.jmx」を開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/8a4f4ba1-0489-8da1-eca9-3f2b3456e3a8.png)

**Test configuration Parametersを以下の要領で編集**
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/72bed56d-d549-fb2a-299a-14d1e645aaa7.jpeg)

*severname*
Cognosサーバーのホスト名を指定してください。IPアドレスでも可です。

*port*
Cognos Analyticsのデフォルトは9300と思いますので、9300に変更して下さい。

*repid*
Cognosポータルでレポートのプロパティから「ID」を取得して記載下さい。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/fa534cfa-f131-621f-623a-918b5f1cb8f4.jpeg)

**Loginを以下の要領で編集**
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/80f15658-51e7-f5d1-7439-01fdd3c298f2.jpeg)

*CAMNamespace*
ご使用の環境に応じて認証ソースのネームスペースをご指定下さい。
自分の環境ではカスタム認証を使用しているので「Restorable」と指定しました。

*CAMUsername*
ユーザーIDを指定。自分の環境では「cogadmin」としました。

*CAMPassword*
上記ユーザーのパスワードを指定します。

**Thread Groupを以下の要領で編集**
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/ba849835-6718-bcde-b66c-35ade8ac3827.jpeg)

まあここは、普通のJMeterの話です。
スレッド数とか、RampUp期間とか調整してください。

**リスナーを以下の要領で編集**
*Simple Data Writer*は削除してしまいました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/f2c0a57b-d5bc-48e2-8433-ebe3c4d88141.png)

代わりに「結果をツリーで表示」リスナーを追加しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/f02fdcf1-e01e-858f-c028-234ab9674714.png)

**実行してみる**
保存して「開始」してみます。
リスナー上は「Login」も「Execute Report」も全てOKです。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/3d99ae1e-4a6a-55fb-6207-be96ca367b09.jpeg)

cogaudit.logにもばっちりレポート実行履歴が出力されました。※ログレベル「標準」
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/a7340288-7d1f-f552-f38a-a498ab233c6d.jpeg)

あとはこの応用で、JMeterの知識があれば負荷テストシナリオ作成可能と思います。

先のスレッドの lsparvieri さんに感謝です！
まだ当面は負荷テストやる予定は無いという方も、リンクが切れるともったいないので、スクリプトだけでもダウンロードしておきましょう。
【第1回 環境構築編】uPortアプリ開発やってみよう！

#**記事概要**
先日、BlockChainEXE × ConsenSys共催のハッカソンに参加させていただきましたので、
そのときに使ったuPortと連携webアプリを作る方法を共有したいと思います。
第一回目の記事は環境構築編です！

*※ uPortについてはこちらの記事が参考になります。*
https://zoom-blc.com/how-uport-is-working

#**目次**
- 環境情報
- 環境構築

#**環境情報**
windows7
node.js v8以上
Truffle Box

#**環境構築**
##Node.js環境のセットアップ
node.jsについては以下の記事に環境構築手順をまとめています。

[windows版](https://qiita.com/KaiOnuma-b/items/0de589e2f1dc8841091e)
*Mac版執筆中

##truffle Box環境のセットアップ
Truffle(Ethereumの開発フレームワーク)を
グローバルにインストール。

```bash:Truffleのインストール
>npm install -g truffle
+ truffle@4.1.13
added 81 packages in 16.997s
```

続いて、react-uportをインストール

```bash:TruffleBoxのインストール
>truffle unbox react-uport
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

 Compile:              truffle compile
 Migrate:              truffle migrate
 Test contracts:       truffle test
 Test dapp:            npm test
 Run dev server:       npm run start
 Build for production: npm run build
```

別のコンソールを立ち上げプロジェクトを実行します。
* http://localhost:3000 で立ち上がります。

```bash:別コンソール
npm run start
```

以下のような画面が表示されれば成功です！
![trufflebox.png](https://qiita-image-store.s3.amazonaws.com/0/242105/9373baba-a349-2862-536b-81ae78bbbd0e.png)

　　
　　
ここまででuPortアプリの開発環境構築は完了です。お疲れ様でした！
【EC-CUBE】同一画面で複数の住所フォームを持つ場合の対応

同一画面で複数の住所フォームを持つ場合の対応
EC-CUBEでは[YubinBango](https://github.com/yubinbango/yubinbango)のライブラリを使用しています。
詳しい使い方は[公式リポジトリ](https://github.com/yubinbango/yubinbango)を参照してください。

# 概要

そのままコピペで住所フォームを増やすだけだと1個の郵便番号の変更で全てのフォームがクリアされてしまう。

# 対応方法

1. 住所フォームごとに `h-adr` クラスで囲む
2. `h-adr`　ごとに `<span class="p-country-name" style="display:none;">Japan</span>` を記載する

# 例

## 修正前

例えば１画面に単一の住所フォームの場合は以下のようになっている。

```twig
<form action="{{ url('hogehoge') }}" class="h-adr">
    <span class="p-country-name" style="display:none;">Japan</span>

    {# ... #}
    
    {# 住所フォーム #}
    〒{{ form_widget(form.postal_code) }}
    {{ form_widget(form.address) }}

    {# ... #}

</form>
```

## 修正後

例えば以下のようにすればお互いのフォームが干渉しない。

```twig
<form action="{{ url('hogehoge') }}">

    {# ... #}

    {% for form in forms %}
        <div class="h-adr">
            <span class="p-country-name" style="display:none;">Japan</span>
    
            {# ... #}
    
            {# 住所フォーム #}
            〒{{ form_widget(form.postal_code) }}
            {{ form_widget(form.address) }}
            
            {# ... #}
            
        </div>
    {% endfor %}

    {# ... #}

</form>
```

# 参考

- 公式リポジトリ
https://github.com/yubinbango/yubinbango

- 複数フォームに対うしていただいたプルリク
https://github.com/yubinbango/yubinbango/pull/9

- 実際に使っている箇所
https://github.com/EC-CUBE/ec-cube/blob/experimental/sf/src/Eccube/Resource/template/admin/Order/shipping.twig
MySQL8.0のrootパスワード変更

調べたらわかったが、たどりつくまでに時間がかかった。
俺と同じように、とりあえずコピペで試してみる派の方々へ。

ここを見れば一目りょうぜn(ry
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html


まず、skip-grant-tablesを/etc/my.cnfに書く。
ファイルの場所は違うかもしれませんが、
俺と同じコピペで試してみる派の方々は多分そこ。

そして、以下のSQLを実行。

```sql
mysql> FLUSH PRIVILEGES;
--xxxxの部分をパスワードに置換してね
--xはチョメと読んでね
--こういう無駄なコメントを書くことを嫌がられています。とても心外です。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxxx';
```

skip-grant-tablesを削除するのをお忘れなきよう。。。

MySQL5.7をインストールする！
的な記事をコピってペしてたから、解決に時間がかかった。
リファレンスはきちんと読まないといけませんね。
Chart.js の円グラフでそれぞれの領域をクリックした際のイベント処理を定義する

Chart.js の円グラフでそれぞれの領域をクリックした際のイベント処理を定義する方法。

まずは option にクリック時のイベントハンドラを登録。

```javascript
var myChart = new Chart(ctx, {
    //グラフの種類
    type: 'doughnut',
    //データの設定
    data: {
        //データ項目のラベル
        labels: ["項目1", "項目2", "項目3"],
        //データセット
        datasets: [{
            //背景色
            backgroundColor: [
                "#808FCD",
                "#CCCCCC",
                "#DDDDDD",
            ],
            //背景色(ホバーしたとき)
            hoverBackgroundColor: [
                "#A0AFED",
                "#DDDDDD",
                "#EEEEEE"
            ],
            //グラフのデータ
            data: [20, 80, 70]
        }]
    },
    options: {
        // クリック時のイベントハンドラの指定
        onClick: onClickChart
    }
});
```
イベントハンドラは以下のように二つ引数を指定すると、最初の引数にイベントの詳細が、２番目にデータの詳細が入ってくる。グラフに表示されているすべてのデータもこのなかに入ってくるが、どの領域をクリックしたかの判定は _index プロパティをみればよい。

```javascript
function onClickChart(event, data) {
    var index = data[0]._index;
    switch (index) {
    case 0 :
        // １番最初の領域クリック時
        break;
    case 1 :
        // ２番目の領域クリック時
        break;
    case 2 :
        // ３番目の領域クリック時
        break;
}
```

さらに項目名なども取得できる。たとえば「項目1」の領域をクリックした場合以下のようにグラフから情報を取得することができる。

```javascript

var clickData = data[0];
clickData._index === 0
clickData._view.label === '項目1'

// この中にチャートのデータ一式が入っている
clickData.tooltip._data
```

[公式ドキュメント](https://misc.0o0o.org/chartjs-doc-ja/general/interactions/modes.html)
Mackerelのカスタムメトリックでプロセス一覧を表示する

断続的なアラートや瞬間的な過負荷等で、対応を検討する際に
プロセス一覧を時系列でみたくなる事ありませんか？
ありますね。

弊社では一部のサーバーをMackerelで監視していて
プラグインで任意の監視項目（メトリック）の追加も簡単にできるのでこれを利用していきます。

公式ページを参考に、今回は`PHP`でMackerelにメトリックを投稿してみます。
[ホストのカスタムメトリックを投稿する](https://mackerel.io/ja/docs/entry/advanced/custom-metrics)

# スクリプトを設置する

プロセス一覧を出力するプラグインを監視対象のサーバーに保存します。

```php:processlist.php
<?php

define(METRICS_NAME,'process-list');  // Mackerelのカスタムメトリックに表示される名前
exec('top -n1 -b | awk \'{print $9,$12}\'', $output);

$processes = array();

for ($i = 7, $count = count($output); $i < $count; $i++) {
    $proc = explode(' ', $output[$i]);
    if (count($proc) != 2) {
        continue;
    }

    if ($proc[0] == '0.0' || $proc[1] == 'top') {
        continue;
    }

    if (preg_match('/^(.*?)[\/]/', $proc[1], $matches) === 1) {
        $proc[1] = $matches[1];
    }
    if (array_key_exists($proc[1], $processes)) {
        $processes[$proc[1]] += $proc[0];
    } else {
        $processes[$proc[1]] = $proc[0];
    }
}

$graph = array(
    'graphs' => array(
        METRICS_NAME => array(
            'label' => 'top',
            'unit' => 'percentage',
            'metrics' => array(),
        ),
    ),
);

$timestamp = date('Y-m-d H:i:s');

echo "# mackerel-agent-plugin\n";
echo json_encode($graph) . "\n";
foreach ($processes as $key => $value) {
    echo METRICS_NAME.".{$key}\t{$value}\t{$timestamp}\n";
}
```

`mackerel-agent.conf`ファイルに先程設置したプラグインを使用するように追記します。

```bash:mackerel-agent.conf
[plugin.metrics.process-list]
command = "php /path/to/processlist.php"
```

# Mackerelで確認

設定したホストのカスタムメトリックにこんな感じでプロセスの一覧が表示されれば完了です。

<img width="175" alt="スクリーンショット 2018-07-17 18.50.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/262735/b5aee826-ec26-b931-c687-6c5492082c03.png">

# さいごに

プロセス一覧を可視化できるようになって、
先回りして対応するなど、アラートへの対応が少し楽になった気がしています。


Mackerelが標準で対応してない項目でも、
少しスクリプトを書くだけで簡単に追加して可視化できるのは便利ですし
どんどん使っていきたいですね。
ASP.NET > WebAPI > Getメソッドで、引数の末尾に.（ピリオド）で404 Error



以下のようにvaluesコントローラーにGetで「dog.cat」という文字列を送ると404エラーになりました。

`/api/values/dog.cat`

試行錯誤したがよく分からず。

↓を参考に、
[asp.net mvc - ApiController returns 404 when ID contains period - Stack Overflow](https://stackoverflow.com/questions/13298542/apicontroller-returns-404-when-id-contains-period)

以下のようにRouteを指定していたのをやめて、

```csharp
[Route("api/Values/{valueString}")]
public string Get(string valueString)
{
}
```

以下のようにただのGetメソッドにしたら404エラーが回避できました。

```csharp
// GET api/Values/email@address.com
public string Get(string valueString)
{
}
```

ひとまずこれでいったんは解決しましたが、根本的解決になっていないような・・・



## みんな困っているようです。

↓ ピリオド問題、みんな困っているようです。

[/api/values/dog.cat](https://stackoverflow.com/questions/30480019/webapi-route-with-period-in-final-parameter-fails)

[*](https://docs.microsoft.com/ja-jp/aspnet/web-api/overview/web-api-routing-and-actions/create-a-rest-api-with-attribute-routing)

[asp.net mvc - ApiController returns 404 when ID contains period - Stack Overflow](https://stackoverflow.com/questions/13298542/apicontroller-returns-404-when-id-contains-period)
CS-CartのPHPフックで捕まえた引数を書き換える方法

#※CS-Cart初心者＋フック管理に馴染みがない人が書いています。

・検索しても中々出てこなかったので、メモ書きします。

アドオンに必要な「addon.xml」「init.php」「アドオン名.po」は割愛します。

```php:func.php

<?php

if (!defined('BOOTSTRAP')) { die('Access denied'); }

/*

このアドオンは「get_currencies_list_post」フックを使って
言語が英語で日本円が来た場合、表示を「Yen」に変えるアドオンです。
*/
function fn_yen_symbol_get_currencies_list_post($params, $area, $lang_code, &$currencies)
{

    if($lang_code == 'en'){
        //ここで$currenciesを書き換えている
        $currencies['JPY']['symbol'] = 'Yen';
    }

}
```
注目してほしいところは`&$currencies`の所です。

引数に*&*を付けることでその引数を更新することが出来ます。
もう泣かない！input type="file"のボタン部分をcssでデザインする方法

`input type="file"` を使って
ファイルを選択する時のボタンがあるのですが
これがなかなかうまくcssが利いてくれなくて困ってました。
※しかも、ボタン部分だけでなく、ファイル名が表示される部分も残しつつです:zap:

なんとか解決策が見つかりましたよー:wave:

:point_up:肝はcssの`::before` 要素。
`::before` 要素を使ってボタン部分をデザインしてください

:v:もう一つの肝は`input[type="file"]::-webkit-file-upload-button`
デフォルトの「ファイルを選択」ボタンの装飾を非表示になるようにcssで調整します

デフォルトのボタンの上にデザインしたボタンを重ねるというイメージですね。
### HTML
```HTML
<div class="file-upload_area">
  <input type="file" id="csv-file" name="files" class="file-upload_input">
</div>
```

### css（SCSS）
```SCSS
//====================================
// input type="file" ボタン
//====================================
input[type="file"]:focus {
  outline: 0;
}
.file-upload_area {
  margin-bottom: 20px;
  position: relative;
  .file-upload_input {
    margin-left: 35px;
    &::before {
      background: #f5faf9;
      border-radius: 2px;
      color: #32a692;
      content: 'ファイルを選択';
      font-size: 14px;
      left: 0;
      padding: 10px 12px;
      position: absolute;
      top: -12px;
    }
  }
  input[type="file"]::-webkit-file-upload-button {
    background: -webkit-gradient(linear, left top, left bottom, from(transparent), to(transparent));
    background-color: transparent;
    border: 0;
    margin: 0 20px 0 0;
  }
}
```

## 出来上がり
や〜良かったよかった:relaxed:

<p data-height="265" data-theme-id="0" data-slug-hash="RBGdVW" data-default-tab="css,result" data-user="kikuchi" data-embed-version="2" data-pen-title="「ファイルを選択ボタン」をcssでデザインする" class="codepen">See the Pen <a href="https://codepen.io/kikuchi/pen/RBGdVW/">「ファイルを選択ボタン」をcssでデザインする</a> by naoko kikuchi (<a href="https://codepen.io/kikuchi">@kikuchi</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Angular CLIでServiceを生成するとe2eディレクトリ内に入ってしまう場合の対応

# 概要

- Angular本体を6系にメジャーバージョンアップした後に発生
- `ng g service XXXXX` とすると、 `e2e/` 内にサービスが生成されてしまう

## 対策

- `angular.json` を下記のように書き換えればOK (プロジェクト名がmy-appの場合)

### 変更前

```json
    "my-app-e2e": {
      "root": "",
      "sourceRoot": "e2e",
```

### 変更後

```json
    "my-app6-e2e": {
      "root": "e2e/",
```
AndroidStudioのエミュレータでスクリーンショットを撮る方法

#はじめに
検索しても意外と古い情報しか出てこないので、書いておきます。

#環境
Windows 10
Android Studio 3.1.3
Android Emulator 27.3.9

#方法
![howToCapture.png](https://qiita-image-store.s3.amazonaws.com/0/104983/fbb17261-5d18-634b-3df9-df45314864d0.png)

エミュレータ横のツールボックスより、カメラマークをタップ。
そうするとシャッターを押したようなエフェクトのあとに、**デスクトップ**に「Screenshot_○○○○○.png」というファイル名で保存されます。

（自分はクリップボードにコピーされるものだと思いこみ、意外とハマりました…:joy:）
メモ：CLIでiOSシミュレータをバージョン指定起動

この記事は
===

* 個人メモです

手順
===

iOSシミュレータの一覧を表示
---

* なんか一覧がキーと一緒にずらっと出てくる

```
xcrun simctl list
```


iOSシミュレータを起動
---

* キーを指定して起動する

```
open -a "Simulator" --args -CurrentDeviceUDID E7F36DD2-5208-43AB-B270-A5E1488AEBB7
```
pythonでグラフ構造が必要な時はnetworkxを使おう

# networkxの使い道
グラフ構造やツリー構造が必要な時に、自分で実装していませんか？
pythonの標準ライブラリにはグラフ構造が実装されていないため、
必要になるたびに簡単なグラフ構造のAPIを自作している方が多いと思います。

<!---
自分で実装した場合ドキュメントの作成等の手間がかかるうえに、
他の開発者が使い方を覚えるための負担になってしまいます。
-->

networkxは最短経路の導出等、ネットワークを解析するためのパッケージですが、
hashableなオブジェクトならなんでもノードにすることができ、
エッジの抽出や幅優先探索等の一般的なAPIも実装されています。
さらに、簡単にグラフを可視化できるため、効率的にデバッグできます。
これらの機能からnetworkxはネットワーク解析だけでなく、
グラフ構造APIの実装として十分活用できます。

本ブログではnetworkxをグラフ構造APIの実装として活用する際に必要となる
最低限な機能以下3点を説明します。

1. グラフの作成
2. グラフからのデータ抽出、
3. グラフの可視化

# グラフの作成
networkxではまずグラフオブジェクトを作成し、
グラフオブジェクトのメソッドを使ってノードやエッジを追加します。[^1]

#### グラフオブジェクトの作成
グラフの種類によってインスタンスを作成するクラスが違います。[^2]

```python
import networkx as nx
simple_graph = nx.Graph() #無向グラフを作成 
directed_graph = nx.Digraph() #有向グラフを作成
```
[^1]: もちろん、グラフとノード、エッジを同時に作成する方法もありますが、基本はグラフ作成後にノード追加です。
[^2]: 単純グラフではないグラフを作成したい場合、MultiGraphを使用する必要があります。

#### ノード、エッジの追加
グラフの作成後、グラフオブジェクト(下表では "graph")のメソッドから
ノードとエッジを追加します。
ノードとエッジは同時に複数追加することもできます。
ノードはhashableなら良いので
基本的なオブジェクトはなんでもノードにできますし、
自前実装のオブジェクトもノードにできます。
エッジを追加する際はノードが存在しない場合、自動的にノードが作成されます。

```python
graph.add_node(node)
graph.add_nodes_from([node1, node2])
graph.add_edge(node1, node2, attr_name = attr_val)
graph.add_edges_from([(node1,node2,{"attr_name": attr_val})
                     ,(node2, node3,{"attr_name": attr_val})])
```

# グラフからのデータ抽出
グラフからデータを取得する方法は様々なAPIが存在しますが、
最も基本的な取得方法は以下の2種類です。

- ノードやエッジの一覧を取得
- ノードを引数として近傍やエッジを取得 

#### 一覧の取得
ノードとエッジの一覧は下記のapiからイテレータを取得できます。
リストにするにはリスト関数を実行する必要があります。

```python
graph.nodes
list(graph.nodes)
graph.edges
list(graph.edges)
```

#### 近傍やエッジの抽出
グラフからデータを抽出するにはグラフオブジェクトがどのようにデータを保存しているか
知る必要があります。
正確ではありませんがグラフオブジェクトはノードをキー、
近傍からエッジへの辞書をバリューとしたオブジェクトを持っているイメージです。

```python
graph = nx.Graph()
graph.add_edge(1,2,attr="edge1")
graph.add_edge(2,3,attr="edge2")
# 以下のようなデータ構造が作成されます。
{
  node1: {node2: {"attr": "edge1"}},
  node2: {node1: {"attr": "edge1"},
          node3: {"attr": "edge2"}
          }, 
  node3: {node2,{"attr": "edge2"}}
}
```

したがって以下のようにノードから近傍の取得、エッジ取得ができます。
なお、エッジは属性名をkey、属性値をvalueとした辞書になっています。

```python
neighbor = graph[node1] # neighborはノードのイテレータ
edge = graph[node1][node2] 
```

# グラフの可視化
netowrokxはMatplotlibを使ってグラフを可視化します。[^3]
グラフの描画ではノードの配置を決めるのが面倒くさいですが、
networkxはよく使われるレイアウト決定方法を実装してくれており、
簡単に可視化できます。
以下の例では、レイアウト決定方法としてspringレイアウト(デフォルト)を使用しています。

[^3]: Graphvizも利用できます。

```python
import matplotlib.pyplot as plt
nx.draw(graph)
plt.show()
```
他のレイアウト決定方法を使いたい場合や、ノードのid, エッジのアトリビュートを表示したい場合等、
詳細な可視化制御が必要な場合は nx.draw_networkxを使用してください。
各パラメータの意味は[公式ページ](https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html#networkx.drawing.nx_pylab.draw_networkx)を参考にしてください。


p.s. 意見や感想をコメントに書いていただけると嬉しいです。
もしコメントがあれば今後も記事を書こうという気になるので、、
ちなみに、今後はnetworkxのメインの機能であるグラフの解析APIや、
グラフを可視化する際のレイアウト決定アルゴリズムを説明する予定です。
しばらく信号が来なかったらそのことをお知らせするパッチ　Max tips

OSCなどでコンピュータ間で通信している状況で、しばらくの間相手のコンピュータから信号が来なかった場合の対策をするために、作ったパッチ。

上からbangが来ている間は、下の方に新号が流れない。上からbangが来なって10秒立つと下からbang
が出てくる。


![画面収録.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/217195/525aae05-f6c2-d9b0-fef7-2a201d4582cb.gif)
MongoDBでデータベースの容量が大きすぎてメモリに乗らない場合の対処方法

# はじめに
MongoDBで特定の環境のみで大量のエラーを吐いて落ちる現象を確認しました．エラーを確認したところ，MongoDBのデータベース容量が過剰でメモリに乗りきらない可能性があると考えました．特に，WiredTriggerがメモリ・アロケーションに失敗しているようなエラーを吐いていました．

ここでは，データベースがメモリに乗りきらないので修復することを目的に話を進めます．ほかの理由でMongoDBが落ちる場合は，ほかの対処方法を探してください．

## MongoDBのデータベースの修復

MongoDBの```mongod```コマンドでは，データベースを現在の環境に合わせて修復するコマンドが用意されています．

```mongod --repair --dbpath="C:\db"```でデータベースの修復処理を走らせることができます．あくまでデータベースの修復だけで，サーバの立ち上げは行いません．

再度，```mongod --dbpath="C:\db"```でデータベースを開いてください．

## MongoDBのrepairオプション
repairオプションでは，MongoDBのデータベースファイルの修復を自動的に行います．

例えば，データベースを作成した環境のメモリが32GBで，運用環境で4GBしかメモリがないとき，データベースがメモリに乗りきらずに落ちることがあります．ほかにも，過去に強制的にMongoDBをシャットダウンしたら```.lock```ファイルが残ってて起動しなくなる，などのトラブルも自動的に解決します．

MongoDBが立ち上がらないときは，焦らずに```repair```オプションを使ってデータベースを修復してみましょう．
特定の日付以降、活動がない Slack channel を一括でアーカイブする

Slackを使った業務コミュニケーションを続けていると、活動が止まってしまったチャンネルがだんだん溜まってきてしまいます。そういうチャンネルはなるべくアーカイブして、アクティブなチャンネルだけ残したい、と思ったんですが、手軽な方法が見つけられませんでした。

そこで、Slack APIと `jq` を組み合わせて、特定の日付以降、活動がない Slack channel を一括でアーカイブするスクリプトを作ったので公開します。誰かの役に立てば幸いです。

## 用意するもの
- Mac
- shell
- jq
- Slackの管理者権限
- Slackのレガシーなトークン
    - レガシーじゃない方がよさそうですが、簡単にできるやり方を選択しちゃいました


## スクリプト

APIをつかい、チャンネルの一覧を取得して、特定の日付以降に発言がないチャンネルをアーカイブする、という単純なものです。レスポンスのフィルタには `jq` を使ってうまいことやってます。

```shell
# 以下二つの変数を設定して実行
TOKEN_SLACK=xoxp-**********
TARGET_DATE=2018-**-**

# アーカイブされていないチャンネルのID一覧を取得し繰り返し処理
for ch in $(curl -s "https://slack.com/api/channels.list?token=$TOKEN_SLACK" | jq -r '.channels[] | select(.is_archived == false) | .id')
do

    # TARGET_DATE以降のメンバーとbotの発言数を取得
    count=$(curl -s "https://slack.com/api/channels.history?token=$TOKEN_SLACK&channel=$ch&count=100&oldest=$(date -j -f '%Y-%m-%d' $TARGET_DATE '+%s')" |
                jq -r '.messages | map(select(.subtype == null or .subtype == "bot_message")) | length')

    # 発言数が0ならアーカイブ
    if [ $count -eq 0 ]; then

        # アーカイブするチャンネルの情報を標準出力に表示して
        curl -s "https://slack.com/api/channels.info?token=$TOKEN_SLACK&channel=$ch"|jq -r '.channel | [.id, .name] | @csv'
        sleep 1

        # アーカイブする
        curl -s "https://slack.com/api/channels.archive" -X POST -F "token=$TOKEN_SLACK" -F "channel=$ch"
    fi
    sleep 1

done
MySQLの起動から定義と操作まで


MAMP導入後のterminalにて、SQLを初歩的に定義、操作する方法をまとめる。
今回は、起動とちょっとした操作まで。
その都度、追記します！

#MySQLの起動
MySQLの起動を行う。

```
$ cd Applications/MAMP/Library/bin

$ ./mysql -u ユーザー名 -p
Enter password: パスワード
```
<font color="blue">Welcome to the MySQL monitor.</font>と表示されればOK!
#SQL
ここからがSQLになる。
小文字、大文字どちらでも結果に変化がないが、大文字で書くと、どれがSQLか分かりやすくなる。

DBは [DATABASES] > [TABLES] > [DATA] のような構造になっている。
##DBの一覧を表示

```
mysql> SHOW DATABASES;
```
構造化されてDB一覧が表示される。
##使用するDBを決める

```
mysql> USE 使用するDB名;
```
<font color="blue">Database changed</font>と表示される。

##TABLE一覧の表示

```
mysql> SHOW TABLES;
```
構造化されてTABLE一覧が表示される。

##TABLEの構造を表示

```
mysql> DESC 開きたいTABLE名;
```
以上で、データの中身を見ることができる。
よく使うBracktes ショートカット

よく使うbrackets
ショートカット
キャッシュクリア
command + shift + r
コマンド　sitft r
●タグを囲む
*ctrl + shift +A

●現在のコードを折りたたむ
＊command + alt [ 

●現在のコードを広げる
＊command + alt ]

●ライブビュー
＊ctrl + alt + p

●行間削除
＊ctrl + shift + D

●Beautyfi
*command + shift + l

●開始タグか終了タグへキャレットを移動
＊Ctrl（Cmd）+Shift+T

●要素や属性が空のポイントにキャレットを移動
*Ctrl（Cmd）+Alt+→

●ベンダープリフィクスのついたプロパティに値を反映させます。
*Ctrl（Cmd）+Shift+Alt+R

●置換
*Cmd + alt + f

●ファイルを横断して置換
*Cmd + alt + shift + f

●タグ境界選択
*内側から：⌘ + opt + b
*外側から：⌘ + opt + sift + b

●EMMET
*img[src=”img_$$.png”]*3

連番
$*n
*ul>.menu$*3>a

テキスト挿入
*{text}	p{text}

●キャレットがある位置の行をコメント
*Ctrl（Cmd）+/

●タグの更新
*（Cmd）+Shift+I

●タグのペアを確認
*Ctrl+Shift+T

●行の先頭や末尾へ移動する
*Ctrl+←もしくは→

●1行まるごと選択する
*Ctrl+L

●選択範囲と同じ文字列を複数選択する
*Ctrl+B （Bを繰り返えせば、同じ文字列を見つけて選択を繰り返します。）

●上記の複数選択中、スキップしたい時
*Ctrl+Shift+B

●行を指定して移動する
*Ctrl+G

●マルチカーソル
Ctrlキーを押したまま 複数のポイントをクリックと選択することで、その箇所を同時に編集可能
Ctrl+Bキーを押すことで同一テキストを順に選択可能
Altキーを押したまま縦方向にポインターを移動することで領域で選択して編集

＊一文字ずつ移動する方法の問題点は、文字数が違う場合は対応しきれないという点です。
そういう場合は単語単位でのカーソル移動で解決できます。
Ctrl + Left, Ctrl + Rightでカーソルの単語単位での移動ができます。

・Homeキー, Endキーで行頭、行末への移動

https://techacademy.jp/magazine/9532
StoryboardでUIScrollViewを用いる際、ContainerViewを使うと便利

## 前置き
Storyboardで画面を作っている時に困ることとして、UIScrollViewを使用する際、中のコンテンツが一部しか見えない問題があります。

先日同様の悩みをお見かけしました。

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">自分はStoryboardでContentViewが全画面見えないのが嫌で、ContentViewはxibにしてます。さらにViewControllerにはプログラム側からaddSubviewして、プログラム側で制約をつけてます。<br><br>もっといい方法知りたい。</p>&mdash; nori (@1amageek) <a href="https://twitter.com/1amageek/status/1020156491486015488?ref_src=twsrc%5Etfw">2018年7月20日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

多くの人は、XibなどContentViewを別ファイル化する、または中のコンテンツが見えない状態でStoryboard上に実装しているのではないかと思っています。

これに対する自分なりの解を書こうと思います。

## 説明
私のやり方は、StoryboardでContainerViewを用いて作る方法です。

流れとしては下記となります。

#### 1. UIScrollViewControllerを置く
<img width="1392" alt="スクリーンショット 2018-07-23 16.23.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/154832/784be29a-882e-7bce-7c35-6595d7797a34.png">

UIScrollViewを用いたい位置とサイズで制約をつけます。


#### 2. UIScrollViewの中のContentViewはContainerViewを置く
<img width="1392" alt="スクリーンショット 2018-07-23 16.22.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/154832/a1b313c2-c966-cb81-5f29-97d1c9516706.png">

UIScrollViewのContentViewとなるViewを`ContainerView`で配置し、制約をつけます。この時、スクロールさせたい方向にViewを伸ばしてやります。
スクリーンショットでは縦にスクロールさせたいため、ContainerViewのHeightを固定で800px指定しています。


#### 3. ContainerViewに対して各種Viewを置く
<img width="1392" alt="スクリーンショット 2018-07-23 16.21.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/154832/74e36847-dfa3-25e4-0014-6965cf191dbf.png">

ContainerViewには、配置した時点でUIViewControllerが紐づいており、このUIViewControllerの大きさはContainerViewの大きさで表示されるため、これがUIScrollViewのContentViewとなります。
これにより、従来UIScrollViewの中にUIViewを入れてた時とは異なり、ContentViewをUIScrollViewと同一ファイル内で扱え、全容も見たり弄ることができます。

[サンプルはこちら](https://github.com/Aryzae/DisplayedContentView)

※ContentViewが可変サイズの場合は、別途書く予定です。

## 補足
副次的なメリットとして

* ContentViewをUIViewControllerとして実装できるため、UIViewとして作るより、LifeCycle途中での処理を記述しやすい
* ContentViewをUIViewControllerとして実装できるため、`touchesEnd`等を使える

デメリットとして

* UIScrollViewが置かれているUIViewController側と分けられるため、ユーザがContentViewで行う操作で、UIScrollViewがあるUIViewController上の何かを操作したい場合、delegate等で伝える仕組みが必要になる
GameShellのタイムゾーン設定

[kickstarterで盛り上がってた？GameShell](https://www.kickstarter.com/projects/954662076/gameshell-redefine-retro-game-console?lang=ja)とりあえず手に入れたので初めにやった事を書いとく。
##timezoneの設定
起動し、ネットワークの設定をするとUTCで時間が表示されるようになる。
それをJSTに変更するには？
まず、sshで自分のGameshellに接続。接続方法は、簡単でデフォでインストールされてるTinyCloudを起動してみればわかる。

sshでログインできたら
後は
```sudo timedatectl set-timezone Asia/Tokyo```
で完了。
Vimでshift-jisからutf-8へ変換

Vim でwindowsで書かれたファイル（shift-jis）をmacやlinuxで開くと文字化けする。
これをutf-8に変換する。
まずは普通にVimでファイルを開く。コマンドモードで以下のコマンドを順番に入力する。

```Vim
#shift-jisで表示する
:e ++enc=shift-jis
#utf-8に変換
:set fenc=utf-8
#改行コードをLFに変換
:e ++ff=unix
#改行コードに^Mが表示されるので（CRLF)、^Mを削除してLFにする
:%s/^M//g
```

^MはCtrl+V + Ctrl+M
Vue.js + Vuex + async/await で非同期処理

## まとめ
- Vue.js + Vuex において非同期処理は、actions 内で実行するのが良い。なぜなら、アクションを定義するメソッドの中で action の dispatch や mutation への commit を任意のタイミングで実行できるので、柔軟に処理を組み合わせることができるからだ。

- その際、async/await シンタックスで書くことで、非同期処理を「あたかも同期処理のように、上から下へと希望する処理順と同じように書くこと」ができる。これはあくまで見た目であって、非同期処理は非同期処理である。内部的には Promise である。

## まずは axios を使った promise ベースの http リクエストをだすメソッドを作る

- axios は http リクエストをだすためによく使われる npm。
- async function を作るには、普通の function literal の前に async をつける。
- async function の中で await を書くと、promise オブジェクトを待ち受けて、それが fulfilled もしくは rejected (ようはなんらかの解決がされる) になるまでそこで停止する。
- 例えばここでは axios の get が終了するまで await でまつ。取得できたら、res に axios の結果が代入されて、次の行に移動する。
- async function の中で return した値は promise object として返される。

```js:/api/fetchListAPI.js
import axios from 'axios'

const fetchList = async () => {
  const res = await axios.get("https://api.com/fetch-list", {})
  return res.data
};

export default fetchListAPI
```

## actions の中で dispatch, commit を任意のタイミングでおこなう

- actions のメソッドは、commit, dispatch を受け取って実行できるので、任意のタイミングで実行すればいい。
- commit で mutation に、dispatch で action にアクセスできる。
- actions のメソッドは async function にできるので、その中で await を使うことができる。
- commit で渡す payload となる引数の場所でも await できる。`await dispatch('fetchList')`
- そうした場合、dispatch された action が返す promise オブジェクトを待つことになる。 

```js:actions.js
import fetchListAPI from '@/api/fetchListAPI'

const actions = {
  async getList({ commit, dispatch, state }, payload) {
    commit('SET_LIST', await dispatch('fetchList'))
  },
  async fetchList({ commit, dispatch, state }, payload) {
    const list = await fetchListAPI()
    dispatch('dispatchDone')
    return list
  },
  dispatchDone() {
    console.log('fetch done')
  }
}

export default actions

```

```js:mutations.js
const mutations = {
  SET_LIST(state, payload) {
    console.log('payload', payload)
    state.List = payload
  }
}

export default mutations
```
Macにインストールするべき便利アプリ・Chrome拡張機能一覧

# Mac環境構築メモ

仕事用・プライベート用ともに入れているMac用のアプリやChrome拡張機能をまとめた。
他に便利そうなの見つけたらその都度更新する予定。

## アプリ

### ブラウザ

- Vivaldi（別にChromeでもいいです。好きな方を選ぶ）

### 便利・効率化

- 1Password: パスワード管理はこれないと死ぬ
- Alfred 3: PC内のファイル検索
- ClickUp: TODO管理用（Trelloの上位互換。たぶんこれが今の所最強）
- Google 日本語入力: デフォルトよりは頭いいはず
- Grammarly: 英文チェッカー
- ToggleDesktop: ポモドーロタイマーで集中してタスクをこなすために使用

### ファイル共有

どちらかに統一した方がいいけれど、なんとなく２つ使ってます。

- Dropbox
- Google Drive

### コミュニケーション

- Slack: 今どき社内のコミュニケーションはSlackでしょ（プライベートでも使ってる）

### メモ・情報管理

- Alternote: Evernoteの代替
- Kindle: 最新の技術書はだいたいkindleで買ってる
- Papers: 論文の管理用（Edwardの作者であるDustin Tranのおすすめ）
- Typora: markdown書くならたぶんこれが最強

### 情報収集

- Cappuccino: RSSとかまとめるやつ
- TweetDeck: twitterは情報収集......

### 開発

#### 仮想環境

だいたいDockerかVirtualBoX使っておけば間違いない。

- Docker
  - Kitematic
- Vagrant + VirtualBox
- Parallels Desktop: GUIがほしくて、かつVirtualBoxではパフォーマンス不足の場合はこれがベスト



#### IDE・ターミナル

- Emacs: spacemacsでvimキーバインド選んでるので、emacsとvimが合わさり最強に見える
- iTerm: neovim入れるといろいろはかどる気がする

#### データ分析用ツール

- RStudio: R使うならこれ
- Gephi: ネットワーク分析ならこれ

#### バージョン管理

- SourceTree: TowerとかGitKrakenとか試したけれど、結局これが使いやすいことに気づく

#### 補助ツール

- Postman: 手軽なHTTPクライアント
- Wireshark: tcpdumpしたい時に使う


### 音楽

- Shazm: 周りの音楽を勝手に認識して教えてくれるやつ。最近入れてみたのでまだよく分かっていない。
- Spotify: BGM


## Chromeの拡張機能

後は適当。必要になったらインストールすればよい。

### 必須

- 1Password
- Save to Pocket
- Toggl Button: Productivity & Time Tracker

### できれば

- Grammarly for Chrome
- Highlight Keywords for Google Search
- No Mouse Search Navigation
- WhatRuns
Proxy下でTensorFlowのMNIST


## 概要

左も右もわからない状態でTensorFlowのMNISTをコピペで動かそうとした際に動かない

```python
#%%
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
```

上のソースを実行しても、

```
URLError: <urlopen error [WinError 10060] 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。>
```
となる。

## 解決策

以下の記事を参考にしました。
https://qiita.com/gazami/items/4b42371ed831c159fb04

input_dataで使われているurllibにプロキシの設定を追加するだけですね。

```python

#%%

from tensorflow.examples.tutorials.mnist import input_data
import urllib.request

proxy = urllib.request.ProxyHandler({'https': 'https://path:port'})
opener = urllib.request.build_opener(proxy)
input_data.urllib.request.install_opener(opener)

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

```

urllibのproxy設定が問題なのは検討がついていたのですが、
Pythonを始めたばかりの事もあり、input_dataで使われているurllibに設定を適用する方法を見つけるのに苦戦しました。
また、ダウンロード先がhttpsかhttpのどちらなのか確認することを忘れずに。
hubot-slack v4 で Cron が動かなくなったので対応してみた

動作環境

hubot-scripts v2.17.2
hubot-slack v4.5.3
node-cron v1.3.0

上記の環境で以下のようなCronを走らせていたとする

```coffeescript:cron.coffee
cronJob = require('cron').CronJob 

CHANNEL_ID = robot.adapter.client.rtm.dataStore.getChannelOrGroupByName(hogehoge).id

new cronJob('0 0 13 * * *', () ->
 robot.send({ room:CHANNEL_ID }, "13時です！")
).start()
```

するとある日から突然、下記のようなエラーを吐いてSlackに通知されなくなった。

```
ERROR TypeError: Cannot read property 'send' of undefined
```

robotにsendプロパティとか無いよ！という内容のエラーで、sendに与えるパラメーターが不正だとこのエラーが出ることがあるのだが、パラメーターをどうやっても修正できず、そもそも robot.send を使わなければいいのでは？と考え始め

```coffeescript:cron.coffee
cronJob = require('cron').CronJob 

CHANNEL_ID = robot.adapter.client.rtm.dataStore.getChannelOrGroupByName(hogehoge).id

new cronJob('0 0 13 * * *', () ->

  message = "13時です！"
  options = { as_user: true, link_names: 1, attachments: '' }

  robot.adapter.client.web.chat.postMessage(CHANNEL_ID, message, options)

).start()
```

最終的に robot.send を使わないという方式で一応解決した、ちなみに options がなくても発言は可能だが botのアイコンがデフォルトのアイコンになってしまう。

参照：https://qiita.com/taka0125/items/6260bc7cfc1a5f6026f1
[React] リストアイテムに対するバケツリレーを recompose を使って軽減する

# Before

```jsx
const Menu = ({ currentUserId, currentLocation, title, path }) => (...)

const MenuBlock = ({ currentUserId, currentLocation }) => (
  <MenuList>
    <Menu
      currentUserId={currentUserId}
      currentLocation={currentLocation}
      title="ホーム"
      path="/home"
    />
    <Menu
      currentUserId={currentUserId}
      currentLocation={currentLocation}
      title="お知らせ"
      path="/notifications"
    />
    <Menu
      currentUserId={currentUserId}
      currentLocation={currentLocation}
      title="設定"
      path="/setting"
    />
  </MenuList>
)
```

# After

## 基本形

```jsx
import { withHandlers } from 'recompose'

const Menu = ({ currentUserId, currentLocation }) => ({ title, path }) => (...)

const MenuBlock = withHandlers({ Menu })(({ Menu }) => (
  <MenuList>
    <Menu title="ホーム" path="/home" />
    <Menu title="お知らせ" path="/notifications" />
    <Menu title="設定" path="/setting" />
  </MenuList>
))
```

注意: `displayName` にこだわる場合は適宜関数に名前つけるなどしてください


## `pure` を付与したい場合

```jsx
import { withHandlers } from 'recompose'

const Menu = pure(({ currentUserId, currentLocation, title, path }) => (...))

const MenuBlock = withHandlers({
  Menu: (parentProps) => (props) => <Menu {...parentProps} {...props} />,
})(({ Menu }) => (
  <MenuList>
    <Menu title="ホーム" path="/home" />
    <Menu title="お知らせ" path="/notifications" />
    <Menu title="設定" path="/setting" />
  </MenuList>
))
```

できれば `withHandlers` の中で引数が分かれたまま `pure()` を当てたかったんですが， recompose の仕様上**`pure`によって作られたクラスを関数として呼んでしまう**ことによりエラーが発生するので，こうするしかないみたいです。
Nickel + Diesel (nickel_diesel) で `db_conn()` するとクラッシュするとき

Rust初心者なので変なところで躓いてしまった。

# 要約

nickel_diesel crateをつかおうとして凡ミスに気づかず謎のクラッシュでハマったので気をつけようというお話。
RouterのHandler内でDatabase接続を使用するときには、Database接続を先にNickelに `utilize` しておこう。
そうでないと crash する。

```command
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/myblog-rs`
Listening on http://127.0.0.1:8019
Ctrl-C to shutdown server
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', libcore/option.rs:335:21
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

## 実装

`extern crate` とか `use` とかは省いて、概ねこんな感じ。
このコードの `server.utilize(db_pool);` と `server.utilize(router());` の行を逆に書いてしまうと、Databaseの接続が取得できずに (`None` が取れてしまって) ランタイムでクラッシュする。
具体的には、当該URLに対してHTTPリクエストを投げたときにクラッシュする。Backtrace見ると、`index` 関数の `req.db_conn()` している行で落ちる。

```rust
fn main() {
    let mut server: = Nickel::new();

    let mysql_url = "mysql://root:password@127.0.0.1:13306/blog";
    let connections: u32 = 5;
    let db_pool: DieselMiddleware<MysqlConnection> =
        DieselMiddleware::new(mysql_url, connections, Box::new(NopErrorHandler)).unwrap();

    server.utilize(db_pool);
    server.utilize(router());

    server.listen("127.0.0.1:8019").unwrap();
}

fn router() -> Router {
    let mut router: = Nickel::router();
    router.get("/", index);

    router
}

fn index<'mw>(req: &mut Request, res: Response<'mw>) -> MiddlewareResult<'mw> {
    let conn: PooledConnection<ConnectionManager<MysqlConnection>> = req.db_conn();
    let result = conn.execute("SELECT 1").unwrap();
    res.send(format!("{}", result))
}
```
AutoHotKeyでCtrl+Spaceを全角／半角切り替えを行う

#Windows10マシンでのUSキーボードで楽をしたい
通常のUSキーボードで日本語切り替えをする場合は、``Alt+`(チルダ) `` の組合せをする必要がある。
当然面倒なので、やってられない。
（5年以上MacOSを使っていたため、AutoHotKeyの存在を知らなかった。）

#MacOSでの日本語切り替えの方法
`Command+Space`

#日本語切り替え方法を悩む
USキーボードの場合、Macキーボードと違い、Spaceキーの左右は、Altキーが存在する(Macキーボードでは、Spaceキーの左右は、`coommand`キーだ)。
そのため、`Alt+Space`を日本語切り替えにしようかと思って設定していたが、なぜか不便な感じがして止めた。
仕方なく、Ctrl+Spaceの組合せにしたのだが、今度はMacOSで日本語入力するときもCtrl+Spaceの組合せで切り替える癖がついてしまい、やる気をそがれてしまう。
複数(とは言え2種類)のOSを使い分けるのは骨が折れてしまう。

##Ctrlキーとは？
当然Aキーの左側にありますよね？
キーボード備え付けのキーレイアウト(マクロ?)で入れ替えていると思います。

```AHK:Caps2Ctrl.ahk
CapsLock::Ctrl
sc03a::Ctrl
#InstallKeybdHook
#UseHook
```

残念ながらAutoHotKeyでは入れ替えることが出来ませんでした。
（Ctrlキーが押しっぱなしになってしまい、使い物になりません）
英語キーボードを使っているのだが・・・。

###参考URL
https://did2memo.net/2013/10/03/autohotkey-ctrl-key-is-stuck/
http://heavy.sblog.jp/?p=144
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1299757242


##キーボード
学生時代から[Happy Hacking Keyboard(以下HHKB)](http://www.pfu.fujitsu.com/hhkeyboard/)を使い続け、そのときはWindowsOSだった。
MacOSとの組合せは、6〜7年ほどしかないが、もう戻れない。
そのため、わざわざWindowsOS用にキーボードを[買い増し](https://www.amazon.co.jp)した。
ここ数週間は[NiZ(87キー)キーボード](https://www.digitevil.com/collections/keyboards)を使っているが、キーが軽くて気持ち悪さを覚えている。
今後もWindowsOSにあったキーボード探しの旅に出ると思う。
　　HHKBは10年以上の友だ。
今日も[Amazon](http://www.duckychannel.com.tw/en/ducky-mini/)からキーボードが届く。
※公式ページはどこだ？
　これ？　https://www.nizkeyboard.com


#実際の設定

```AHK:AutoHotKey.ahk
#IfWinNotActive, Minecraft
	^Space::Send, {vkF3sc029}	; Ctrl+Spaceで"全角/半角"キー送信
	return
#IfWinNotActive

;;; Minecraftの起動 win + Alt + m
#!m::
	MinecraftGame := "D:¥game¥Minecraft¥MinecraftLauncher.exe"
	IfWinExist, Minecraft
	{
		sleep 500
		WinActivate
	}
	else
	{
		Run, %MinecraftGame%, , , varMinecraftPID
		WinActivate
	}
return

#IfWinActive Minecraft
b::SubMinecraftF3AndB()	; F3+b あたり判定表示の有無を切り替える.
PrintScreen::Send, {F2}	; Minecraft用のスクリーンショット
#IfWinActive

;	■□■□■□■□■□■□ 以下,サブ関数 □■□■□■□■□■□■
SubMinecraftF3AndB()
{	; bキー単独で動く.
;			F3+b あたり判定表示の有無を切り替える.
		Send, {F3 Down}b
		Sleep 100
		Send, {F3 Up}
}
```

##AutoHotKeyなのに、Minecraftの話
`Ctrl+Space`を日本語切り替えにした場合、Minecraftのキーと競合する。
Minecraftゲームでは、Ctrlキーが走る。Spaceキーはジャンプ。
Ctrl+Spaceでは、走りながらジャンプする。これをすることにより、微妙に移動速度が上がる。
そのため、この組合せを殺すことが出来ない。
ゆえに、ゲームが起動しているときだけ、日本語切り替えを無効化するようにしている。
そのキーワードが`IfWinNotActive`で、スペース後にゲームのタイトル名を付ければ、ゲーム起動時にはキーワードで囲まれたホットキーを無効化できるという訳だ。
設定時は、競合していることに気づかず、混乱していた。

##ついでに、Minecraftゲームの起動設定
`Win+Alt+m`の組合せで、Minecraftゲームが起動するように設定した。

その後、ゲームのなかで、Mob(動物や敵など)を検知しやすくしたいので、デバッグ機能の一部に、`F3+b`の組合せにて、それが可能になるのだが、キーを押すのがめんどくさい。
そのため、bキー押下のみでそれが実現できるように設定している。
Minecraftを起動しているときにだけ動けば良いため、`*.ahk`ファイルもそのように分けていた。
しかし、`IfWinActive`は、どちらにせよ記述しなければまともに動いてくれなかったため、ファイルを分ける意味を見つけられなくなってしまった。
IfWinActiveを付けずにキーの組合せをした場合、F3だけが単独でゲーム側に送られる。これもCapsLockをCtrlに入れ替えられないのと同様に、解決方法を見つけられなかった。
Minecraft用に設定しているのは、これだけではないため、全容を・・・いずれGithubに公開しようと思っている。


#リンク
・[[Windows10]US配列の入力切替を Ctrl + Space に変更して楽になった](https://qiita.com/Q_tomoking/items/eedd42c4f2099a9a8542)

・[Nizキーボードのカスタマイズ](https://win-tab.net/acc/niz_keyboard_1801182/)

#いずれは参考にしたいリンク
・[IMEの状態をゲット出来るようになるまでのノンプログラマー的冒険](https://qiita.com/neokix/items/83ac2ac8e1dd405528b0)
・[レジストリをちょさないでHHKBをWindowsで使う](https://qiita.com/844196/items/9fc1cd8470a9ad9c3a69)
Emmetで、ベタ打ちのURLの一覧を一発でリンク付き一覧にする

Emmetで、次のようなベタ打ちのURL一覧を、リンク付きの一覧に一発で整形する方法。
資料などで機械的にURL一覧を作成した場合、テキストのままだと不便なので、HTMLにしてページ一覧にしたい場合などに。

```
https://qiita.com
https://www.facebook.com
https://twitter.com
https://www.google.com
```

このテキストに対して、次のようなAbbreviation（短縮形式）入力をして、展開します。

```
ul>li*>a[href=$#][target=_blank]{$#}
```

これによって、次のようにフォーマットされます。

```
<ul>
	<li><a href="https://qiita.com">https://qiita.com</a></li>
	<li><a href="https://www.facebook.com">https://www.facebook.com</a></li>
	<li><a href="https://twitter.com">https://twitter.com</a></li>
	<li><a href="https://www.google.com">https://www.google.com</a></li>
</ul>
```

target属性を追加する場合は、

```
ul>li*>a[href=$#][target=_blank]{$#}
```

参考ページ：
https://docs.emmet.io/actions/wrap-with-abbreviation/
外に出る経路はDNSのフォワーダ

と思ったけど
http://www.atmarkit.co.jp/ait/articles/1706/23/news042.html
```
　DNSフォワーダとは、自分自身ではDNSの名前解決を行わず、別のフルサービスリゾルバへDNS要求を中継するDNSサーバを指す。
```
なのでローカルから　ping　www.yahoo.co.jp
で
```
C:\Users\fujisan>ping www.yahoo.co.jp

edge.g.yimg.jp [183.79.249.124]に ping を送信しています 32 バイトのデータ:
10.241.0.1 からの応答: 宛先ホストに到達できません。
10.241.0.1 からの応答: 宛先ホストに到達できません。
10.241.0.1 からの応答: 宛先ホストに到達できません。
10.241.0.1 からの応答: 宛先ホストに到達できません。

183.79.249.124 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
```
と引けるようですっ
コマンドラインで翻訳するやつ

`homebrew`からインストールして任意で~~alias登録~~して
コマンドで翻訳を利用可能にする（Shellは`Zsh`を使用）

→ alias登録よりfunctionで設定した方が文章翻訳の際に利便性が高まると思われ
（※ 記述の仕方によってはaliasでもいけるかも）

# 作業
```zsh:インストール
brew install translate-shell
```
<details><summary>**`alias登録`** の例</summary><div>

```zsh:alias登録（「~/.zshrc」末尾に追記される）
echo -e "#translate-shell\nalias te_=\"trans {en=ja}\" #英→日\nalias tj_=\"trans {ja=en}\" #日→英" >> ~/.zshrc
```
```shell:~/.zshrc
#translate-shell
alias te_="trans {en=ja}" #英→日
alias tj_="trans {ja=en}" #日→英
```
```zsh:コマンド例
# 2単語以上のものは（ダブル）クォーテーションで括る

te_ english
te_ "Hello! World."

tj_ 英語
tj_ "こんにちは！世界。"
```
</div></details>


# 複数単語（文章）を翻訳する際にクォートつけるのがめんどい → クォート不要で翻訳できるようにする 
aliasではなく、functionで登録する。
全引数を1つにまとめて渡すようにすればいける

```zsh:
vi ~/.zshrc
```
```shell:~/.zshrc
# コメントアウト
#alias te_="trans {en=ja}" #英→日
#alias tj_="trans {ja=en}" #日→英

# trans 英→日
function te_(){
  [ $# -ge 2 ] && command trans {en=ja} "$*"
  [ $# -eq 1 ] && command trans {en=ja} $1 || echo "No arguments."
}
# trans 日→英
function tj_(){
  [ $# -ge 2 ] && command trans {ja=en} "$*"
  [ $# -eq 1 ] && command trans {ja=en} $1 || echo "引数がありません。"
}
```
```zsh:実行例
te_ boiled of under the hogehoge machine

tj_ ホゲホゲマシンの下のボイル
```

# 課題
シングルクォートを含む文章の場合は、閉じクォートを追加入力するなりで
1発変換実行できないのが現状の欠点
※ 大抵の場合、シングルクォートがなくてもそれなりにちゃんと翻訳はしてくれるっぽい

```zsh:
te_ let's go 
quote> '
```
```zsh:事前エスケープしとけば1発実行できるけど手間
te_ let\'s go 
```

# 参考
>
[コマンドラインでGoogle翻訳をする](https://qiita.com/passionate-engineer/items/1eaa806c857516aea051)
[Translate Shell](https://www.soimort.org/translate-shell/)