OmniAICreator/Qiita-1.07M huggingface dataset:
こんなFizzBuzzも嫌だ

- 偉大なる先駆者へ => https://qiita.com/shinderuman@github/items/e2e6f9b10ff33fed56aa

## 実に嫌すぎるだろ

```php
<?php ($f = function ($i = 1) {echo $i % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;return ++$i;})($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f($f())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
```

## そもそも引数で終端制御するのがイけてなくね？

```php
<?php ($f = function ($f = null, $max = 100) {echo ($i = count(debug_backtrace())) % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;$i === $max ?: $f($f, $max);})($f);
```

## 風味が損なわれている

```php
<?php ($f = function($f, $i = 1, $max = 100) {echo $i % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;$i === $max ?: $f($f, ++$i, $max);})($f);
```

## すげぇお行儀が悪い。散らかしっぱなし。

```php
<?php
($f = function () {echo !ob_start(), ($i = ob_get_level()) % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;})();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
ob_end_flush();
```

## あまりひねくれていない

```php
<?php $f = function() {echo ($i = debug_backtrace()[0]['line'] - 1) % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;};
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
$f();
```
JavaScriptのprototypeチェーンとはなんぞや

# はじめに
JavaScriptのメソッドなんかをググってる時に、よく以下のようなものを見ますよね。

<img width="924" alt="Array_prototype_map___-_JavaScript___MDN.png" src="https://qiita-image-store.s3.amazonaws.com/0/93967/821477c2-f8dc-ce57-e248-b9b48b4eff0a.png">

JSはよくprototypeベースな言語とか言われたりしていますが、prototypeとはなんぞやって疑問に思っていました。
特に今回はその中でも、**prototypeチェーン**に絞っています。

※もし間違いがあれば、指摘していただけると助かりますm(__)m

# すべてのオブジェクトは \_\_proto\_\_ を保持している

以下のコードをブラウザのConsoleなどで実行して見てください。

```js:sample.js
const dog = {}
console.log(dog)
```

生成されたオブジェクトdogの中身をconsole.logで確認すると、**\_proto_**というプロパティが確認できますよね。

<img width="218" alt="良い記事を書くためのガイドライン_-_Qiita_Support.png" src="https://qiita-image-store.s3.amazonaws.com/0/93967/af4b2aa5-baaf-6603-cbe6-3b32135d8afd.png">

結論を先に言いますと、<font color="Red">全てのオブジェクトは、自動的に \_\_proto\_\_ プロパティを保持しています</font>。
ちなみに、 \_\_proto\_\_ プロパティもオブジェクトです。

# \_\_proto\_\_ ってなんなのか

結論を先に言います。
オブジェクトの \_\_proto\_\_ プロパティはコンストラクタ関数のprototypeプロパティを参照している。

以下の画像を見てください。

<img width="257" alt="良い記事を書くためのガイドライン_-_Qiita_Support.png" src="https://qiita-image-store.s3.amazonaws.com/0/93967/6aa4a16d-69c8-c577-be16-db1630aa6b04.png">

\_\_proto\_\_ は、Object.prototypeということがわかります。
これはつまり、dogの\_\_proto\_\_プロパティがObjectコンストラクタ関数のprototypeプロパティのオブジェクトを参照しているということです。

また、コンストラクタ関数は自動的にprototypeプロパティを保持しています。prototypeプロパティはオブジェクトです。

以下のコードで確認しておきましょう。

```js:sample2.js
//コンストラクタ関数Humanを定義
function Human (name) {
  this.name = name;
}

//prototypeオブジェクトに関数をいれる
Human.prototype.hello = function () {
  return this.name + 'さん、こんにちは！';
}

var shin = new Human('shin');
console.log(shin.hello()); //=>shinさん、こんにちは！
```

ちょっと脱線したので、大事なことをまとめます。

|                           |       内容 |   
|:--------------------------|------------------|
| オブジェクト                |全てのオブジェクトは\_\_proto__プロパティを保持している。<br>また、\_\_proto\_\_プロパティはコンストラクタ関数のprototypeプロパティを参照している |
| コンストラクタ関数           |prototypeプロパティを保持している|


# prototypeチェーンとは
まず、言葉で説明します。
prototypeチェーンとは、<font color="Red">オブジェクトに必要なプロパティや関数がない場合、\_\_proto\_\_が参照するコンストラクタ関数のprototypeオブジェクトにさかのぼって探す</font>ことをいいます。

わかりづらいので、コードで見ていきましょう。

```js:sample3.js
//オブジェクトを生成
const str = new String("");

console.log(str.__proto__ === String.prototype); //=>true

console.log(String.prototype.__proto__ === Object.prototype); //=>true

//prototypeチェーンの最終地点
console.log(Object.prototype.__proto__); //=>null
```

ここで重要なのは、prototypeプロパティもオブジェクトであるということです。
つまり、\_\_proto\_\_を保持していることになります。

図で表すと以下のようなイメージですね。

