OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsのsoket.ioでリアルタイムな双方向通信を実装してみた

複数のクライアントから送信されたデータを、
サーバー側で集約して、
接続中のクライアントにサーバーで集約した情報を共有するプログラムを書いてみた。

これができるということは、ゲームであれば、
各クライアントの座標をサーバーでまとめて、
クライアントにお互いの位置を共有したりすることができるので、
Node.jsを利用してゲーム等を作るのに役立ちそう。

# 1. クライアント側
以下の2点を実装する。
1-1. サーバーに情報を送信する処理
1-2. サーバーで集約したデータを受け取った時の処理

```client.html
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>soket.io client</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
	$(function() {
		var socket = io.connect();
		// ----------------------------------------------------------------------
		// 1-1. サーバーにメッセージを送信する処理.
		// ----------------------------------------------------------------------
		$('#sendButton').click(function() {
			var sendData = {
				message : $('#text').val()
			};
			socket.emit('saveData', sendData);
		});
		// ----------------------------------------------------------------------
		// 1-2. サーバーで集約している情報を表示する処理.
		// ----------------------------------------------------------------------
		socket.on('setView', function(dataByServer, serverFunction) {
			$('#view').empty().html(dataByServer.messages.join('<br />'));
		});
	});
</script>
</head>
<body>
	<h3>クライアントからのメッセージをサーバーで集約し、クライアントに集約したデータを共有するテスト</h3>
	<input id="text" type="text" />
	<input id="sendButton" type="button" value="送信" />
	<div id="view"></div>
</body>
</html>
```

# 2. サーバー側
以下の2点を実装する。
2-1. クライアントが接続された時の初期処理
2-2. クライアントからメッセージを受け取った時に保存して全体に共有する処理

```server.js
var fs = require('fs');
var http = require('http');
var server = http.createServer();

server.on('request', function(req, res) {
	var stream = fs.createReadStream('./client.html');
	res.writeHead(200, {
		'Content-Type' : 'text/html'
	});
	stream.pipe(res);
});

var io = require('socket.io').listen(server);
server.listen(8000);

var MAX_MESSAGES_SIZE = 30;
var data = {messages: []};
io.sockets.on('connection', function(socket) {
	// ----------------------------------------------------------------------
	// 2-1. クライアントの描画処理を呼ぶ.
	// ----------------------------------------------------------------------
	socket.emit('setView', data);
	// ----------------------------------------------------------------------
	// 2-2. クライアントから送信されたメッセージをサーバーにて保存する処理.
	// ----------------------------------------------------------------------
	socket.on('saveData', function(dataByClient) {
		data.messages.unshift(dataByClient.message);
		if (data.messages.length > MAX_MESSAGES_SIZE) {
			data.messages.splice(data.messages.length - 1);
		}
		io.sockets.emit('setView', data);
	});
});
```

# 3. 実行
ターミナルにて `node server.js` を実行。
ブラウザで `http://127.0.0.1:8000/`にアクセス。（窓を同時に複数開くと実験しやすい）
テキストボックスに適当な文字列を入力して送信ボタンを押すと、
複数の窓でメッセージが共有されていることが確認できる。
IndexedDBでインデックスを利用して前方一致検索する

IndexedDBでは，インデックスを利用してデータベースから項目を検索することが出来ます。
完全一致で検索する処理は容易に実装が可能ですが，前方一致で検索したい場合にはひと工夫が必要です。

#ひとことで言うと
インデックスに対するカーソルの範囲をこうすれば良い。

``` javaScript
const str = 'hoge';
const nextStr = str.slice(0, -1) + String.fromCharCode(str.slice(-1).charCodeAt() + 1);

const range = IDBKeyRange.bound(str, nextStr, false, true);

//~~~~

index.openCursor(range);
//'hoge'から始まる項目にマッチ
```

#下ごしらえ

こんな感じでデータベース`data`を初期化。
`id`をキーパスとして使用し，`name`で検索するためのインデックスを作成しています。
なお，例外処理や非同期処理の処理順などについては省略しています。

``` javaScript:init
let DB;

const init= () =>{
  const request = window.indexedDB.open('data', 1);
  
  request.onupgradeneeded = e => {
    const db = request.result;
    const store = db.createObjectStore('data', {keyPath: 'id'});
  
    //'name'で検索するためのインデックスを作成
    store.createIndex('name', 'name');
  }
  
  request.onsuccess= e => {
    DB = request.result;
  }
}

init();
```

このデータベースに対し，次のデータを追加します。

``` javaScript:add
const add= data => {
  const db = DB;
  const transaction = db.transaction('data', 'readwrite');
  const store = transaction.objectStore('data');

  store.put(data);
}

const data=[
  {id: '0', name: 'hoge'},
  {id: '1', name: 'fuga'},
  {id: '2', name: 'hogehoge'}
];

add(data[0]);
add(data[1]);
add(data[2]);
```

範囲を指定して`name`インデックスから項目を取得する関数を定義。

``` javaScript:search
const search= range => {
  const db = DB;
  const transaction = db.transaction('data', 'readonly');
  const store = transaction.objectStore('data');
  const request = store.index('name').openCursor(range, 'next');

  request.onsuccess= e => {
    const cursor = request.result;
    if (cursor){
      console.log('検索結果:', cursor.value);
      cursor.continue();
    } else {
      console.log('検索終了');
    }
  }
}
```

`name`が`"hoge"`に完全一致するデータを取得するにはこんな感じ。

``` javaScript:完全一致
const range= IDBKeyRange.only("hoge");
search(range);

// 検索結果:{id: '0', name: 'hoge'}
// 検索終了
```

#本題

`name`が`"hoge"`から始まるデータを取得するにはこうします。

``` javaScript:前方一致
const str = 'hoge';
const nextStr = str.slice(0, -1) + String.fromCharCode(str.slice(-1).charCodeAt() + 1);

const range = IDBKeyRange.bound(str, nextStr, false, true);
search(range);

// 検索結果:{id: '0', name:'hoge'}
// 検索結果:{id: '2', name:'hogehoge'}
// 検索終了
```
`nextStr`は，`str`の最後の一文字を「文字コードにおける次の文字」に置き換えた文字列です。この場合は`"hogf"`になります。
`IDBKeyRange.bound(str, nextStr, false, true)`は，`str`から`nextStr`の範囲(ただし`nextStr`を含まない)を指定しています。

すなわち，`name`を辞書順に並べたときに`"hoge"`と`"hoge"`より後ろかつ`"hogf"`より前にある文字列にマッチするので，`"hoge"`から始まる項目を取得することができます。
コンテナにclickハンドラ付ければ要素毎につける必要は無い

HTMLはこんな感じ

```html
<ul>
  <li data-id="1">push</li>
</ul>
```

増えていく`li`に対して`click`ハンドラ付けたい場合、
今まで愚直に`$('li').on('click', function() {})`
を毎回やっていたけど、今日もっと良い方法を知った

```javascript
let seq = 1;
$('ul').on('click', 'button', function() {
  $('ul').append('<li data-id="' + (++seq) + '">push</li>');
});
```

コンテナの方に`click`ハンドラを付けて、
`on()`の第二引数にセレクタを追加してやれば、`li`毎にハンドラを設定しなくても良い
Elixirで文字列をモジュールに変換する

mixのタスクで受け取ったパラメータをモジュールに変換して何か実行したい場合とか用メモ。

`"some_module"` を `SomeModule` に変換したい場合。

``` elixir
string = "some_module"
module = string |> Macro.camelize()
m = Module.concat([Elixir, module])　# => SomeModule
```

`Module.concat`を使えば変換してくれるけど、モジュール名がネストしていない場合は暗黙的に付加されている `Elixir` を先頭に指定してやれば問題ない。

上の例なら、SomeModuleがexec/0という関数を持っていれば、

```
m.exec()
```

で関数を実行できる。
ReduxでネストしているStateの一部分だけを更新する（備忘録）

Stateを小さい単位で更新したい時の、Reducerのreturn内の書き方

Reducerを分割するほどではない時にやる

いっつも忘れるので備忘


## Example

レストランの注文管理システムだとして...

Stateの構造。各要素に個数を持ってるイメージ

- foods
  - beef
  - chicken
- drinks
  - coffee
  - tea
  - water

```js
// @flow

type State = {
  foods: Foods,
  drinks: Drinks,
}

type Foods = {
  beef: number,
  chicken: number,
}

type Drinks = {
  coffee: number,
  tea: number,
  water: number,
}

```

注文情報をセットする`SET_ORDER`と、コーヒーの個数だけセットする`SET_COFFEE`があるとする


```js
// @flow

const setOrder = (order: State): Action => ({
  payload: order,
  type: "SET_ORDER",
})

const setCoffee = (count: number): Action => ({
  payload: count,
  type: "SET_COFFEE",
})

```

## こんな感じ

`SET_COFFEE`のreturn内

```js
// @flow

const orderReducer = (state: State = initialState, action: Action): State => {
  switch (action.type) {
    case "SET_ORDER":
      return action.payload
    case "SET_COFFEE":
      return {
        ...state,
        drinks: {
          ...state.drinks,
          coffee: action.payload,
        },
      }
    default:
      return state
  }
}

```

以上
簡単にパスワードを作るRubyワンライナー

就活をしていると、企業のマイページ毎にパスワードを作る必要があったので書きました。

## 組み込みライブラリで単純に
```terminal
$ ruby -e 'puts 8.times.map{[*"A".."Z", *"a".."z", *0..9].sample}.join'
```
パスワードはシンプルに大文字、小文字、数字で構成されます。
同じ文字が何回もあってもいいとしました。
桁数を変えたければ、8を任意の数に変えてください。