[![Screenshot from Gyazo](https://gyazo.com/2f0d7a75823aeacd8e8540f5d0157f1c/raw)](https://gyazo.com/2f0d7a75823aeacd8e8540f5d0157f1c)

例えば、strに対して定義されていないメソッドやプロパティを呼び出すと、Stringコンストラクタ関数のprototypeプロパティを参照し、それでもなければStringコンストラクタ関数のprototypeオブジェクトが持っている\_\_proto\_\_が最終地点のObjectコンストラクタ関数のprototypeプロパティを参照します。それでもない場合は、Objectコンストラクタ関数のprototypeが持っている\_\_proto\_\_がnullが返却されます。
GPL v3 > 修正コードの公開方法?

GPL v3のコードがある。
https://github.com/squeed/AppleRemoteSender

このままではESP8266では動かない。

ソースを改変して、公開する場合、GPL v3に則り公開することになるのだろう。

1. LICENSE(GPL v3)を用意
2. オリジナルからの変更を明示

2はどこに、どのように、書くのか未消化。

「お客さまの中にGPL v3のコードを修正し、GitHubで公開されている方はおられませんか」状態。

## 例

### 例1. cuckoo-modified

https://github.com/spender-sandbox/cuckoo-modified

README.mdに以下の記載がある。

> This fork aims to continue the work of the heavily modified version of Cuckoo Sandbox provided under the GPL by Optiv, Inc.

docs/にLICENSE (GPL v3)がある。

### 例2. ping.py

https://github.com/paris-ci/CloudBot/blob/d5c7e31a9c474efd69aca0ca5fa0cb0675c491fc/plugins/ping.py

Created By:
と
Modified By:
という書き方。

### 例3. mobs_sandworm

https://github.com/blert2112/mobs_more_monsters/blob/0b92cb849292de9596524a072603a9d684c2cac7/mobs_sandworm/License.txt

Artist/origin:
と
Modifed by:
という記載があるLicense.txtがある。

##　リンク

https://www.gnu.org/licenses/quick-guide-gplv3.ja.html
Fish-nvm で `$(npm bin)/gulp` が動かなくて

`eval (npm bin)/gulp` としたら動いた ~~ので取り敢えずコレで凌ぐか、、微妙な所。
解決方法をご存知の方いたら教えてくださいー（爆~~


※言わずもがなですが `./node_modules/.bin/gulp` でも行けます。

今だと以下のコマンドで同様の事が可能。
※ 間違ってたらご指摘ください🙏

```
npx gulp
# or
yarn gulp
```
Crowiに検索機能を追加する方法

Crowiに検索機能が欲しくなったため、構築済のCrowi1.6に機能を追加する。

## 検証環境
* CentOS 7.4 x64 (Minimal Install)
* Crowi 1.6.2

Crowiのセットアップ方法は以下の記事を参照
https://qiita.com/SkyLaptor/items/f5de5f8528da277abd8f


## セットアップに必要なモジュールのインストール
```shell-session:
# yum install java-1.8.0-openjdk
# rpm -qa | grep java-
java-1.8.0-openjdk-headless-1.8.0.144-0.b01.el7_4.x86_64
java-1.8.0-openjdk-1.8.0.144-0.b01.el7_4.x86_64
```


## Elasticsearchのインストール
```shell-session:
# vi /etc/yum.repos.d/elasticsearch.repo
# yum install elasticsearch
# rpm -qa | grep elasticsearch
elasticsearch-5.6.1-1.noarch
# cd /usr/share/elasticsearch
# bin/elasticsearch-plugin install analysis-kuromoji
# systemctl start elasticsearch
# systemctl enable elasticsearch
```

```bash:elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
```

参考: https://www.elastic.co/guide/en/elasticsearch/plugins/current/installation.html


## Crowiの設定変更
```shell-session:
# vi /etc/sysconfig/crowi
# systemctl restart crowi
```

```bash:/etc/sysconfig/crowi
# 追記
ELASTICSEARCH_URI="http://localhost:9200"
```


## 検索機能の動作確認
Crowiにアクセスし、検索機能が追加されていることを確認する。

![2017-09-22_12h22_28.png](https://qiita-image-store.s3.amazonaws.com/0/97774/64eff8b2-a694-ad04-96a9-7370cc4d778d.png)

なぜかInternetExplorerでは表示されない。ChromeとFirefoxは問題なし。


## 参考
https://qiita.com/bezeklik/items/48fe054c2df05f03f3d1
https://qiita.com/oshuya/items/05883de5cc275d87a7b8
Requests使ってみたメモ

[Requests](http://requests-docs-ja.readthedocs.io/en/latest/)を使った時のメモ

## コード
```py3
import requests

url = 'http://www.ekidata.jp/api/s/1130224.xml'
res = requests.get(url)

# 日本語文字化け対応
res.encoding = res.apparent_encoding

print(res.text)
```

## 出力結果
```
<?xml version="1.0" encoding="UTF-8"?>
<ekidata version="ekidata.jp station api 1.0">
	<station>
		<pref_cd>13</pref_cd>
		<line_cd>11302</line_cd>
		<line_name>JR山手線</line_name>
		<station_cd>1130224</station_cd>
		<station_g_cd>1130101</station_g_cd>
		<station_name>東京</station_name>
		<lon>139.766103</lon>
		<lat>35.681391</lat>
	</station>
</ekidata>
```
Firebase tips(Database rule .2)

# FIREBASE TIPS

## Validate that new record contain specified columns.

```json:database.rule.json
{
  "rules": {
    ".read": true,
    ".write": true,
    ".validate" :  "newData.hasChildren(['id', 'name'])"
  }
}
```

- TEST1
![validate1.png](https://qiita-image-store.s3.amazonaws.com/0/199460/bb8dd311-6a12-2b7e-83fc-c5c260c28974.png)

- TEST2
![validate2.png](https://qiita-image-store.s3.amazonaws.com/0/199460/a1988fde-2620-4f1a-0ca5-6fde5dd6cfbc.png)


## Validate that a member of new record is string value and its length is less than 3 characters.

```json:database.rule.json
{
  "rules": {

    ".read": true,
    ".write": true,
    "key":{
			".validate": "newData.isString() && newData.val().length < 3"
  	}
  }
}
```

- TEST1
![validate1.png](https://qiita-image-store.s3.amazonaws.com/0/199460/87145d38-5d62-0a95-5480-1320a8e4ed65.png)


- TEST2
![validate2.png](https://qiita-image-store.s3.amazonaws.com/0/199460/8c1e4bff-c102-3b17-c83d-1a0f8898f07c.png)

## Validate that a member of new record is string value and its regexp is email format.

```json:database.rule.json
{
  "rules": {

    ".read": true,
    ".write": true,
    "key":{
			".validate": "newData.isString() && newData.val().matches(/^[-a-z0-9~!$%^&*_=+}{\\'?]+(\\.[-a-z0-9~!$%^&*_=+}{\\'?]+)*@([a-z0-9_][-a-z0-9_]*(\\.[-a-z0-9_]+)*\\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,5})?$/i)"
  	}
  }
}
```

- TEST1:
![validate1.png](https://qiita-image-store.s3.amazonaws.com/0/199460/fa547a6e-1fc2-bf97-c31f-03646335fb49.png)

- TEST2:
![validate2.png](https://qiita-image-store.s3.amazonaws.com/0/199460/e123af06-8a77-4ea3-a14f-a4a3f94fe747.png)
Git　Conflict発生！片方のブランチのファイルを強制的に優先とする

普通Conflict発生となったら、新旧両方のファイルを開いて、おとなしく手動でマージするもんですが、どうしても片方のファイルでまるっと上書きしたい時があったりします。  
私が遭遇したのは、以下のような状況です。
1.  fileA.txtをbranchAで作成
2.  masterにbranchAをmerge
3.  masterでfileA.txtを削除
4.  branchAでfileA.txtを修正
5.  branchAをmasterにmergeしようとすると　「fileA.txtはmasterで削除されたファイルです。CONFLICTですよ。」で拒否られる。

...まぁ手違いとはいえ、上のような混乱状況を作った自分が悪いとは言え、masterにはなく、branchAにしかないファイルをどうやってマージするの？単にbranchAのファイルが絶対優先で上書きマージしてほしいだけなのよ。  

以下、そのような場合の手順です。

1. git clone [マスタのURL]                    // まずはリポジトリ取り出します
2. git fetch origin                          //
3. git checkout -b branchA origin/branchA    // branchAも取り出します
4. git checkout master                       // masterに戻って
5. git merge --no-ff branchA                 // これでCONFLICTのワーニング出ます
6. git checkout --theirs fileA.txt           // branchAのほうのfileA.txtが最優先なのだと宣言
7. git add fileA.txt 
8. git commit
9. git push


もしも逆にmaster側のほうが最優先なんだ！って場合は
6. git checkout --ours ..... らしい　けどこっちの操作はやってないので確かなことが言えないです。
Bootstrapで作ったサイトがスマホでめっちゃ小さかった時


自分用メモ。


スマホ用のviewportを設定しないと、モバイル端末ではめちゃ小さくなってしまう。
以下をheadタグ内に記載する。

```
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
```
PHPでリバースプロキシを挟んだアクセス元のIPを取得する方法


ちょっとハマったのでメモ

## はじめに

運営しているサイトで攻撃を防ぐためにWAF製品を導入している。
問題があって、一度WAFを経由してくるためにアクセスしてきたユーザーのIPが変更されてしまってアクセス元のIPが取得できていなかった。

それまではPHPで`$_SERVER['REMOTE_ADDR']`としておけばIPを取得出来ていたのだが、このIPが変換されたものだと気づいたので対処することになった。


X-FORWARD-FORで取得するというのはわかったのだけど、どこのサイトを見ても`httpd.conf`を編集するというのが前提で説明されていた。運営しているサイトのサーバーがXserverだったので、いじれる部分に制限があったために詰まった。結果的に`.htaccess`に書くことで解決できた。

## 手順

`.htaccess`の最終行とかに以下を追記

```
// X-FORWARD-FORを使えるようにする
%{X-Forwarded-For}i
```


アクセス元のIPを取得したいPHPファイルで以下を書く

```PHP
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
	$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
//自分の環境下では以上だと接続元と変換後のIPが取得されていたので、以下のようにexplodeを使って配列にして抜き出す処理を書く
// 取得例："アクセス元IP, 経由後IP"

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
	$_SERVER['REMOTE_ADDR'] = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
}
// explodeを使ってカンマ区切りに分割
//取得例[0] => "アクセス元IP", [1] => "経由後IP"

//なのでアクセス元IPを使いたい時は、添字を入れれば取得出来る
echo $_SERVER['REMOTE_ADDR'][0]

```

全然いい方法ではないかと思うので、ツッコミどころあったらコメントください
Bash on Ubuntu on Windowsを使う(3)：WindowsからLinuxを使う

過去記事の転載
(Creators Update以降とは異なる場合があります)

ヾ(・ω<)ﾉ"　三三三●　ⅱⅲ コロコロ♪

----
------------------- ↓ 余談はここから ↓-------------------
関連記事
* [Bash on Ubuntu on Windowsを使う(1)](https://qiita.com/dozo/items/07ae85ab3937d2ed675a)
* [Bash on Ubuntu on Windowsを使う(2)：初期設定](https://qiita.com/dozo/items/6cbedf3fd057b50d0ada)
* [Bash on Ubuntu on Windowsを使う(3)：WindowsからLinuxを使う](https://qiita.com/dozo/items/ff41ece3771affda8845)
 

インストール最新状態にするのは完了。
あとはWindowsから直接Linuxにアクセスできれば完璧。

基本的にはbashを経由すればなんでもできる。
ん？・・・今なんでもって 

----
------------------- ↓ 本題はここから ↓-------------------

###bashを通してLinuxにアクセス

```
$ bash -c "実行したいコマンド"
```
Bash on Ubuntu on Windowsを使う(2)：初期設定

過去記事の転載
(Creators Update以降とは異なる場合があります)

ヾ(・ω<)ﾉ"　三三三●　ⅱⅲ コロコロ♪

----
------------------- ↓ 余談はここから ↓-------------------
関連記事
* [Bash on Ubuntu on Windowsを使う(1)](https://qiita.com/dozo/items/07ae85ab3937d2ed675a)
* [Bash on Ubuntu on Windowsを使う(2)：初期設定](https://qiita.com/dozo/items/6cbedf3fd057b50d0ada)
* [Bash on Ubuntu on Windowsを使う(3)：WindowsからLinuxを使う](https://qiita.com/dozo/items/ff41ece3771affda8845)
 
インストールはできたので活用していこう。
兎にも角にも日本語表示から。 


----
------------------- ↓ 本題はここから ↓-------------------

###Ubuntuの状態を最新にする

- コマンドプロンプトを起動
- bashと入力
- 以下のコマンドを実行
 
```shell-session
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get autoremove
```

###gitを最新にする

- Ubuntuのバージョンが14なので普通にインストールすると古いバージョンのgitが入る
- そこで、リポジトリを追加して最新のものを取得 
- 以下のコマンドを実行
 
```shell-session
$ sudo apt-get install build-essential
$ sudo add-apt-repository ppa:git-core/ppa
$ sudo apt-get update
$ sudo apt-get install git
$ git --version
git version 2.11.0
```

###phpをインストール

- 以下のコマンドを実行

```shell-session
$ sudo apt-get install php5-cli php5-curl
$ php -v
PHP 5.5.9-1ubuntu4.21 (cli) (built: Feb  9 2017 20:54:58)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
```

###その他インストール(随時追加)

- 以下のコマンドを実行

```shell-session
$ sudo apt-get install unzip
```

----
------------------- ↓ 後書はここから ↓-------------------

###コマンドプロンプトじゃないターミナルを使う

コマンドプロンプトだとターミナルとしてイマイチなので、別のものを用意
 - [cmder](http://cmder.net)
 - [wsltty(minttyのBow版)](https://github.com/mintty/wsltty)
 - [mobaxterm](http://mobaxterm.mobatek.net)

```shell-session
$ scoop install cmder
$ scoop bucket add extra
$ scoop install mobaxterm
```

Scoopのインストールは以下を参照。
[Scoopで作るLinux on Windows開発環境](https://qiita.com/dozo/items/a6f63aa1b03d1773b8ec)


###IDEのターミナルとしてbashを使う
eclipseやphpstormでターミナルを使うときにbashを指定しておくと、
Linuxとして動かせる

- bashのパスを指定する

```
32bit版: c:\windows\sysnative\bash.exe
64bit版: c:\windows\sytem32\bash.exe 
```
Bash on Ubuntu on Windowsを使う(1)

過去記事の転載
(Creaters Update以降とは異なる場合があります)

ヾ(・ω<)ﾉ"　三三三●　ⅱⅲ コロコロ♪

----
------------------- ↓ 余談はここから ↓-------------------

 関連記事
* [Bash on Ubuntu on Windowsを使う(1)](https://qiita.com/dozo/items/07ae85ab3937d2ed675a)
* [Bash on Ubuntu on Windowsを使う(2)：初期設定](https://qiita.com/dozo/items/6cbedf3fd057b50d0ada)
* [Bash on Ubuntu on Windowsを使う(3)：WindowsからLinuxを使う](https://qiita.com/dozo/items/ff41ece3771affda8845)
 




PCがWindows10になったので、
せっかくだからBash on Ubuntu on WIndows(以下、ゼルダじゃない方のBoW)を入れてみる。


----
------------------- ↓ 本題はここから ↓-------------------

###PCを開発者モードに変更

- 「設定(スタートボタンの歯車アイコン)」-「更新とセキュリティ」-「開発者向け」を選択
- 「開発者向け機能を使う」欄の「開発者モード」を選択

![bash on windows01.PNG](https://qiita-image-store.s3.amazonaws.com/0/40697/d4205790-771e-e6b2-a770-e01006b39b63.png)

###追加機能でSubsystem for Linuxを有効化

- 「コントロールパネル」-「プログラム」-「Windowsの機能の有効化または無効化」を選択
-  一覧のなかから「Windows Subsystem for Linux(Beta)」にチェックを入れてOK
-  (2回ぐらい再起動)

![bash on windows02.PNG](https://qiita-image-store.s3.amazonaws.com/0/40697/32767a94-0121-18ab-478c-37f0696126d9.png)

###インストール

- コマンドラインプロンプト起動
- bashと入力
 - "ｙ"と入力するとインストールが始まる。
 - ユーザー名とパスワードを２回入れればインストール完了。


----
------------------- ↓ 後書はここから ↓-------------------
###インストール先

- 本体: C:\Users\[ユーザー名]\AppData\Local\lxss (隠しファイル)
- Cドライブ: /mnt/c

###アンインストール

- コマンドプロンプトを起動
- "lxrun /uninstall /full"と入力
iOS11にしたので、開発環境を更新したメモ

テスト端末iOS11にしたら、XCode8のままデバッグ実行できなくなったので、XCode9に更新したときのメモ。

## MacOSを最新に
トラブル防止のため、最新にしました。（2017年9月21日現在）

* MacOS Sierra 10.12.6
* Safari 11.0
* iTunes 12.7

## XCode9

iTunesStoreの[AppStore](https://itunes.apple.com/jp/app/xcode/id497799835?mt=12)に公開されたので、こちらからダウンロード。

## Carthageの更新
`carthage update`しようとしたら古いって怒られたので、`brew`コマンドでcarthage 0.25.0にアップデートしました。

```
$ brew update
$ brew upgrade carthage
```

プロジェクトの依存ライブラリたちを更新します。

```
$ carthage update --platform iOS
```

~~SwiftyJSONが対応してない…~~
~~`/Users/xxxxx/xxxx/Credit.swift:11:8: Module compiled with Swift 3.1 cannot be imported in Swift 3.2: /Users/xxxxx/xxxx/Carthage/Build/iOS/SwiftyJSON.framework/Modules/SwiftyJSON.swiftmodule/arm64.swiftmodule`~~

~~[試行錯誤](https://stackoverflow.com/questions/44399109/xcode-9-module-compiled-with-swift-3-1-cannot-be-imported-in-swift-4-0/44415247)されてる様子。~~

作業してたterminalの環境変数更新されてなかっただけだった。XCodeインストール後、terminal入り直してやったらいけた。
Macで全角英字を入力する。

たまにサービス名で全角英字を使っているものがあるかと思いますが、
Macで入力するには?となったのでメモ。

## 方法
1. 日本語入力で全角にしたい文字を入力
2. Ctrl + l(小文字のL)

大文字にしたいときは、日本語入力時にShiftを押しながら入力してください。

## 例
### 日本語入力
```
アいウえオ
```
### 変換
```
ＡｉＵｅＯ
```
C++ Builder XE4, 10.2 Tokyo > HWNDの取り方 > リファクタリング対応

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
```

### はまったこと

1. HWND型変数にFindWindowEx()にて値を代入
2. その対象となるフォームの名前を変更した (xxxFormからFormXXX)
3. HWND型変数がNULLになる
4. NULLのまま処理をされ、別の処理でのNULLチェックにひっかかりエラーが出た

### 希望

フォーム名を変更した時に、ビルド処理でエラーの原因を明示したい。

### 実装

- 構成
    - Form1 (Unit1.cpp)
    - Form2 (Unit2.cpp)

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// Case 1
	String fullCaption = L"Form2";

	HWND subHwnd = FindWindowEx(NULL, NULL, NULL, fullCaption.c_str());
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
	// Case 2
	String fullCaption = Form2->Caption;

	HWND subHwnd = FindWindowEx(NULL, NULL, NULL, fullCaption.c_str());
}
//---------------------------------------------------------------------------
```

上記のCase 2にすることで、「フォーム名の変更時」にビルドエラーが出てくれ、間違いに気づきやすい。

### pros and cons

- Case 1
    - 利点: `#include "Unit2.h"`が不要
    - 欠点: フォーム名変更時に失敗に気づきにくい
- Case 2
    - 利点: フォーム名変更時に失敗に気づく
    - 欠点: `#include "Unit2.h"`が必要
        - 依存関係が生まれるが、Form2のコンポーネントを使っている時点で依存関係はある
        
### 備考

~~FindWindowEx()を使わずにForm2からHWNDを取る方法はあるかもしれない（未調査)~~。

### Case 3

Case 2の処理は以下でよかった。

```Unit1.cpp
void __fastcall TForm1::Button3Click(TObject *Sender)
{
	// Case 3
	HWND subHwnd = Form2->Handle;
}
```

FindWindowEx()は不要。
[Xcode9] ipaをAppStoreにあげた後にAppleからメールが来て突き返された

## 送られてきたもの
Xcode9で初めてAppStoreにipaをあげました。アップロード自体は成功したんですが、Appleから以下のメールが届きました。

>Invalid Bundle - Disallowed LLVM instrumentation. Do not submit apps with LLVM profiling instrumentation or coverage collection enabled. Turn off LLVM profiling or code coverage, rebuild your app and resubmit the app.

なるほど、`LLVM Profiling Instrumentation`がAppにくっついているか、`coverage colllection`が有効になったままだよって言ってるっぽいです。

## 対処方法
前提として、今回作っていたプロダクトでは`Carthage`と`CocoaPods`を使ってました。各自の状況に合わせて読んでください。

まず、開発しているプロダクトの`Build Settings > Apple LLVM 9.0 Code Generation > Enable Code Coverage Support`の項目を見てください。`YES`になっている場合はここを`NO`にします。私はひとまず`Release`環境のみNOにしておきました。

`CocoaPods`を使っている方は、Podsでも上記と同様の設定をします。

`Carthage`を使っている方は、`Build Settings`がないのでちょっと手順が変わります。ちなみに[こちら](https://stackoverflow.com/questions/46160518/xcode-9-carthage-itunes-connect-error-invalid-bundle-disallowed-llvm-instr)を参考にしました。

1. terminalを開いてプロジェクトルートに行く
2. `carthage update --platform iOS --no-use-binaries --no-build`を叩いて、コンパイルが始まったら`ctrl+C`でキャンセル
  - （これなんで必要なのかわからない）
3. `grep -lR "codeCoverageEnabled" --include *.xcscheme --null Carthage | xargs -0 sed -i '' -e 's/codeCoverageEnabled = "YES"/codeCoverageEnabled = "NO"/g'`を叩く
  - Carthage内の各プロジェクトの`codeCoverageEnabled`を`NO`にしている様子
4. `carthage build --platform iOS`を叩いて完了を待つ
5. ビルドが通るか確認する

私の場合、以上を実施後、もう一度ArchiveしてAppStoreにあげればAppleは何も言ってこなくなりました。

そのうちCarthageがアップデートされて解決しそうですが、念のため書いておきました。
bxSlider バグで困ったの巻

自由にjQueryバージョン選択できない案件。
自分が追加した以外のスクリプトも既存で読み込まれているのでbxSliderが悪いと言っているわけではない。


##組み合わせ
bxslider 4.1.2
jQuery 1.8.2

###症状
次へボタン押下時の挙動がおかしい。スライドが戻ったりする。


##組み合わせ
bxslider 4.2.5
jQuery 1.8.2

###症状
次へボタン連打すると動作がフリーズする（いや、そんなことするなよ）


##どうしよう
さくっと解決できる情報も見当たらない上に、組み合わせを試すのも面倒なので別のスライダーで実装すべきだろうか
httpでアクセスしたいのにhttpsへリダイレクトされて悩んだ（HSTSまたはStrict-Transport-Securityの沼）

解決まで時間がかかったので自分への戒めとして残しておく

#[事象]
* httpでアクセスしたいのにhttpsでのアクセスにリダイレクトする
* `ERR_SSL_PROTOCOL_ERROR`とブラウザに言われる  
これはSSLに対応していないサーバにhttpsでアクセスしたため

#[ポイント]
サーバにSSLの設定はしていない
アプリケーションでもリダイレクトの設定はしていない
でもhttpsになる。。。

#[原因]
レスポンスヘッダで以下を返却していることで
そのドメインではブラウザがhttpsでアクセスするように求めていると理解する

```
Strict-Transport-Security:max-age=315360000; includeSubDomains
```

`includeSubDomains`があることで、サブドメインまで対象となる。

#[解決方法]
ブラウザにセットされたHSTSのリストから、該当するドメインを削除する。
<font color="red">注）サブドメインだけを削除することはできなかった</font>
*Chrome*
1. アドレスバーに`chrome://net-internals/#hsts`を入力
2. `Delete domain`に削除したいドメインを入力して`Delete`ボタン押下

*Firefox*
1. 履歴リストを表示する
　方法は２つ
　履歴メニューから`すべての履歴を表示`を選択
　画面でMac（cmd+Shift+H）、Win（Ctrl+Shift+H）を入力
2. 削除したいドメインをみつけたら、右クリックして`このサイトの履歴を消去`

*ALL*([<font color="red">自身では未検証</font>](https://developer.mozilla.org/ja/docs/Web/Security/HTTP_Strict_Transport_Security))
1. 削除したいドメインのWWWサーバにレスポンスヘッダで以下を返すように設定
`Strict-Transport-Security:max-age=0; includeSubDomains`
2. 1のWWWサーバへブラウザでアクセス


[参考]
[http のリクエストが勝手に https にリダイレクトされるときは Strict-Transport-Security を疑おう](http://beniyama.hatenablog.jp/entry/2014/11/08/175925)
[Re-Hashed: How to clear HSTS settings in Chrome and Firefox](https://www.thesslstore.com/blog/clear-hsts-settings-chrome-firefox/)
[MDN web docs(HTTP Strict Transport Security)](https://developer.mozilla.org/ja/docs/Web/Security/HTTP_Strict_Transport_Security)
【macOS】ホームディレクトリ変更できない問題は再起動で解決できた

環境：macOS Sierra 10.12.6

### ホームディレクトリがなぜか/Users/hogeになっている

新しいmacがきたので環境構築しようと思ったらなぜかホームディレクトリ(~)が`/Users/hoge`になっている。

```
$ ~
-bash: /Users/hoge: No such file or directory
```

!?

### 結論：再起動したら解決

はい、再起動したらちゃんと

```
$ ~
-bash: /Users/ユーザ名: is a directory
```

になってました。


### 補足1：ホームディレクトリの確認

ホームディレクトリの確認方法は[こちら](https://support.apple.com/ja-jp/HT201548)の『アカウント名とホームフォルダ名を変更する』を参考に。ホームフォルダ=ホームディレクトリのようです。

見てみるとちゃんと`/Users/ユーザ名`になっていて、でもターミナルでは

```
$ ~
-bash: /Users/hoge: No such file or directory
```
……
謎。ということでひとまず再起動したら`/Users/hode`ではなく`/Users/ユーザ名`になってくれてました。

### 補足2：usermodは使えない

linuxコマンドの`usermod`なら簡単にホームディレクトリを変更できるようなのですが、macOSでは使えないようで…
代わりに`dscl`コマンドなるものがあるそうなのですが、ググってもアカウント追加の話ばかり出てきたので、結局補足1の方法で解決しました。
[OSX][Swift]変更したviewのサイズがデバッグ時に反映されない場合にやること

## 事象
Storyboardで変更したはずのviewのサイズがデバッグ時に反映されない。

## 対処
Xcodeの「DerivedData」を削除後、再度デバッグすると変更が反映される。

## DerivedData 格納場所
~/Library/Developer/Xcode/DerivedData

## 参考
https://stackoverflow.com/questions/31575217/setting-the-initial-window-size-of-an-app-on-os-x
ロードを高速化するprefetch

本記事は、[こちらの記事](https://www.sitepoint.com/lightning-fast-websites-prefetching/)を参考にまとめています。

## Prefetchとは

ユーザーが次に訪問するページを開発者がわかっている場合、次のページの準備しておいたら早くない？みたいな。前もって準備できるものはしておく、そうすれば処理早いよね、要は先読みするってこと。

ここでは、先読みする3つの方法があります。
- DNS Prefetching
- Link Prefetching
- Page Prefetching / Prerendering

## DNS Prefetching

DNSとは、ホスト名をIPアドレスに変換するプロトコル。いわゆる名前解決と呼ばれる仕組み。例えば、ページの中にFacebook/Twitterウィジェット、google analyticsなど、外部URLからリソースを取得する要素がある場合、ブラウザはdocumentの上部から解釈し、外部URLを見つけた時点で外部URLへリクエストを送ります。この時に、前もって名前解決を済ませておけば、どこにリクエストするのかがわかっているから処理するのが早いよね、ってこと。

対応していないブラウザは`dns-prefetch`の記述は無視されるため、記述していても害はない。

```html
<link rel="dns-prefetch" href="//somewidget.example.com">
```

[対応ブラウザ](http://caniuse.com/#search=dns-prefetch)

## Link Prefetching

ユーザーが次に訪問する可能性が高いページを開発者がわかっている場合、リソースを前もって取得しておくことができる。ただし、JSやCSSなどキャッシュ可能なリソースに限られる。

現在ページのリソースをダウンロードしている最中に、指定した次のページで使用するリソースもダウンロードされるため、現在ページのリソースの表示速度に影響するかは要調査。

```html
<link rel="prefetch" href="//example.com/future-image.jpg">
```

[対応ブラウザ](http://caniuse.com/#search=prefetch)

## Page Prefetching / Prerendering 

指定したページのCSSを読み込み、JSを実行、ページ全体の不可視バージョンを作成する。効果の程は要調査。

```html
<link rel="prerender" href="//example.com/future-page.html">
```

[対応ブラウザ](http://caniuse.com/#search=prerender)

## 参考サイト
[https://www.sitepoint.com/lightning-fast-websites-prefetching/](https://www.sitepoint.com/lightning-fast-websites-prefetching/)
[https://www.suzukikenichi.com/blog/dns-prefetching/](https://www.suzukikenichi.com/blog/dns-prefetching/)
Dockerで必要十分なNodejs+PostgreSQLの環境を作る方法

Docker-composeを使い、PostgreSQLに接続するNodeJsアプリケーションの環境構築方法を説明します。
また、Dockerで難しい永続化されるファイル、されないファイルの違いを確認する事も出来ます。

成果物は以下の通り。手っ取り早く確認したい人もこちら
https://github.com/fushihara/docker-pgsql/tree/qiita-1

linuxで以下のコマンドを入力

```shell-session
$ git clone https://github.com/fushihara/docker-pgsql.git
$ cd ./docker-pgsql
$ git checkout qiita-1
$ docker-compose up -d
```
その後、対象マシン上で以下のURLを開く http://localhost:20006/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/e6973ce6-2de8-2d4e-13b0-96b1e6b304fa.png)

サーバー部分はnodejsのexpress、アクセスログはpostgresqlを使用しています。サーバー部分はcronで定期的なジョブが実行されています。ファイル永続化の部分はdocker-compose.ymlでvolumesの項目の指定方法の違いです。

---

最終的なDocker関連のファイルは以下の通り

```yml:docker-compose.yml
version: '2'
volumes:
    vl:
        driver: 'local'

services:
  pgsql_aaa:
    build: ./pgsql/
    restart: always
  nodejs_xxx: 
    build: .
    ports: 
      - "20006:20006"
    volumes:
      -    /usr/src/sample-node/node_modules
      -  .:/usr/src/sample-node
      -    /usr/src/volume-a/
      - vl:/usr/src/volume-b/
    depends_on: 
      - pgsql_aaa
    restart: always
```

```:Dockerfile
FROM node:8.5.0
ENV TZ=Asia/Tokyo
ENV APP_ROOT /usr/src/sample-node
RUN groupadd -g 500 ec2-user && useradd -g ec2-user -u 500 --create-home ec2-user

COPY . $APP_ROOT
RUN chown -R ec2-user:ec2-user $APP_ROOT
RUN mkdir /usr/src/volume-a && chown -R ec2-user:ec2-user /usr/src/volume-a
RUN mkdir /usr/src/volume-b && chown -R ec2-user:ec2-user /usr/src/volume-b

USER ec2-user
WORKDIR $APP_ROOT
RUN npm install

ENTRYPOINT ["npm","start"]
```

docker-compose.ymlでの`pgsql_aaa`や`nodejs_xxx`は`docker ps`等で識別しやすくするための表記です。

Volumeについて。

- /tmp/test.txtは設定ファイルに記載が無いので、Dockerで**何も指定しない**場合の挙動となります。
- /usr/src/volume-a/test.txt は`docker-compose.yml`で`/usr/src/volume-a/`とだけ指定されています。正直、この場合は何も指定していない/tmp/test.txtとの**違いが分かりませんでした**。(ハイライトしていませんが、すぐ上の`/usr/src/sample-node/`では指定する意味があります)
- /usr/src/volume-b/test.txtは`docker-compose.yml`で`vi:/usr/src/volume-b/`と書かれており、viというのは別の箇所でも指定されています。この表記ですと、上記の二つよりデータが消える場合が少なくなります。データボリュームの名前が固定されるので、コンテナを作り直してもデータが引き継がれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/ae27a23c-e428-9c9b-0238-88f3d445d6a5.png)

最低限これさえ把握していれば、自分で作る分の簡単なツールは不自由なく作れると思います
MySQLクエリチューニング　〜SHOW PROFILEを試す〜

# 再現性のあるスロークエリには `SHOW PROFILE` を試してみよう

MySQLサーバ組み込みプロファイラから情報を取り出すためのステートメント
使えるかどうかはビルドオプション( `cmake - DENABLED_PROFILING=ON` )を有効にすれば使用可能
`EXPLAIN` 上問題ないが、クエリの遅さに再現性がある場合に有効な場合がある
準備
以下のどちらかを実行すればプロファイラーが有効になる

```sql
SET SESSION profiling = 1

# もしくはこっち
SET @@profiling = 1
```

MySQL5.6から非推奨になっており、今後削除される可能せいのある機能なため、以下のようにwarningが出る

```sql
show warnings;
```

## 出力結果
Level    Code    Message
Warning    1287    '@@profiling' is deprecated and will be removed in a future release.
利用方法
クエリを叩いた後に以下のクエリを流すだけ

```sql
SHOW PROFILE;

# 出力結果
Status    Duration
starting    0.000076
checking permissions    0.000010
Opening tables    0.000026
init    0.000030
System lock    0.000014
optimizing    0.000010
statistics    0.000021
preparing    0.000032
executing    0.000003
Sending data    0.000299
end    0.000012
query end    0.000038
closing tables    0.000013
freeing items    0.000123
cleaning up    0.000037
```
これはそれぞれどの実行で時間がか方かを示している。

読み方

上から順番に実行されており、どこにどれだけ時間がかかったかがわかる。 `sending data` ストレージエンジンからデータをフェッチする時のステータスなので、ここに一番時間がかかっていることがわかる
C#でscreenをcaptureしてsaveする。


```C#
using System;
using System.IO;
using System.Windows;

namespace CaptureScreen
{
    class Capture
    {
        /// <summary>
        /// screenをcaptureしてsaveする。
        /// </summary>
        /// <param name="startpoint">開始点</param>
        /// <param name="size">サイズ</param>
        /// <param name="savefolder">保存フォルダorFullpath</param>
        /// <param name="savename">ファイル名(Fullpathを指定するときは空)</param>
        /// <returns></returns>
        public static string CaptureScreen(Point startpoint, Size size, string savefolder, string savename = "")
        {
            //保存パス生成
            string executeTime = (DateTime.Now.ToString("yyyy_MMdd_HHmmss_ffff"));
            string file = savefolder.TrimEnd('\\') + @"\" + executeTime + savename;
            try
            {
                // 保存するBitmap(handWrite)
                var bitmap = new System.Drawing.Bitmap(
																		(int)size.Width,
																		(int)size.Height,
																		System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                try
                {
                    using (var g = System.Drawing.Graphics.FromImage(bitmap))
                    {
                        g.CopyFromScreen(
                            (int)startpoint.X,
                            (int)startpoint.Y,
                            0,
                            0,
                            bitmap.Size,
                            System.Drawing.CopyPixelOperation.SourceCopy);
                    }
                }
				catch (Exception exception) {
					string error = savefolder + file + exception.Message;
				}

				//fullpathを指定した場合。
				if (savename == "")
                {
                    file = savefolder;
                    savefolder = Path.GetDirectoryName(savefolder);
                }

                if (!Directory.Exists(savefolder))
                    Directory.CreateDirectory(savefolder);

                try
                {
                    bitmap.Save(file, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch (Exception exception)
                {
                    string error = savefolder + file + exception.Message;
                }
                bitmap.Dispose();
            }
			catch (Exception exception) {
				string error = savefolder + file + exception.Message;
			}
            return file;
        }
    }
}
```
vim コマンド集

vimのコマンドをまとめておく。
[ここ](https://github.com/ktoyod/initfiles/blob/master/.vimrc)の`.vimrc`を設定した場合のコマンド集。

一部プラグインを用いているのでリンク先を参照していただければ。
プラグイン管理には`dein.vim`を使っている。

https://github.com/Shougo/dein.vim

設定方法に関しても書いているがかなり前のものなので動くか怪しい...（一応以下にリンク）

https://qiita.com/ktoyod/items/94f74a680c2cc6a65709

# モード

|モード| コマンド      | 挙動 |
|:--:|:-----------------:|:------------------|
|インサートモード| a             | カーソルの右側にインサートモード |
|| i  | カーソルの位置からインサートモード |
|| A  | 行末に移動しインサートモード |
|| I  | 行頭に移動しインサートモード |
|| o  | 現在の行の下に改行しインサートモード |
|| cc | １行を削除してインサートモード |
|ビジュアルモード| v | ビジュアルモードへ |
|| Ctrl + v | 矩形選択のビジュアルモードへ |
|| V | カーソルがある行を選択してビジュアルモード |
| その他 | ESC | コマンドモードに戻る |
|| Ctrl + l | コマンドモードに戻る |
|| Ctrl + z | vimを一時停止する |

# 移動

| コマンド      | 挙動 |
|:-----------------:|:------------------|
| j | 下に移動 |
| k | 上に移動 |
| h | 左に移動 |
| l | 右に移動 |
| w, W | 次の単語の先頭に前進 |
| b, B | 現在の単語もしくは前の単語の先頭に後退 |
| e, E | 単語のendまで前進 |
|| ※大文字: ドットやコロンのような記号も一続きの単語とみなして移動 |
| H | ウィンドウ内の一番上の行に移動 |
| M | ウィンドウ内の真ん中の行に移動 |
| L | ウィンドウ内の一番下の行に移動 |
| gg | ページの先頭に移動 |
| G | ページの最後に移動 |
| "数字"G, :"数字" | "数字"行に移動 |
| zz | 現在のカーソル位置を中央となるように画面がスクロール |
| zt | 現在のカーソル位置が一番上となるように画面がスクロール |
| Ctrl + u | 半画面分戻る |
| Ctrl + d | 半画面分進む |
| Ctrl + b | １画面分戻る |
| Ctrl + f | １画面分進む |
| ^, O | 行頭へ移動 |
| $ | 行末へ移動 |
| % | 対応するカッコに移動 |
| Ctrl + o | 古いカーソル位置に戻る |
| Ctrl + i | 新しいカーソル位置に進む |
| f"文字" | カーソルがある行の"文字"に移動 |
| F"文字" | カーソルがある行の"文字"に移動（逆向き） |

# 削除
| コマンド | 挙動 |
|:--:|:--|
| dd | カーソルがある行を削除 |
| :"行番号"d | 特定の行を削除 |
| "数字"dl | "数字"文字削除 |
| diw | カーソル上の単語を削除 |
| di" | ダブルクウォーテーションの内部を削除 |
| dit | HTMLタグの内部を削除 |
| ciw | カーソル上の単語を削除してインサートモード |
| ci" | ダブルクウォーテーションの内部を削除してインサートモード |
| cit | HTMLタグの内部を削除してインサートモード |
| x | １文字削除 |
| D | カーソル位置から行末まで削除 |
| C | カーソル位置から行末まで削除してインサートモード |

# undo&redo

| コマンド | 挙動 |
|:---:|:--|
| u | udno |
| Ctrl + r | redo(undoをundo) |

# コピー＆ペースト
| コマンド | 挙動 |
|:--:|:--|
| yy | 今いる行をコピー（ヤンク） |
| "数字"yl | "数字"文字だけコピー（ヤンク） |
| yiw | カーソル上の単語をコピー |
| yi" | ダブルクウォーテーションの内部をコピー |
| yit | HTMLタグの内部をコピー |
| p | カーソルに下にヤンクした行をペースト |
| "数字"p | カーソルの下にヤンクした行を"数字"行追加する |

# 検索と置換

| コマンド | 挙動 |
|:---:|:----|
| * | カーソル下の単語を検索 |
| # | カーソル下の単語を検索（上方向に検索） |
| /"文字" | "文字"を検索する。(本来は:%s/"hoge"/&/gnで検索) |
| :%s/hoge/huga/g | 単語の置換（hogeをhugaへ置換）。/と打てば:%s//&/gnと出てくる。 |

# ウィンドウ&タブ

以下の設定を`.vimrc`などに書くことで画面分割が手軽に行えるようになる

```vimscript
nnoremap sv :<C-u>vs<CR>
nnoremap ss :<C-u>sp<CR>
nnoremap st :<C-u>tabnew<CR>
nnoremap sn gt
nnoremap sp gT
nnoremap sq :<C-u>q<CR>
```

| コマンド | 挙動 |
|:--:|:--|
| sv | 画面を左右に分割する |
| ss | 画面を上下に分割する |
| st | 新しいタブを開く |
| sn | 次のタブに移動 |
| sp | 前のタブに移動 |
| sq | タブを閉じる |

# バッファ

| コマンド | 挙動 |
|:--:|:--|
| :buffes | 編集中のバッファ一覧を表示 |
| :bn | 次のバッファに移動 |
| :bd[elete] | バッファを削除 |

# ファイル関連
| コマンド | 挙動 |
|:--:|:--|
| sq | 閉じる |
| :w | 保存 |
| :q | 閉じる |
| :q! | 強制終了 |
| :e "file name" | "file name"を開く |

# その他
https://github.com/preservim/nerdtree

https://qiita.com/jnchito/items/5141b3b01bced9f7f48f

| コマンド | 挙動 |
|:--:|:--|
| Ctrl + n | ツリーを表示 |
Python で Domo のデータセットのデータをイクスポートする

Domo の データを CSV に出力します。
データセットは、dataset_id で決めます。

アクセストークンを取得するプログラムは、こちらです。
[Python で Domo の アクセストークンを取得する](https://qiita.com/ekzemplaro/items/91ddb8a19f3ec861666f)

```py3
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	main_export_dataset.py
#
#					Sep/22/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
from domo_config import domo_config_proc
from get_access_token import get_access_token_proc
from export_dataset import export_dataset_proc
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
config = domo_config_proc()
access_token = get_access_token_proc(config)
#
dataset_id="4e7a793f-21d1-4afb-8d87-915267f7cf8g"
#
sys.stderr.write("*** check *** ppp ***\n")
#
#
str_csv = export_dataset_proc(access_token,dataset_id)
#
print(str_csv)
#
sys.stderr.write("*** 終了 ***\n")
#
# ------------------------------------------------------------------
```

```py3:export_dataset.py
# -*- coding: utf-8 -*-
#
#	export_dataset.py
#
#					Sep/21/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
# ------------------------------------------------------------------
def export_dataset_proc(access_token,dataset_id):
	sys.stderr.write("*** export_dataset_proc *** start ***\n")
	headers = {"Authorization": "Bearer " + access_token,
			"Accept": "text/csv"
		}
	params = {
		"includeHeader": "true",
		}
#
	url_datasets="https://api.domo.com/v1/datasets/" + dataset_id + "/data"
#
	try:
		rr=requests.get(url_datasets,params=params,headers=headers)
		print(rr.status_code)
		sys.stderr.write(str(rr.status_code) + "\n")
	except Exception as ee:
		sys.stderr.write(str(ee) + "\n")
#
	sys.stderr.write("*** export_dataset_proc *** end ***\n")
#
	return rr.text
# ------------------------------------------------------------------
```

API の仕様はこちら
[Export data from DataSet](https://developer.domo.com/docs/dataset-api-reference/dataset#Export%20data%20from%20DataSet)
Python で Domo のデータセットにデータをインポートする

こちらで作成したデータセットにデータをインポートします。
[Python で Domo のデータセットを作成する](https://qiita.com/ekzemplaro/items/5b772b95e120e1e6dd3c)

```py3
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	main_import_dataset.py
#
#					Sep/22/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
from get_access_token import get_access_token_proc
from import_dataset import import_dataset_proc
from domo_config import domo_config_proc
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
config = domo_config_proc()
access_token = get_access_token_proc(config)
#
dataset_id="4e7a793f-21d1-4afb-8d87-915267f7cf8g"
#
file_csv="cities.csv"
#
json_str = import_dataset_proc(access_token,dataset_id,file_csv)
print(json_str)
#
sys.stderr.write("*** 終了 ***\n")
#
# ------------------------------------------------------------------
```

```py3:import_dataset.py
# -*- coding: utf-8 -*-
#
#	import_dataset.py
#
#					Sep/21/2017
#
# ------------------------------------------------------------------
import	sys
import	requests
#
from file_io import file_to_str_proc
#
# ------------------------------------------------------------------
def import_dataset_proc(access_token,dataset_id,file_csv):
	sys.stderr.write("*** import_dataset_proc *** start ***\n")
	headers = {"Authorization": "Bearer " + access_token,
			"Content-Type": "text/csv"
		}
	params = {
		"includeHeader": "true",
		}
#
	url_datasets="https://api.domo.com/v1/datasets/" + dataset_id + "/data"
#
	str_csv = file_to_str_proc(file_csv)
	str_csv = str_csv.encode('utf-8')
#
	try:
		rr=requests.put(url_datasets,params=params,data=str_csv,headers=headers)
		print(rr.status_code)
		sys.stderr.write(str(rr.status_code) + "\n")
	except Exception as ee:
		sys.stderr.write(str(ee) + "\n")
#
	sys.stderr.write("*** import_dataset_proc *** end ***\n")
#
	return rr.text
# ------------------------------------------------------------------
```

```csv:cities.csv
t1271,千葉,40178,2003-9-21
t1272,勝浦,40215,2003-10-15
t1273,市原,80654,2003-6-14
t1274,流山,70251,2003-9-9
t1275,八千代,42516,2003-8-4
t1276,我孫子,35987,2003-1-21
t1277,鴨川,81256,2003-7-23
t1278,銚子,29374,2003-10-26
t1279,市川,85613,2003-2-17
```


アクセストークンを取得するプログラムは、こちらです。
[Python で Domo の アクセストークンを取得する](https://qiita.com/ekzemplaro/items/91ddb8a19f3ec861666f)

API の仕様はこちら
[Import data into DataSet](https://developer.domo.com/docs/dataset-api-reference/dataset#Import%20data%20into%20DataSet)
Spotifyで再生中の曲をtmuxのステータスバーに表示する

## はじめに
macOS版のSpotifyアプリがAppleScript APIを持っていることを知ったので、試しにtmuxのステータスバーに再生中のトラック情報を表示するようにしてみました。

## 試した環境
* macOS Sierra 10.12.6
* AppleScript 2.5
* Spotify 1.0.63.617
* tmux 2.5

## 手順
* 任意のパスに以下のスクリプトファイルを配置します。今回は `~/bin/get-currently-playing-track-on-spotify` としました。実行権限もつけておいてください。

```applescript:~/bin/get-currently-playing-track-on-spotify
#!/usr/bin/osascript

if application "Spotify" is running
  tell application "Spotify"
    if (player state as string) is "playing" then
        set nowPlaying to "♫ "
    else
        set nowPlaying to ""
    end if
    set currentArtist to artist of current track as string
    set currentTrack to name of current track as string
    return nowPlaying & currentArtist & " - " & currentTrack
  end tell
else
  "Spotify is not running."
end if
```

* .tmux.confのstatus-rightに追加します。

```~/tmux.conf(抜粋)
set -g status-right ' #(~/bin/get-currently-playing-track-on-spotify) ...'
```
※参考までに私のtmux.confです。
[osx-provisioner/.tmux.conf at master · j-un/osx-provisioner](https://github.com/j-un/osx-provisioner/blob/master/roles/dotfiles/files/.tmux.conf)

* tmuxをリロードします。

## 結果
* Spotifyで曲を再生すると、ステータスバーにトラック情報が表示されます。
<img width="539" src="https://qiita-image-store.s3.amazonaws.com/0/92629/90a03616-8a59-caf0-79e6-857b453dc2ff.png">
<br>

* 再生を停止すると♫が消える滋味あふれる演出。
<img width="539" src="https://qiita-image-store.s3.amazonaws.com/0/92629/ec5f7e0f-89ee-0499-83ff-1a9636c75c9f.png">
<br>

* Spotifyアプリが起動していない時。いらないかな。
<img width="539" src="https://qiita-image-store.s3.amazonaws.com/0/92629/6a440bbf-0765-81ec-6302-fddad212773a.png">


## 補足と雑記
* 詳細なリファレンスは、スクリプトエディタで以下の方法で参照できます。
`スクリプトエディタ　- ファイル - 用語説明を開く - Spotify`

* このままだと曲名が長い時にステータスバーが見切れちゃうので、ある程度の文字数を超えたら切り捨てたりしたほうがいいかもしれません。

## 参考文献
[AppleScript API - Spotify Developer](https://developer.spotify.com/applescript-api/)
文字列関数のテストのために文字を直積で生成する


## 概要

文字列関数をテストするとき、文字を構成するバイトの範囲をもとにすべての文字を生成することが必要になります。直積を使えば、重点的にテストしたい範囲の組み合わせをピックアップして文字を生成することができるので、負荷を減らすことができます。

## itertools.product

`itertools.product` を使う方法がもっとも手軽です。例題として UTF-8 の「あいう」のバイト列を調べてみましょう。

```python
>>> 'あいう'.encode()
b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
```

1バイト目が 0xe3、2バイト目が 0x81、3バイト目が 0x82 から 0x86 の範囲にあります。

バイト列の組み合わせを調べてみましょう。それぞれの組み合わせはタプルであらわされます。

```python
>>> import itertools
>>> [tuple(map(lambda a: hex(a), t)) for t in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
[('0xe3', '0x81', '0x81'), ('0xe3', '0x81', '0x82'), ('0xe3', '0x81', '0x83'), ('0xe3', '0x81', '0x84'), ('0xe3', '0x81', '0x85'), ('0xe3', '0x81', '0x86')]
```

数値の組み合わせを文字に変換してみましょう。バイト列を生成するのにタプルをリストに変換して `bytes` に渡します。

```python
>>> [bytes(list(e)).decode() for e in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う']
```

次のようにシーケンスのアンパックも利用できます。

```python
>>> [bytes([*e]).decode() for e in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
```

Python 3.5 から `%` はバイト型に対応しました (PEP 461)。bytes.format (PEP 460)の提案もありましたが、却下されました。

```python
>>> [(b'%c' * len(e)  % e).decode() for e in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う']
```

16進数文字列から変換する方法を選ぶのであれば、`bytes.fromhex` を使います。

```python
>>> [bytes.fromhex(('{:x}'*len(t)).format(*t)).decode() for t in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う']
```

`bytes.join` を使うこともできます。

```python
>>> [b''.join(map(lambda a: a.to_bytes(1, byteorder='big'), t)).decode() for t in itertools.product([0xe3], [0x81], range(0x81, 0x87))]
['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う']
```

## リスト内包表記

リスト内包表記を入れ子にすることでも直積をつくることができます。

```python
>>> lists = [[0xe3], [0x81], range(0x81, 0x87)]
>>> [e for e in [(a, b, c) for a in lists[0] for b in lists[1] for c in lists[2]]]
[(227, 129, 129), (227, 129, 130), (227, 129, 131), (227, 129, 132), (227, 129, 133), (227, 129, 134)]
```

文字を生成してみましょう。

```python
>>> [bytes(list(e)).decode() for e in [(a, b, c) for a in lists[0] for b in lists[1] for c in lists[2]]]
['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う']
```


## 往復変換が保障されない文字を調べる

cp932 の文字のうち utf-8 との往復変換で変わってしまうものを表示させてみましょう。マイクロソフトの[サイト](https://support.microsoft.com/ja-jp/help/170559/prb-conversion-problem-between-shift-jis-and-unicode)でリストが公開されているので、テストデータの参考にすることができます。

```python
import itertools
import unicodedata

def check(l, enc):
    count = 0
    for t in itertools.product(*l):
        c = bytes(list(t))
        u = c.decode(enc, 'replace')

        if len(u) == 2 or ord(u) == 0xfffd:
            continue

        ret = u.encode(enc, 'replace')

        if c != ret:
            print(
                c.hex(), '->',
                'U+'+format(ord(u), 'x'),
                '->', ret.hex(),
                u, unicodedata.name(u)
            )
            count += 1

    print('cp932 unsafe:', count)


l = [range(0x87, 0xfb), range(0x40, 0xff)]
enc = 'cp932'

check(l, enc)
```
こんなFizzBuzzは嫌だ

- 嫌すぎるだろ
- 追記: [gist](https://gist.github.com/shinderuman/4b83845b290bdca47dd840559076bb3d)の方が行番号出てわかりやすいです 

```php
<?php ($f = function($i) {echo $i % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;})(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);

```
pip install cryptographyができない時の対処法

# 環境
- macOS Sierra 10.12.6
- Homebrew
    - `OpenSSL 1.0.2l`と`1.1.0f`がインストール済み
- fish

# 対処法
以下を実行すればいい

```
env LDFLAGS="-L /usr/local/opt/openssl/lib" CFLAGS="-I /usr/local/opt/openssl/include" pip install cryptography
```

というのも[ここ](https://cryptography.io/en/latest/installation/)に書いてあったスクリプトが以下なのですが，

```
$ brew install openssl@1.1
$ env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography
```

これを実行すると`openssl1.1.0f`がインストールされてしまい動作しなかった．`OpenSSL 1.0.2l`でもいけるらしいのでそのパスを調べて書き換えたらうまく言った．
社内布教用のvimチートシート

# 前提
この投稿は社内でvimを布教するに当たって、基本的な使い方を説明するためのチートシートです。
分かりやすさを重視して、vimの正確な用語を使っていない箇所が多数あります。
なお、30分ほどの時間の余裕があるなら、この記事を読むより、vimで `:Tutorial` と打ち、チュートリアルを実践することをお勧めします(※英語に堪能でない場合は日本語化しておくこと良いでしょう)。

また、この記事は随時編集される可能性があります。

# 移動(基本)
- hjklで左/下/上/右に移動
    - 何はともあれ、これを覚えましょう。

# モード切り替え
- vimには大きく分けて3つのモードがあります。
    - ノーマルモード: カーソル移動や編集
    - 挿入モード: テキストを入力
    - 選択モード: テキストを選択
        - 通常選択モード
        - 行選択モード
        - 矩形選択モード

| キー   |説明 |
|:-------|:------------------|
| ESC    |ノーマルモードに戻る(困ったらとにかくESC)|
| i      |カーソルの位置で挿入モード開始|
| a      |カーソルの直後で挿入モード開始 |
| I      |行頭で挿入モード開始 |
| A      |行末尾で挿入モード開始 |
| o      |次の行で挿入モード開始 |
| v      |選択モード開始 |
| V      |行選択モード開始 |
| Ctrl+V |矩形選択モード開始 |

# 移動(応用1)
| キー   |説明 |
|:-------|:------------------|
| w    |次の単語の先頭へ移動|
| b    |前の単語の先頭へ移動|
| ^    |行頭へ移動(インデントを考慮する) |
| 0    |行頭へ移動(インデントを考慮しない) |
| $    |行末へ移動 |
| gg   |ファイル先頭へ移動 |
| G    |ファイル末尾へ移動 |

# 編集(ノーマルモード)
| キー  |説明 |
|:-----|:------------------|
| x    |1文字削除|
| dd   |1行削除|
| D    |カーソル位置以降を削除|
| yy   |1行コピー |
| 0    |行頭へ移動(インデントを考慮しない) |

# 編集(選択モード)
| キー  |説明 |
|:-----|:------------------|
| d    |選択範囲を削除|
| y   |選択範囲をコピー|
| p   |ペースト|
| .   |直前のアクションを再実行|

# 移動(応用2)
| キー   |説明 |
|:-------|:------------------|
| f「文字」  |行内で「文字」の位置まで移動|
| t「文字」  |行内で「文字」の手前まで移動|

# 検索
| キー   |説明 |
|:-------|:------------------|
| /「文字列」  |ファイル内の「文字列」を検索|
| *  |カーソル位置の単語を検索|
| n  |次の検索ヒット位置に移動|
| N  |前の検索ヒット位置に移動|

# 頻出パターン
| キー   |説明 |
|:-------|:------------------|
| dw  |カーソル位置の単語を削除|
| cw  |カーソル位置の単語を削除して挿入モード開始|
| *cw「文字列」n.n.n.  |カーソル位置の単語を検索し、次々に「文字列」に書き換え|
| yyp |現在行を複製|
| f, ; ; ;  |次のコンマへ移動(を繰り返す)|
| f<スペース> ; ; ;  |次のスペースへ移動(を繰り返す)|