ですが、**この方法でパスワードを作るのはダメ**です。
`sample`を使ったパスワードは安全とは言えません。予測されてしまいます。
詳しくは、「[Rubyのsecurerandomを使う意味](https://teratail.com/questions/117807)」の回答を参照してください。

## SecureRandomで安全に
```terminal
$ ruby -r securerandom -e 'puts SecureRandom.alphanumeric(8)'
```

安全なパスワードを作るには`securerandom`を用いるのが良いようです。
`SecureRandom.alphanumeric`を使えば大文字、小文字、数字の安全なパスワードが作れます。
このUNIX秒って何時？に即答する

# 知りたい

1234567890 UNIX秒を日時で表すと？


2009/02/13 00:00:00 +0900　をUNIX秒にすると何秒？


2018/03/16 10:33:08 +0000　は+0650だと何時？

---
# ツール

無かったので、作りました。

![ChromeExtension_SmartTimeConverter.gif](https://drive.google.com/uc?export=view&id=1o8ZGduy1TeUuTt44tAhl0LsniW5AgKxk "Smart Time Converter.gif")

[Smart Time Converter](https://chrome.google.com/webstore/detail/smart-time-converter/afankndojeemjbdjhehnpahcobjdhnhi?hl=ja&utm_source=chrome-ntp-launcher)
Google Chrome Extension.

---
# Google Chrome Extension

[![Smart Time Converter](https://qiita-image-store.s3.amazonaws.com/0/137776/bbcfb406-e767-ebb5-4504-243612630199.png "Smart Time Converter")](https://chrome.google.com/webstore/detail/smart-time-converter/afankndojeemjbdjhehnpahcobjdhnhi?hl=ja&utm_source=chrome-ntp-launcher)

UnixtimeとUTC日時・ローカル日時を相互に変換できます。

[■ 試してみたい方はこちら ■](https://chrome.google.com/webstore/detail/smart-time-converter/afankndojeemjbdjhehnpahcobjdhnhi?hl=ja&utm_source=chrome-ntp-launcher)

---
# 参考にしたサイト
- https://qiita.com/k7a/items/26d7a22233ecdf48fed8
- https://developer.chrome.com/extensions/manifest
- https://developer.chrome.com/extensions/samples

---
# おまけ

1234567890 UNIX秒を日時で表すと？
こたえ：　2009/02/14 08:31:30 +0900

2009/02/13 00:00:00 +0900　をUNIX秒にすると何秒？
こたえ：　1234450800 秒

2018/03/16 10:33:08 +0000　は+0650だと何時？
こたえ：　2018/03/16 17:23:08 +0650
AWS LambdaでPythonのweb3.pyライブラリを使用する

AWSのLambdaで[Web3.py](https://github.com/ethereum/web3.py) (Pythonのweb3ライブラリ)を使用しようとして動かない場合があります。

![スクリーンショット 2018-03-16 19.50.22.png](https://qiita-image-store.s3.amazonaws.com/0/50056/1875bfbb-6e81-73a7-f204-20799e65d5bc.png)


```bash
Unable to import module 'handler': No module named '_pysha3'
```
上記のようなエラー。
どうやらPythonのビルドオプションに依存した問題の模様です。

- [Web3.py on AWS Lambda](https://github.com/ethereum/web3.py/issues/554)

私はMacで資材を作成した際に再現しました。

# 結論
Amazon Linux環境で資材を作成すれば問題なく動作します。
このエントリではその資材の構築手順を記載します。
環境構築が面倒な方は↓のDockerfileにまとめてありますのでご利用ください。
- https://github.com/sot528/lambda-web3py

# 環境
Docker for Mac: `Version 17.12.0-ce-mac55 (23011) d62ef8d1b0`
Dockerイメージ・amazonlinux: `3faa54d46dec`

# Amazon Linuxのコンテナイメージを取得
```bash
docker pull amazonlinux
```
:warning: [Lambdaの環境](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html)は厳密には異なりますがひとまず上記のコンテナイメージで問題ありません。

# コンテナで環境を構築

コンテナを起動。

```bash
docker run -it amazonlinux:latest /bin/bash
```

yumで必要なものを入れる。

```bash
yum install -y vi git gcc zip wget libssl-dev zlib-devel bzip2 \
    bzip2-devel readline-devel sqlite sqlite-devel openssl-devel
```

pipを入れる。

```bash
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
```

pyenvを入れる。

```bash
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
```
以下を`~/.bash_profile`に3行追記。

```bash
$ vi ~/.bash_proifile
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

反映してLambdaで使用するバージョンのPythonを入れる。

```bash
source ~/.bash_proifile
pyenv install 3.6.1
```
作業用ディレクトリを作成。

```bash
mkdir ~/work
cd ~/work
pyenv local 3.6.1
```

# Lambdaにデプロイする資材を作成
ミニマムのhandlerを書く。

```bash
vi lambda_function.py
```

以下を書き込む。
`YOUR_ETH_NODE`にはEthereumのノードのアドレスを入れる。

```bash
# -*- coding: utf-8 -*-
from web3 import Web3,HTTPProvider

def lambda_handler(event, context):
        web3 = Web3(HTTPProvider('http://YOUR_ETH_NODE:8540'))
        blockNumber=web3.eth.blockNumber
        print(blockNumber)
        return blockNumber
```

ライブラリを入れる。

```bash
pip install ethereum web3 -t .
```

資材をzipに固める。

```bash
zip -r upload.zip *
```

生成された`upload.zip`をlambdaにデプロイすれば問題なく動作します。

![スクリーンショット 2018-03-16 19.31.57.png](https://qiita-image-store.s3.amazonaws.com/0/50056/54b3d29e-4636-8011-475b-7bf5656638cc.png)


# 備考: コンソールから動作確認する手順
以下、要AWS設定。

dockerコンテナからファイルをローカルに持ってくる。

```bash
docker cp YOUR_CONTAINER_ID:/root/work/upload.zip /tmp
```

Lambda Function作成。

```bash
cd /tmp
aws lambda create-function \
    --function-name web3pytest \
    --runtime python3.6 \
    --role arn:aws:iam::099999999999:role/somerole \
    --handler lambda_function.lambda_handler \
    --zip-file fileb:///path/to/upload.zip
```

実行。

```bash
aws lambda invoke --function-name web3pytest result.txt
```

成功して200が返り、`result.txt`にブロックナンバーが書き込まれるはずです。

# 追記: 
以下のようなエラーとなる場合もあります。

```bash
Unable to import module 'handler': dynamic module does not define module export function (PyInit__cpuid)
```
Rich Notificationを本番とSTGで作成時の証明書類と設定


## はじめに

### 概要
Push通知へ画像を追加するRich Notification機能を実装する際は、複雑で複数の証明書類の作成および設定が必要になる。

本番環境のみのプロジェクトでこれを行なう場合は、Webの情報でなんとか設定できそうだが、本番とSTGのような複数の環境を持ったプロジェクト用の情報はWebで見つけられなかった。

このような状況でどんな証明証類と設定が必要かを記述する。

細かい設定方法等は省いてあるので、他のページ等を参考にしてもらいた。他のページから得たある程度の知識があれば、その後このページを参照することで、本番とSTGの両方に対応したRich Notificationの実装を行うことができるようになるだろう。


### 実現すること
１つのNotificationServiceExtensionのターゲットとUNNotificationServiceExtensionのクラスファイルを本番とSTGで共有させる。

### 必要な前提知識
1. Build Configを使って本番とSTG等の複数の環境を作ることへの理解。
参考: [Staging用の環境設定をXcodeに追加する](https://qiita.com/rika-tawashi/items/cc8f86ed6f4ad3f2514c)
2. NotificationServiceExtensionの実装に関する最低限の知識 etc.


### 今回記載しないこと
以下の内容等は他のページを参考にしてもらいたい。

- 個々項目の具体的な操作設定方法
- NotificationServiceExtensionターゲットの作成
- UNNotificationServiceExtensionクラス内の実装コード
- Xcode内でのProvisioning Profileの設定等 etc.



## 概念一覧
### Group
- MyAppGroup

### App
- MyApp
- MyAppSTG

### Extension ID
- MyApp.MyPushExtension
- MyAppSTG.MyPushExtensionSTG

### Extension
- MyPushExtension


## 1. App Group
開発者ページで一つだけ作成

- MyAppGroup


## 2. App ID
App Extensionは個別にApp IDが必要となる。

**開発者ページ**で**全てのIDのAppGroupを有効**にする必要がある。

### Appそのもの用
- MyApp
- MyAppSTG

### Extension用
AppID名を親となるAppの名称に合わせる必要がある。

- MyApp.MyPushExtension
- MyAppSTG.MyPushExtensionSTG


## 3. Provisioning Profile
AppIDでAppGroupの設定を変更したタイミングで、これらの内の既に作成済みのものは**Invalid**となる。それらは再度作成することになる。

### Appそのもの用
- MyApp
- MyAppSTG

### Extension用
App Extensionは個別のProfileを作成する必要がある。

- MyPushExtension
- MyPushExtensionSTG


## 4. Xcode内Target設定
Build ConfigのBundleID設定と、AppGroupの有効可の設定をする。

### Bundle IDを設定
**MyAppのターゲット**では、一般的にPrduction, STGの環境を構築した際にすでにこの設定になっている。

**MyPushExtensionのターゲット**へは、MyAppのターゲットと同じ手順で、Production, STGの環境に対応したBundleIDを設定する。
これは前項で作成したAppIDと同じものを入れる。


### AppGroupの有効化
MyAppとMyPushExtensionの**双方のターゲット**のCapabilitiesタブで、AppGroupを有効にする。その際、前項で作成したAppGroupを選択する（一つしかグループを作成していないので、他の選択肢は画面に出てこない）。
SwiftLintがmallocエラーで終了する場合の対処方法

# 概要
以下のように、Run Scriptでビルドする度に[SwiftLint](https://github.com/realm/SwiftLint)を実行していましたが、**mallocエラーで終了**するようになってしまったのでその対処方法をメモとして残します。

> swiftlint(1664,0x7000093d4000) malloc: *** error for object 0x7000093d1180: pointer being reallocated was not allocated

## Run Script

```bash
if which swiftlint >/dev/null; then
    swiftlint autocorrect
    swiftlint
else
    echo "SwiftLint does not exist, download from https://github.com/realm/SwiftLint"
fi
```

## 実行環境

```
MacOS: 10.13.3（17D47）
Xcode: 9.2 (9C40b)
SwiftLint: 0.25.0
```

# エラー内容詳細

> Done linting! Found 0 violations, 0 serious in 62 files.
swiftlint(1664,0x7000093d4000) malloc: *** error for object 0x7000093d1180: pointer being reallocated was not allocated
*** set a breakpoint in malloc_error_break to debug
/Users/[USER_NAME]/Library/Developer/Xcode/DerivedData/[PROJECT_NAME]-bshwakahiifqrnahsabchzdjyilu/Build/Intermediates.noindex/[PROJECT_NAME].build/Debug-iphonesimulator/MyLibrary.build/Script-163CEC159927D1238880A119.sh: line 7:  1664 Abort trap: 6           swiftlint

# 対処方法
SwiftLintのキャッシュファイルを削除することで正常にSwiftLintが実行できるようになりました。

```
$ rm -rf ~/Library/Caches/SwiftLint
```

# 参考
 - [malloc: *** error for object 0x700002a96090 #2032](https://github.com/realm/SwiftLint/issues/2032)
 - [0.25.0 makes path case sensitive - breaks with malloc error #2091](https://github.com/realm/SwiftLint/issues/2091)
Lua::ReaScript:REAPERで選択したメディアアイテムのフェードイン・フェードアウトの解除

もしかしたら公式にアクションが既にあるかもしれないし他にもっといいもの書いてる人がいると思いますが、せっかくなのでReaScriptなるものを触ってみました。
ReaScriptは簡単に言うと、LuaやPythonで記述されたREAPER上で実行できるスクリプトのことです。今回はLuaで。というかPythonかけません。

以下がコードになります。



```lua:OffCrossfade.lua
local SelectedMediasNum = reaper.CountSelectedMediaItems(0)
local count = 0

while count < SelectedMediasNum do
  local media = reaper.GetSelectedMediaItem(0, count)
  reaper.SetMediaItemInfo_Value(media, "D_FADEINLEN", 0, 0)
  reaper.SetMediaItemInfo_Value(media, "D_FADEOUTLEN", 0, 0)
  count = count + 1
end
```

はい。これだけです。

まず、reaper.CountSelectedMediaItems(ReaProject proj)で現在選択しているメディアアイテムの数を取得します。このとき引数を0にするとActive Projectに対して処理を行うようです。基本0でOK?

reaper.GetSelectedMediaItem(ReaProject proj, Integer SelItem)の第二引数に操作したいメディアアイテムの番号を入れると、そのメディアアイテムを返してくれます。Cなどの配列と同じでインデックスは0から始まるみたいです。

reaper.SetMediaItemInfo_Value(MediaItem item, string parmname, number newvalue)は、メディアアイテム、パラメータ名、新たに設定するパラメータ値を引数にとります。今回はフェードインとフェードアウトを無くしたいので、D_FADEINLENとD_FADEOUTLENをどちらも0にします。パラメータ名については詳しくは公式リファレンス↓
https://www.reaper.fm/sdk/reascript/reascripthelp.html#SetMediaItemInfo_Value

あとはwhileでまわすだけです。おわり！

<br>

アクション一覧からでも実行できますが、ショートカットキーを設定すればさらに便利になりますね。
これでメディアアイテムを追加するたびにいらんクロスフェードがついていたのを１ボタンで消せるようになったりします。おっちょこちょいの私は、時々消し忘れて後で全部手動で処理したりしていたので、非常に助かりますね。
ORDER句でCASE文を使用する

# SQLのORDER句でCASE文を使用する

## 環境
Microsoft SQL Server
## テーブル
テーブルに、優先順位を表すフィールドがある。優先順位は上位のものにだけ存在し、「1」から順に番号が振られている。
大半のレコードには優先順位がなく、それらの値は「」である。
このとき、優先順位があるものを先に表示し、優先順位がないものは名称順で表示したい。
![table.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/501d9402-e63c-12a0-be44-f4f6beb5e752.png)
## クエリ
ORDER句の中でCASE文を使用する。優先順位があればその値とし、なければ999としてソートを行う。

```
SELECT m.MachineId, m.MachineCd, SpecialPriority, IsDelete
FROM Machines m
WHERE m.IsDelete = 'False'
ORDER BY 
	CASE WHEN m.SpecialPriority='' 
		THEN 999 
		ELSE CONVERT(INT, m.SpecialPriority) 
	END
```

## 検索結果
優先度がある場合とない場合に区別したCASE文が働き、結果が取得できた。
![result.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/03df5cea-3b34-1cd4-59ed-70ffed0779e7.png)
Djangoでtwitterログイン

Djangoでtwitterログイン機能を実装する

#追記
アップデートでTwitterがOAuth認証時にCallback URLをチェックするようになったみたいなのでその対策

#実装
環境
　Python 3.6.1
　Django 2.0.3

下記のコマンドでパッケージをインストール

```


pip install social-auth-app-django

```
setting.pyに以下を追記する

```
INSTALLED_APP = [
    ・・・
    'social_django',
    ・・・
]
```

```
TEMPLATES = [
    {
        ・・・
        'OPTIONS': {
            'context_processors': [
                ・・・
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
            ],
        },
    },
]
```

```
LOGIN_REDIRECT_URL = ログイン後のページ
SOCIAL_AUTH_TWITTER_KEY = クライアントID
SOCIAL_AUTH_TWITTER_SECRET = クライアントシークレット

AUTHENTICATION_BACKENDS = (
    'social_core.backends.twitter.TwitterOAuth',
    'django.contrib.auth.backends.ModelBackend',
)
```
INSTALLED_APPSを追加したのでmigrateする

urls.pyに以下を追記する

```project名/urls.py
urlpatterns = [
    
    path('',include('social_django.urls')),
]
```

ログイン機能を追加したいテンプレートに以下を記入

```
<a href="{% url 'social:begin' 'twitter' %}">Login with Twitter</a>
```

#Callback URLのチェック対策
https://apps.twitter.com/
上のURLでCallback URLという項目があるのでそれをSettingsで再設定する

Callback URLのところをhttp://127.0.0.1:8000/complete/twitter/
と入力する

これでログイン機能は完成
Elixirでコンパイル時にconfigの値をチェックする

## 追記
コメントでafter_compileを使わなくてもよい方法をいただきました。
after_compile版も残しておきますが、ぜひコメントの方をご覧ください。

----------

重要なconfigの値があり、実行時ではなくコンパイル時にチェックし、
おかしければエラーで終了させたかった。

調べた結果、 `@after_compile` で実現できた。
https://hexdocs.pm/elixir/Module.html#module-after_compile

## sample source
``` elixir
defmodule ConfigError do
  defexception [:message]
end

defmodule ConfigCheckEx do
  @after_compile __MODULE__

  def __after_compile__(_env, _bytecode) do
    val = Application.fetch_env!(:config_check, :val)

    unless val in [:hoge, :fuga] do
      raise ConfigError, "val must be :hoge or :fuga"
    end
  end
end
```

## config.exs
``` elixir
use Mix.Config

config :config_check, val: :piyo
```

## 実行結果
```
$ mix compile
Compiling 1 file (.ex)

== Compilation error in file lib/config_check_ex.ex ==
** (ConfigError) val must be :hoge or :fuga
    lib/config_check_ex.ex:12: ConfigCheckEx.__after_compile__/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
```

もっといい方法があれば知りたい。
TermuxとBluetoothキーボードでPC禁止を回避する

人事「情報漏洩防止のためにノートPCは持ち込み禁止です。もちろん<b>寮でも禁止です</b>。」
新入社員「ええ～っ！！！」
人事「スマホ、タブレットならいいです。」
新入社員「なんじゃそれ」

# 用意するもの
* スマホ or タブレット
* Bluetoothキーボード

Hacker's keyboardというアプリを使えばソフトウェアキーボードでもできるそうですが、ソフトウェアキーボードでプログラミングするのは現実的ではありません。

# 使用するアプリ
今回はTermuxというターミナルエミュレータを使います。
https://play.google.com/store/apps/details?id=com.termux&hl=ja

Termuxのメリット

* aptでパッケージが管理できる。
* ドキュメントがそこそこ落ちている。
* アップデートが新しい。
* vimがデフォルトで使える。

他には「Android Terminal Emulater」というものがあるそうです。古いバージョンのAndroidはこちらしか対応していませんが、アップデートも2015年で止まっているようです。

https://play.google.com/store/apps/details?id=jackpal.androidterm&hl=ja

# 環境構築

## ストレージにアクセスできるようにする
インストールした時点では、権限の問題でTermuxからAndroidのstorageにアクセスすることはできません。そのため、アクセスできるようにするには設定が必要になります。

とはいえ全く難しいことではなく、```termux-setup-storage```と唱えるだけです。するとTermuxにファイルアクセスを許可するかAndroidからプロンプトが出るので、許可するとホームディレクトリにstorageというディレクトリができ、その下にリンクが張られます。

ホーム直下に置きたい場合は、普通のリンクとして扱えばいいだけなので、```mv```で移動しましょう。

## パッケージ群
<b>全部aptでできます。</b>デフォルトでvimが使えますが、Emacs派の人はEmacsもインストールできます。

### clangコンパイラ
<b>Termuxでは現在gccが使えません。</b>代わりにllvmとclangを使います。
```apt install libllvm clang```

Cのソースファイルのコンパイルは```gcc```ではなく```clang```とします。
```clang mysrc.c```

C++の場合はclang++とします。
```clang++ mysrc.cpp```

## Python
Python本体はaptでインストールでき、pipも使えます。しかしライブラリの整備が結構面倒です。pythonのライブラリはCでビルドするものも多いので、上述のclangのインストールが必要です。

### NumPy
インストールに7分くらいかかります。
```pip install numpy```

### matplotlib
libpngとfreetypeがいります。またfreetypeはpkg-configがないとmatplotlibをインストールできません。

```apt install libpng-dev freetype-dev pkg-config
pip install matplotlib```

# 問題点
* GCCが使えない。ゆえにfortranは使えない。
* Emacsが重い。起動に5秒以上かかる。
* Emacsでは日本語が使えない。
* ファイルストレージ上ではファイルを実行できない。```chmod u+x```ができない。
* ハードウェアキーではバックスラッシュが打てない。ゆえに改行記号などはその都度ソフトキーを出して打たなければならない。

とはいえSSHが使えるので、最悪VPSでも借りてSSHでやりましょう。

# 参考サイト
Termux-setup-storage
https://wiki.termux.com/wiki/Termux-setup-storage

freetype cannot be found by build　#3029
https://github.com/matplotlib/matplotlib/issues/3029
VisualStudio > Typewriter (下書き中)





[Typewriter - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=frhagn.Typewriter)

[frhagn/Typewriter: Automatic TypeScript template generation from C# source files](https://github.com/frhagn/Typewriter/)



# Typewriter
Typewriter is a Visual Studio extensions that generates TypeScript files from c# code files using TypeScript Templates.
This allows you to create fully typed TypeScript representations of server side API, models, controllers, SignalR hubs etc. that automatically updates when you make changes to your c# code.

[Documentation](http://frhagn.github.io/Typewriter)  
[Download from Visual Studio Gallery](https://visualstudiogallery.msdn.microsoft.com/e1d68248-f30e-4a5d-bf18-31399a0bcfa6)

## Issues
The issue tracker is the preferred channel for bug reports, features requests and submitting pull requests.   
For personal support requests Stack Overflow is a better place to get help. Please use the   [typewriter](http://stackoverflow.com/questions/tagged/typewriter) tag when posting your questions.

## Getting started
Step 1: Add a TypeScript Template file (.tst)  
Step 2: Add the following code in the template  
```typescript
$Classes(*Model)[ // Find all classes with a name ending with Model
    class $Name {
        constructor($Properties[public $name: $Type][, ]) {
        }
    }
]
```
Step 3: Save the template  
Step 4: Add a c# class named TestModel  
Step 5: Add the following code to the class  
```c#
using System;

namespace TestApplication
{
    public class TestModel
    {
        public int Id { get; set; }
        public int Name { get; set; }
    }
}
```
Step 6: Save the class.  

Each time a class matching the filter in the template is saved a TypeScript class matching the template is updated or added to the project.
Unity NGUIで、ScrollView内のUISprite等が拡大縮小しない。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/311aeb1d-e964-e75f-517c-2fc9006c511d.png)

いくらtransformのscaleを大きくしても反応なし。
だけど、UISpriteのUIRectをいじると変更できる。。
tweenや、UniRxや、Spineなども色々疑ってみたけどだめ。。

で、まったく理由がわからずScrollViewを疑うと下記項目にチェックが入っていた。。。！汗

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/3d605711-caf8-5001-fbd4-4232c554a94c.png)

このStaticのチェックをはずすと無事拡縮できました。ｗ

長年さわっているけど、NGUIのScrollView難しい。
全てのコンポーネントで暗黙的にscss|sassを@importする

色々ハマりましたが↓を使うのが楽でした。
[nuxt-sass-resources-loader](https://github.com/anteriovieira/nuxt-sass-resources-loader)

ただし、用法用量を正しく守って使いましょう
https://github.com/anteriovieira/nuxt-sass-resources-loader/issues/8
Link > Markdown > diff書式による行の強調表示

書いた記事に対するコメントで今後使いそうな良い方法が掲示されていた。
複数行の出力に対して、特定の行を強調させて掲示することができる。

2018年3月現在、コメントは検索できないので、リンク記事とします。

### コメントいただいた中でのアイデア

[@tukiyo3さんのコメント](https://qiita.com/7of9/items/510165dfb946a7184305#comment-fde28b35f9ffbfe2c709)


### esa.io上

esa.ioではどうなるか確認してみた。

[Markdown > diff > 行の強調表示](https://esa-pages.io/p/sharing/6206/posts/5374/465cc543372b688dc6a9.html)
mattermost プロキシ メモ

# mattermost 

proxyで引っかかったのでメモ
https://github.com/mattermost/mattermost-docker

```bash
$ git clone https://github.com/mattermost/mattermost-docker.git mattermost-docker
$ cd mattermost-docker
$ docker-compose build
# 失敗 apkのDNS lookup error
```

```bash
$ls -1
LICENSE
MAINTENANCE.md
README.md
app                   # Dockerfile apkを利用
contrib
db                    # Dockerfile apkを利用
docker-compose.yml
web                   # Dockerfile
```

dbとappのDockerfile内にプロキシ設定を追加するとうまくいった

```bash
ENV http_proxy=http://...
ENV https_proxy=http://...
```
CentOS 6.9 > ビデオドライバをnouveauからkmod-nvidiaへ変更

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

nouveauというのはCentOS 6.Xでデフォルトに使われるドライバのようだ。
このnouveauとGeForce GT 730の相性が良くないためか、原因不明のrebootが発生している。

関連: [CentOS > 謎の再起動の再発 > ps -efのログ確認 | Link > CentOS ビデオドライバ(NVIDIA GeForce)関連](https://qiita.com/7of9/items/510165dfb946a7184305)

reboot対策の1つとしてビデオドライバをnouveauからkmod-nvidiaへ変更してみる。
(kmod-nvidiaを使うとkernelアップデート時に問題が少ないらしい)

### 参考

- [ThinkPad W520 + CentOS 7 夏対策（省電力設定）](http://luna2-linux.blogspot.jp/2017/08/)
    - CentOS 7の情報ではあるが、CentOS 6.9でも`yum list`の確認は同じ方法で可能

情報感謝です。

### 前準備

[CentOS 6.X > 外部パッケージELRepoのrpmファイル名を見つける (2018-03-16版)](https://qiita.com/7of9/items/7789c0a6bef2bc48f9ae)

上記の「ELRepoのrpmファイル」節の2つのコマンドを実行してELRepoリポジトリを追加しておく。

### 実施

利用可能なバージョンを以下で確認する。

```bash
$ yum list kmod-nvidia --enablerepo=elrepo --showduplicates
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * elrepo: ftp.yz.yamagata-u.ac.jp
 * epel: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
Available Packages
kmod-nvidia.x86_64                                   367.57-1.el6.elrepo                                     elrepo
kmod-nvidia.x86_64                                   384.90-1.el6.elrepo                                     elrepo
kmod-nvidia.x86_64                                   384.98-1.el6.elrepo                                     elrepo
kmod-nvidia.x86_64                                   384.111-1.el6.elrepo                                    elrepo
kmod-nvidia.x86_64                                   390.25-1.el6.elrepo                                     elrepo
```

390.25を使うことにした。

```bash
$ sudo yum install kmod-nvidia-390.25-1.el6.elrepo.x86_64 --enablerepo=elrepo
```

OS再起動後、以下であることを確認した。

```bash
$ dmesg | grep NVIDIA
NVRM: loading NVIDIA UNIX x86_64 Kernel Module  390.25  Wed Jan 24 20:02:43 PST 2018 (using threaded interrupts)
nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms  390.25  Wed Jan 24 19:29:37 PST 2018
```

画面表示は問題ない。

rebootの問題が解消するかどうか。しばらく様子を見ることになる。
Carthageのcopy-frameworksをRelease時のみ実行したい

# はじめに

下記のようにやってたけど、指摘があってクリーンビルドしたら `dyld: Library not loaded: ` が見つからなくてクラッシュするので、**下記に書かれているようにReleaseのみにする方法はやめましょう...!!**

# Release時のみ実行（してしまうとまずい）

iOSアプリ開発でCarthage使う時、Run Scriptにcopy-frameworksを設定すると思うんだけど、これは[App Storeへのサブミット時の不具合を回避するため](https://www.slideshare.net/syoikeda/carthagen)に設定しているのということなので、普段のDebugビルド時にはいらないんじゃないかなと。

つまり、Run Scriptは次のようにしていいんでは...という気持ちで下記のようにしてました

```sh

if [ "${CONFIGURATION}" = "Release" ]; then
/usr/local/bin/carthage copy-frameworks
fi
```

この`"${CONFIGURATION}"`の ReleaseはXcodeでデフォルトで用意されているので、自分でカスタムするものではなく、それをそのまま使っています。

しかしこれではクリーンビルドしてしまうと次のビルド実行後はダイナミックライブラリが見つからずに実行時エラーになってしまうのでした。

## 追記: Debug時にもcopy-frameworks必要という件の概要

岸川さん（ @kishikawakatsumi ）に指摘をしてもらった内容を追記します

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">バイナリの除去は必要ないけどコピーは必要なので、これはCarthageのドキュメントに従ってEmbeddedじゃなくてLinked Frameworksにドラッグ＆ドロップしてたら動かないですね。</p>&mdash; kishikawa katsumi (@k_katsumi) <a href="https://twitter.com/k_katsumi/status/974576782954213381?ref_src=twsrc%5Etfw">2018年3月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

他にも指摘をしてくれたんですが割愛させてもらって、なぜCarthageのドキュメントどおりにしてcopy-frameworksの実行が必要かを記載します

- 前提として
    - ライブラリをDynamic Frameworkとしてビルドして利用する場合、app bundleのFrameworksにコピーされる必要がある
        - copy-frameworksはinput filesに追加したパスのフレームワークをコピーしてくれている
    - iTunesへの申請にはシミュレータ用のバイナリがipaに含まれてはいけない
        - copy-frameworksはi386とx86_64をipaから省いてもくれる（Valid Archのみにしている）
- Linked Frameworksに追加するのは
    - Linkとビルドフェーズに設定を追加している


つまり、ipaをValid ArchのみにしてくれてるのはRelease時のみでいいが、フレームワークのコピーはDebug時でもやる必要があるので（一度やればキャッシュが残っているがクリーンビルドで消える）、Debug時でもcopy-frameworksが必要だということですね。

## 関連

CrashlyticsのdSYM送信スクリプトをRelease時のみ実行したい
https://qiita.com/yimajo/items/98cbf5bdbc098c683657
pythonのrequestsモジュールで認証プロキシを超えたい

# この記事について
* [Azure FaceAPI](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/)を利用するのに、[Python用SDK]( https://github.com/Microsoft/Cognitive-Face-Python)を使いたい。
* ただ、社内環境だと認証プロキシを超えてWebAPIにアクセスする必要がある。
* さぁ、どうするか。という記事

# Proxyを超える方法（結論は簡単だった）
* 結論は、環境変数（**HTTP_PROXY**）に認証プロキシを指定するだけ。（以上！）

```shell
export HTTP_PROXY="http://${USERNAME}:${PASSWORD}@${PROXY_HOST}:${PROXY_PORT}"
```

* なお、環境変数に定義したく無い場合、pythonのプログラム内で下記を書いておけば実行中に環境変数を定義し、プロキシ適用が可能。

```python
import os
os.environ["http_proxy"] = "http://user:pass@server:port"
```

# 上記でいい理由

* FaceAPIのPythonSDKはHTTP通信に[requestsモジュール](http://docs.python-requests.org/en/master/)を利用している。
* そのため、環境変数が定義されていれば、そのプロキシを使ってHTTPしてくれる。（素晴しい！）
* 図にするとこんな感じ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/183826/a7ad6ecc-c5e5-d666-52c4-e80aff886ae7.png)
jsdoで遺伝的アルゴリズム

#概要
遺伝的アルゴリズムを理解したかった。
jsdoで、やってみた。

#写真
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/O/m/h/Omhk.jpg?t=1521184198)

#one maxのようなもの。

http://jsdo.it/ohisama1/K6WTi
http://jsdo.it/ohisama1/oHbU

#文字をフィットする。

http://jsdo.it/ohisama1/YhB4
http://jsdo.it/ohisama1/ccY8
http://jsdo.it/ohisama1/CndW


#XORをフィットする。

http://jsdo.it/ohisama1/AvEZ

#p5.jsを使ってる。

http://jsdo.it/ohisama1/Omhk
http://jsdo.it/ohisama1/gZm1
http://jsdo.it/ohisama1/oTCe

#ブロック崩し

http://jsdo.it/ohisama1/8XVx
http://jsdo.it/ohisama1/U0RS

#巡回セールスマン問題

http://jsdo.it/ohisama1/qlxy

以上。
Golang：複数条件でソートする

華麗なコードではない。

# バージョン
## golang
1.8.7くらい

https://hub.docker.com/r/library/golang/tags/

# 実装
```
package main

import (
    "fmt"
    "sort"
)

func main() {
    people := []struct {
        Name string
        Age  int
    }{
        {"Steve", 70},
        {"Carol", 99},
        {"Alice", 100},
        {"Bob", 1},        
        {"Alice", 26},
    }

    sort.Slice(people, func(i, j int) bool {
        if people[i].Name < people[j].Name {
            return true
        } else if people[i].Name == people[j].Name {
            if people[i].Age < people[j].Age {
                return true
            }
        }
        return false
    })
    fmt.Println("Order by name, age:", people)
}
```

## 出力結果
```
Order by name, age: [{Alice 26} {Alice 100} {Bob 1} {Carol 99} {Steve 70}]
```

# 参考
https://golang.org/pkg/sort/#Slice
スレッドセーフへの道 c++

理論はわかるけど、結局どんなコードで書けばいいの！？と悩む、同志たちに捧ぐ。

#基本

複数のスレッドが共有する変数を操作するときは、適切な排他制御のもとに行う必要がある。

例えば、mutex によるクリティカルセクションを設けて、その中で共有変数への読み書きを安全に実行する。

#失敗

全ての実装(シングルスレッドで動作するもの)を終えたあとに、基本アイデアに従って、対象の共有変数へアクセスしている全てのコードブロックをクリティカルセクションで包んでいては骨が折れる。

#アイデア

もし、対象の変数へアクセスする度に、必ずクリティカルセクションを設けてくれる機能があるのなら、安心して実装を進められるだろう。

##★共有変数制御テンプレート
###コード
```cpp:
	//--------------------------------------------------------------------------------------------

	extern std::recursive_mutex thread_mutex;

	//--------------------------------------------------------------------------------------------

	template<typename T>
	T Delegate_Mutex( const std::function<T()>& mutex_event )
	{
        // ロックする
		std::lock_guard<std::recursive_mutex> lock( thread_mutex );

		return mutex_event();
	}

	//--------------------------------------------------------------------------------------------

	template<typename T>
	class Critical
	{
	public:

        // 値を書き換える版
		template<typename R>
		R Invoke( const std::function<R( T& )>& critical_event )
		{
			return Delegate_Mutex<R>( [&]() { return critical_event( m_sharedValue); } );
		}

        // 値を書き換えない版
		template<typename R>
		R Invoke( const std::function<R( const T& )>& critical_event ) const
		{
			return Delegate_Mutex<R>( [&]() { return critical_event( m_sharedValue); } );
		}

	private:

		T m_sharedValue;
	};

	//--------------------------------------------------------------------------------------------

```
###解説
共有変数をprivate 修飾で宣言しているので、この変数への操作はInvoke 関数を経由するほかない。さらにInvoke 関数は、引数に渡された関数オブジェクトをコールするが、その前に必ずmutex によるロック(※ここでは再帰的なロックとした。)を行う。

こうすることで、うっかり共有変数を排他制御なしに操作してしまう危険性を排除できる。

##使い方

```cpp:
	struct Counter
	{
		uint32_t count = 0;
	};

	{
		Critical<Counter> criticalCounter;

		criticalCounter.Invoke<void>( []( Counter& counter ) {
            // 安全なインクリメント
			counter++;
		} );
	}
```

#おわりに
スレッドセーフを実現するための道具には、atomic 変数や、他のロック管理クラスなどたくさんある。今回は排他制御の記述漏れ問題に対しての解決手段を提案した。何を優先し、どこにコストを払うのか、常にトレードオフを意識することが大切だと思う。
Subversion で ignore を設定する

Subversion では コミットしてリポジトリに適用する ignore とローカルのみに適用できる ignore があります。
リポジトリを使用する人、全社員に適用したい場合は前者、個人的に自分の環境にだけ作りたい場合は後者を使うと良いでしょう。
また、デフォルトで以下の値は無視されるように設定されています。

```
*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store.
```

ここから分かるように `*` はワイルドカードとして使用できます。

## リポジトリに適用する

### svn:ignore

```sh
svn propset svn:ignore PROPBAL PATH...
```

を使います。
例えば、

```sh
svn propset svn:ignore *.bak .
```

と書くと現在のディレクトリの末尾が `.bak` であるファイルが無視されるようになります。
`svn:ignore` はディレクトリごとに適用されます。
再帰的に適用したい場合は `svn propset` では `-R [--recursive]` オプションを利用できます。

```
svn propset -R svn:ignore *.bak .
```

とすれば現在のディレクトリ配下全体にこの `svn:ignore` が適用されます。
リポジトリ全体に適用したい場合、 propset で `svn:global-ignores` も使用できるようですが、未検証。

また、 `svn:ignore` はコミットする必要があることに注意してください。
自分自身にだけ適用したい場合は次のセクションを参考にしてください。

## ローカルにだけ適用する

### config ファイルを編集する

`C:\Users\<USERNAME>\AppData\Roaming\Subversion\` に `config` ファイルがあります。
この中で `[miscellany]` の位置を探してその下に `global-ignores` の以下のような例が載っています。

```
global-ignores = *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo __pycache__ *.rej *~ #*# .#* .*.swp .DS_Store
```

これを参考に設定します。
保存した後

```
svn status
```

をすると設定したファイルが無視されているはずです。
また、

```
svn status --no-ignore
```

とオプションをつけると無視されるファイルには `I` がついて表示され、正しく設定できていることが分かると思います。

## 参考
[Subversionで無視パターンを指定](https://ateraimemo.com/Subversion/GlobalIgnores.html#la613547)
http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2
http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.3
バックグラウンドで起動したプロセスの殺し方

# プロセス残留事件

負荷試験をしていたので複数台のサーバーの状態を調べるため、バックグラウンドプロセスで複数のsshを実行していました。

```bash
monitor(){
  host=$1
  ssh $host "while true;do uptime;sleep 5;done" > $host.log
}

monitor host_a &
monitor host_b &
monitor host_c &
wait
```

データ取り終わって`ctrl + c`をしたら、sshのプロセスが全部残ってました。てへ。
`ps aux | grep ssh`して拾ったPIDを使ってプロセスを殺しました。メンドクサイ。

# 解決法

```bash
monitor(){
  host=$1
  # このsshを非同期にする
  ssh $host "while true;do uptime;sleep 5;done" > $host.log &
}

# 関数実行を非同期にするとkillでsshが死なないのでこれを非同期にしない
monitor host_a
monitor host_b
monitor host_c

# いつ殺すかを自由に決めたいので標準入力で待機
echo "press any key."
read tmp

# 殺します
kill $(jobs -p)
```
thisを使わないJavaScriptパターン

アロー演算子が導入されたからと言ってJavaScriptにおいて`this`がややこしいことには変わりがない。以下、よくやる間違い。

```js
class Person {
  constructor({name,age}){
    this.name = name
    this.age = age
  }
  say () {
    console.log(`${this.name} ${this.age}`)
  }
}
const p = new Person({name:'Alice',age:16})
p.say() //OK
setTimeout(()=>{p.say()},1000) //OK
setTimeout(p.say,1000) //NG
const f = p.say
//f() //NG Compile error
```

もう`this`使わないようなコードを書く、と規約にしてもいいんじゃない？

```js
function createPerson({name,age}){
  const say = () => {
    console.log(`${name} ${age}`)
  }
  return {
    say,  //and other method if you like
  }
}
const p2 = createPerson({name:'Alice',age:16})
p2.say() //OK
setTimeout(()=>{p2.say()},1000) //OK
setTimeout(p2.say,1000) //OK
const f2 = p2.say
f2() //OK
```

継承だってできるし。

```js
function createWizard({name,age,rod}){
  const p = createPerson({name,age})
  const zap = () => {
    console.log(`${rod}!!`)
  }
  return {
    ...p,
    zap,
  }
}
const wiz = createWizard({name:'Alice',age:16,rod:'fire'})
wiz.say()
wiz.zap()
```

なんとなく参考: https://medium.freecodecamp.org/elegant-patterns-in-modern-javascript-ice-factory-4161859a0eee
【Python3】文字列のスライス

# 概要

``` ex.py
a = "abcdefg"
print(a[3::-2])
```
みたいなプログラムへのアレルギーをなくすための記事

# 基本
``` a[i:j:k] ``` は**「文字列aのi番目の要素からj番目の直前の要素までk刻みで抜き出す」**ということを意味する。

例

``` ex1.py
a = "abcdefg"
print(a[1:6:2])
>>> bdf
```

![20180315_01.png](https://qiita-image-store.s3.amazonaws.com/0/199887/8bae3a77-6e09-227d-7516-30d423d388ed.png)

a[1], a[3], a[5]が結果として出力されている。
つまり文字列aの1番目の要素から5番目の要素まで2刻みで抜き出されていることがわかる。

# 標準
##1.``` a[i:j:k] ``` のkが負の値をとる時

``` ex2.py
a = "abcdefg"
print(a[5:2:-1])
>>> fed
```


![20180316_02.png](https://qiita-image-store.s3.amazonaws.com/0/199887/6abbe079-fadd-361c-071c-4dab69a62885.png)

この例で取り出されているのはa[5], a[4], a[3]
つまり、**j番目の直前の要素は、ここではj-1番目ではなくj+1番目である**。

``` ex3.py
a = "abcdefg"
print(a[2:5:-1])
>>>
```
![20180316_03.png](https://qiita-image-store.s3.amazonaws.com/0/199887/f3b68455-40cf-7e5f-86f6-431b529badcf.png)

それと面白いのは、kがマイナスの時は最初のインデックスの方が大きい値でなければ**(i > jでなければ)**文字列を取り出せないこと。




##2.``` a[i:j:k] ``` のiまたはjが省略されている時

``` ex4.py
a = "abcdefg"
print(a[:4:2])
>>> ac
```
kが正の値のとき、iが省略されたら自動的に左端に設定される。

``` ex5.py
a = "abcdefg"
print(a[1::2])
>>> bdf
```

jが省略されたら自動的に右端に設定される。

``` ex6.py
a = "abcdefg"
print(a[::3])
>>> adg
print(a[:6:3])
>>> ad
```

![20180316_04.png](https://qiita-image-store.s3.amazonaws.com/0/199887/c1d44ca3-6ebf-4063-ee16-bc1be3dacf3d.png)
![20180316_05.png](https://qiita-image-store.s3.amazonaws.com/0/199887/5df67f33-399c-9332-8beb-52304717f404.png)


両方省略されたら端から端まで。ただし、この例で右端の要素はa[6]だけど、**```a[::3]```と```a[:6:3]```は意味が違うことに注意する**。




##3.``` a[i:j:k] ``` のiまたはjが負の値の時

``` ex7.py
a = "abcdefg"
print(a[-6:6:3])
>>> be
```

![20180316_06.png](https://qiita-image-store.s3.amazonaws.com/0/199887/373f8720-dbb0-f6b6-9d7d-f3b212151ce7.png)

iやjを負にすると後ろから数えることになる。**a[-1]が末尾に対応**している。


``` ex8.py
a = "abcdefg"
print(a[1:-2:2])
>>> bd
```
![20180316_07.png](https://qiita-image-store.s3.amazonaws.com/0/199887/adaf267b-4b39-85cf-0059-480fe8c1eec3.png)

**fは抜き出されない**ことに注意する。a[1]からa[-2]の直前の要素(a[4])までが対象であるため。


# 発展
だいたい標準パターンの複合で説明できる。
## 標準1と標準2の複合
``` ex9.py
a = "abcdefg"
print(a[:2:-2])
>>> ge
```
![20180316_08.png](https://qiita-image-store.s3.amazonaws.com/0/199887/892db486-15b3-d73b-dca4-bf820ba84b31.png)

**kが負の値でiが省略されている時、自動的に右端が開始位置になる**。同じように、kが負でjが省略されていたら左端が終了位置になる。

文字列を反転させる```a[::-1]```はこのくくりに分類できる。開始位置が右端、終了位置が左端で1刻みに文字を拾っていけば文字列を逆転させるってことになるよね。


## 標準2と標準3の複合
``` ex10.py
a = "abcdefg"
print(a[-5::2])
>>> ceg
```
![20180316_09.png](https://qiita-image-store.s3.amazonaws.com/0/199887/a1fd203a-d62b-8657-afc0-91438d56db92.png)

わざわざこんな書き方をする意味があるのかはわからない。


## 標準1と標準3の複合
``` ex11.py
a = "abcdefg"
print(a[-1:-7:-3])
>>> gd
```
![20180316_10.png](https://qiita-image-store.s3.amazonaws.com/0/199887/b02e139c-b918-2af6-2566-bea90704fe90.png)

後ろから文字を拾い上げていく時はi,j,kをマイナスで統一したほうが見やすいかもしれない。


## 標準1,2,3の複合
``` ex12.py
a = "abcdefg"
print(a[-1::-3])
>>> gda
```
![20180316_11.png](https://qiita-image-store.s3.amazonaws.com/0/199887/cbf75836-c261-da14-1c2f-8cb597657d70.png)

jを左端の要素にするのと何も入れないのとでは意味が変わってくる。```a[-1:-7:-3]とa[-1::-3]```は違う。

# まとめ
概要のプログラムをもう一度見る。

``` ex.py
a = "abcdefg"
print(a[3::-2])
```
出力されるのは...db！
もう怖くない。




*追記(2018/03/16)*
コードのミスを修正しました。ご指摘ありがとうございます。
Arch Linux に SoftEther_VPN をインストール

関連ソフトのインストール

```bash
sudo pacman -S dhclient
```

SoftEther_VPN のインストール

```bash
yaourt -Sb softethervpn
```

次のコマンドがインストールされます。
>/usr/bin/vpnserver
>/usr/bin/vpnclient
>/usr/bin/vpncmd

サーバーのスタート
>sudo systemctl start softethervpn-server
>sudo systemctl status softethervpn-server

クライアントサービスのスタート
>systemctl start softethervpn-client
>systemctl status softethervpn-client

サーバーの設定
>vpncmd /server

クライアントの設定
>vpncmd /client

サーバーの設定の確認方法

```text
$ vpncmd /server

VPN Server>Hub Default

VPN Server/DEFAULT>UserList

VPN Server/DEFAULT>DhcpGet

VPN Server/DEFAULT>DhcpTable

VPN Server/DEFAULT>quit
```

クライアントの設定の確認方法

```text
$ vpncmd /client

VPN Client>NicList

VPN Client>AccountList

VPN Client>quit
```

設定済みのクライアントをサーバーに接続する

```text
VPN Client>AccountConnect test
AccountConnect command - Start Connection to VPN Server using VPN Connection Setting
The command completed successfully.
```

DHCP で　アドレスを取得する

```bash
ip addr show vpn_test
sudo dhclient vpn_test
ip addr show vpn_test
```

アドレスが取得できたことを確認する

```text
$ ip addr
```


サーバー側でアドレスを配布していることを確認 (サーバーでの操作）

```text
VPN Server/DEFAULT>dhcptable
DhcpTable command - Get Virtual DHCP Server Function Lease Table of SecureNAT Function
Item            |Value
----------------+-------------------------
ID              |1
Leased at       |2019-12-10 (Tue) 18:31:56
Expires at      |2019-12-10 (Tue) 20:31:56
MAC Address     |5E-89-43-E7-E4-20
Allocated IP    |192.168.30.10
Client Host Name|pansy
The command completed successfully.
```


参考にしたページ
[ SoftEtherでVPN環境を作ろう](https://www.linuxmania.jp/softether-vpn.html#ser-set)
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?の解決策

詰まったのでメモ。

docker起動中に、PCが強制終了してしまったところ以下エラーが発生しました。

```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

言葉の通りなのですが、docker daemonが起動していません。

Docker quick　start terminalで起動させましょう。

しかしもし起動させても以下メッセージが出る場合もあります。

```


                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/


Error getting IP address: ssh command error:
command : ip addr show
err     : exit status 255
output  :
docker is configured to use the default machine with IP
For help getting started, check out the docs at https://docs.docker.com
```

その場合は、以下コマンドでdefaultを削除。
その後再度Dcoker quick start terminalを起動させれば解決します。

```
docker-machine rm default
```
郵便料金の条件判定を3つのやり方で試してみる

[定形郵便物・定形外郵便物の基本料金](http://www.post.japanpost.jp/fee/simulator/kokunai/one_two.html)は、つぎの表のように定められています。重さから料金を求めようとすると、条件判定の処理をしなければなりません。本稿では、3つのやり方をご紹介します。

####定形郵便物
|   重さ   |  料金  |
|--------:|------:|
|  25g以内 |  82円 |
|  50g以内 |  92円 |

####定形外郵便物
|    重さ   |  料金  |
|---------:|------:|
|   50g以内 | 120円 |
|  100g以内 | 140円 |
|  150g以内 | 205円 |
|  250g以内 | 250円 |
|  500g以内 | 380円 |
| 1000g以内 | 570円 |

#if文を使う
もっとも基本的な条件判定のやり方は`if`文を使うことでしょう。また、応用範囲も広い手法です。関数(getPostage())として定めることにします。引数は重さで、戻り値が料金です。1kgを超えると規格外になるので、-1を返すことします。

```js
function getPostage(weight) {
	let postage;
	if (weight <= 25) {
		postage = 82;
	} else if (weight <= 50) {
		postage = 120;
	} else if (weight <= 100) {
		postage = 140;
	} else if (weight <= 150) {
		postage = 205;
	} else if (weight <= 250) {
		postage = 250;
	} else if (weight <= 500) {
		postage = 380;
	} else if (weight <= 1000) {
		postage = 570;
	} else {
		postage = -1;
	}
	return postage;
}
```

処理としてはまったく問題ありません。少し書きづらく、見にくいというのが難点でしょう。

#条件演算子を使う
値を代入したり、返したりする判定処理では、[条件(三項)演算子`? :`](https://developer.mozilla.org/docs/JavaScript/Reference/Operators/Conditional_Operator)を使うとすっきり見やすく書けることが少なくありません。Microsoft Excelの[IF関数](https://support.office.com/ja-jp/article/if-%E9%96%A2%E6%95%B0-69aed7c9-4e8a-4755-a9bc-aa8bbff73be2)と構文の組み立ては同じです。

```js
function getPostage(weight) {
	const postage =
		(weight <=   25) ?  82 :		
		(weight <=   50) ? 120 :		
		(weight <=  100) ? 140 :		
		(weight <=  150) ? 205 :		
		(weight <=  250) ? 250 :		
		(weight <=  500) ? 380 :		
		(weight <= 1000) ? 570 :
							-1;
	return postage;
}
```

コードの条件演算子は入れ子になっています。けれど、書き方をうえのように整えれば、`if`文よりも構成がわかりやすいのではないでしょうか。

#Array.prototype.find()メソッドを使う
[`Array.prototype.find()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/find)は、ECMAScript 2015 (ECMAScript 6)から備わった新しいメソッドです。引数に関数を渡すと、その条件に合う要素が得られます。

```js
function getPostage(weight) {
	const postageTable = [
		{weight:   25, postage:  82},
		{weight:   50, postage: 120},
		{weight:  100, postage: 140},
		{weight:  150, postage: 205},
		{weight:  250, postage: 250},
		{weight:  500, postage: 380},
		{weight: 1000, postage: 570}
	];
	const adapt = postageTable.find((element) =>
		weight <= element.weight
	);
	return (adapt) ? adapt.postage : -1;
}
```

料金表が予め配列で示されるので見やすくなります。また、`Array.prototype.find()`メソッドは条件を関数で定めるため、複雑な処理が加えやすいのもよい点です。条件に合う要素が見つからない場合は、`undefind`が返されます。その判定には条件演算子を用いました。

3つの手法それぞれに、応用範囲の広さ、見やすさ、手の加えやすさなど、異なったよい点があります。場合によって使い分けてみてください。
URL公開したHumanServiceにパラメータを渡して呼び出す

#IBM BPMで、URL公開したHumanServiceにパラメータを渡したい
IBM BPMでHuman ServiceをURL公開し、そこに初期値をパラメータで渡したいときの方法を質問されたのでメモ
##QueryStringによるパラメータの受け渡し
以下のように、HumanServiceを呼び出す際に、パラメータを指定してHumanServiceを起動することが可能です。tw.local.変数名で指定することが可能です。


・Heritage HumanServiceの例

`https://hostname/teamworks/executeServiceByName?processApp=processAppName&serviceName=serviceName&tw.local.variable1=value1`


・Client Side Human Serviceの例

`https://hostname/bpm/dev/teamworks/executecf?modelID=1.7d1e22cf-811d-40ea-b706-89064df8c4xxx&branchID=2063.4539fb85-3218-4c8d-9f26-a534cc7cxxx&tw.local.variable1=value1`	

#参考資料
https://www.ibm.com/support/knowledgecenter/SSFPJS_8.5.5/com.ibm.wbpm.wle.editor.doc/topics/creating_services_C.html
Github Pages でVueのrouterが動かなくてハマった件の対応

トップからrouter-linkを辿ったときは正常にページ遷移できるけど、
外部から直リンクでアクセスしたら404になるやんけ！
……と困ったときの対応メモです。
手間を掛けず、サクッと対応できる方法、ということで。

## 概要
そもそも論、実際には存在していないページにアクセスしようとしているから404が出るわけで、
まず404ページからドキュメントルートに飛ばしてから、うまく表示できるような細工をするという流れになります。

## 404ページの作成
404ページにて、アクセスしたパスを記録したうえでドキュメントルートに遷移させてあげます。
ルート直下に404.htmlを作ればOK。

```html:404.html
<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script>
    // sessionStorageにアクセスしたURLを記録しておく
    sessionStorage.redirect = location.href;
  </script>
  <!-- ドキュメントルートに遷移させる -->
  <meta http-equiv="refresh" content="0;URL='/'"></meta>
</head>
<body>
</body>
</html>
```

## Vue側の準備
Vueの方は基本的に通常通りページ構築すればOK。
必要に応じてベースディレクトリの設定を修正しましょう。

index.htmlだけ、ちょこっと細工をします。
下記をhead内に追記。

```html:index.html
<script>
  (function(){
    // 保存しておいたURLを取り出す
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      // historyを書き換える。これで正常にページ遷移を行ったときの表示となる。
      history.replaceState(null, null, redirect);
    }
  })();
</script>
```

## 雑感
便利で快適なGithub Pagesをご利用ください。

参考

* [csuwildcat/sghpa](https://github.com/csuwildcat/sghpa)
* [GitHub Pages and Single-Page Apps](https://dev.to/_evansalter/github-pages-and-single-page-apps)
【Swift】ConstraintでAnimationをするときに絶対に気をつけたほうがいいこと

まぁ、普通に以下のようにAnimationのコードを書いていたりすると思うのですが、以下のようにしていたらハマりました。

```swift:hoge.swift
self.hogeButtonBottomConstraint.constant = 8
UIView.animate(withDuration: 0.2) {
  self.view.layoutIfNeeded()
}
```

何がまずいかっていうと、self.view.layoutIfNeeded()をAnimationさせる前に叩いていないので、以下の処理が呼ばれる前にConstraintを設定すると全部Animationされてしまうんですよね。
なので、以下のようにAnimaitonしたいConstraintの修正のみを`self.view.layoutIfNeeded()`ではさんであげる必要があります。

```swift:hoge.swift
// ここに以下のような処理があると一緒にAnimationされちゃう
// self.fugaButtonBottomConstraint.constant = 8

self.view.layoutIfNeeded()
self.hogeButtonBottomConstraint.constant = 8
UIView.animate(withDuration: 0.2) {
  self.view.layoutIfNeeded()
}
```

まぁ、皆さんはご存知だとは思うんですけどね...