OmniAICreator/Qiita-1.07M huggingface dataset:
リリースビルドからSimulator用のarchitectureを抜く方法（Unity編）

# 背景
iOSアプリ向けのSDK(framework)には、実機とシミュレータの両方で動作するよう、Simulator用のアーキテクチャが含まれている場合があります。そのようなSDKを組み込んだ状態でリリースビルドを作成し、iTunesConnectにアップロードをしようとすると、下記のように"Unsupported Architectures"のエラーが出てアップロードに失敗することがあります。

<img width="614" alt="iTC-Unsupported-Archs.png" src="https://qiita-image-store.s3.amazonaws.com/0/122091/733957ad-19f4-433d-8f30-ba0ec4b2e1c4.png">

これを回避するには、XcodeのBuild Phases -> Run Scriptの項目に、Simulator用Architectureを除去するスクリプトを追加する必要があります。この手法については下記の記事が参考になります。
http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/
https://stackoverflow.com/questions/30547283/submit-to-app-store-issues-unsupported-architecture-x86

ただし、純粋なiOSアプリでなくUnityからXcodeにエクスポートしたプロジェクトの場合、上記のスクリプトを追加してもアップロードに失敗するケースがあります。その場合、下記で紹介するようにスクリプトに若干修正を加える必要があります。

# UnityからXcodeにエクスポートした場合の除外スクリプト
※'YourLibrary.framework'の箇所を適切なframework名に修正してください

```bash:UnityからiOSへエクスポートした場合のスクリプト
#!/bin/sh

# SDK search path for project source directory
APP_PATH_SRC="${PROJECT_DIR}"

# SDK search path for build destination directory
APP_PATH_DST="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

echo "APP_PATH_SRC: $APP_PATH_SRC"
echo "APP_PATH_DST: $APP_PATH_DST"

# Search SDK from destination path first. If not found, search from source path.
find "$APP_PATH_DST" "$APP_PATH_SRC" -name 'YourLibrary.framework' -type d | while read -r FRAMEWORK
do
echo "FRAMEWORK: $FRAMEWORK"
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

EXTRACTED_ARCHS=()

for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done

echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"

echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

# If SDK was found in the first loop (destination path), no need to proceed to next loop.
break
done
```

# 処理内容
元記事のスクリプトでは\$APP_PATH_DSTのみに対し走査を行なっているのに対し、上記のスクリプトでは\$APP_PATH_SRCと\$APP_PATH_DSTという２つのディレクトリに対し走査を行ってarchitectureの除去を行っています。これは、Unityからエクスポートしたプロジェクトの場合、なぜか除去のタイミングのあとにビルドディレクトリへのframeworkのコピーが行われ、architectureの除去がうまくいかない場合があるためです。
Javascript・ES6メモ(随時追加)

#exportとrequire
デフォルトエクスポートの時に、`require()`の後に`.default`をつけないと読み込まれなかった。

```javascript
//export.js(export側)
export default class MyClass
{
   //
}

//import.js(import側)
const MyClass = require('./export').default

```

#グローバル変数

・Javascript

```javascript
top, window, parent, frames, self
```
・node.js

```node.js
global, GLOBAL, root
```

#要素の移動
scrollIntoView()メソッドを使う。

```javascript
element.scrollIntoView({
  behavior: 'smooth',
  block: 'center',
  inline: 'center',
});
```

https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
2018.02.03勉強まとめ

・`SID`
>「SID（Security Identifier。セキュリティ識別子）」と呼ばれる一意のID番号列を使用して管理されている。具体的には「S-1-5-21-917266621-1342861121-1792158721-512」のような数字列のことを指す。システムを新規にセットアップし直さない限り、同じSIDが使われることはない。

削除するとSIDが変わってしまうので注意
http://www.atmarkit.co.jp/ait/articles/0306/28/news004.html

・ネットワークトラフィックの監視

`トラフィック`
ネットワーク上を流れる単位時間あたりのデータ量
`bps(bits per second)`

`トラフィックパターン`
バースト型：一度に大量のトラフィックが発生するパターン
インタラクティブ型：比較的少量のトラフィックが周期的に発生するパターン

`帯域使用率`
Band Width：単位時間あたりに転送できるデータ量。使用しているネットワーク規格ごとの最大伝送能力
帯域の内どのくらいが使用されているかをパーセントで表した値

`SNMP`
>ネットワークデバイスを管理するためのプロトコル
>http://www.apresia.jp/products/ent/np/usersguide/management/NP_snmp_c_fc.html

`ポートミラーリング`
>特定のポートを通じてやり取りしているイーサネット・フレームを、指定した別のポートにも複製して流す機能だ。だから、監視対象となるコンピュータを接続しているポートに対して、そのポートのトラフィックをキャプチャ用のコンピュータを接続したポートに複製するように設定すればよい
>https://news.mynavi.jp/article/networkswitch-6/

・`アップリンクポート`
>VLANにおいて、すべてのネットワークのデータが通れるスイッチの穴
>http://wa3.i-3-i.info/word12100.html
>http://wa3.i-3-i.info/word12097.html

・`MIB(Management Information Base)`
データ保管場所

参考URL：http://www.cqpub.co.jp/hanbai/books/18/18411/18411.pdf
参考URL：https://news.mynavi.jp/article/networkswitch-24/

・`ネットワーク負荷の可視化`
参考URL：https://docs.oracle.com/cd/E19355-01/820-7389/abfcc/index.html

・`CASB`
Cloud Access Security Broker：キャスビー
>「ユーザーと複数のクラウドプロバイダーの間に単一のコントロールポイントを設け、ここでクラウド利用の可視化や制御を行うことで、全体として一貫性のあるポリシーを適用できるようにする」
http://www.cybernet.co.jp/netskope/casb/
Python ターミナルで操るよ

# Pythonを使うときのターミナルコマンド
- Python起動 → ```python```
- Python終了 → ```control +D```


# ファイル名のディレクトリをコピペするよ
![ディレクトリコピペ.png](https://qiita-image-store.s3.amazonaws.com/0/222672/efaca068-9d0f-89bc-e447-78eab95a53b0.png)
ディレクトリを正確にコピペする → ```option + command + C```

# ターミナルコマンド覚書
- ディレクトリの移動 → ```cd```
WinMR開発環境メモ

WinMRの開発環境で詰まったので、動作できた環境をメモ

WinMR : Lenovo Explorer
OS : Windows 10 home (ビルドバージョン 16299.192) 
Visual Studio : 15.5
Unity : Unity Editor 2017.2.0p1 MRTP4 (http://beta.unity3d.com/download/b1565bfe4a0c/download.html)
IL2CPPは入れてない

MRTK : https://github.com/Microsoft/MixedRealityToolkit-Unity/releases/tag/v1.2017.2.0

Editor実行時にImmersiveの方に出力されないことがあったが、再起動をすると解決した。全体的に動作が不安定。
unityのml-agents のGridWorldを試してみる

# はじめに
　先週、unit ML-Agentsの tennisサンプルを試したみた。今週は次のサンプル GridWorldも試してみた。

> unityのml-agentsでtensorflowを使った強化学習を試してみる
> https://qiita.com/kznx/items/b0614b08e052bd95addf

# GridWorld サンプル
　ランダムに置かれた障害物を避けて、ゴールにたどり着くことを学習するサンプル。デフォルトだと障害物が一つで、エリアも5x5と小さいので、エリアを広げ、障害物の数を増やしてみた。変更点は下記の通り。

1. unityの[Hierarchy]タブの[GridAcademy]を選択。
2. Inspectorに表示されるgridSizeのValueを10、numObstaclesのValueを20にしてみた。

# tensorboard
　一応訓練は進んでいるように見えるが・・・

<img width="1373" alt="Screen Shot 2018-02-03 at 14.41.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/128327/53ca9580-93c0-0e40-800f-ed20a7533615.png">


# 学習結果
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">今週は、GridWorldのサンプルを試してみたが、あまり賢くなってない。学習がうまく進んでないようだ。 reinforcement learning by unity ml-agents, GridWorld example <a href="https://t.co/PjTSYKSzCD">https://t.co/PjTSYKSzCD</a> via <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a></p>&mdash; Kazutoshi Nakano (@kznx) <a href="https://twitter.com/kznx/status/959658782912520192?ref_src=twsrc%5Etfw">February 3, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 最後に
　もう少しハイパーパラメータを調整しないと、学習が進まず、賢くならないようだ。
Sublime Text3でHTML/CSS/JS Prettifyパッケージ実行エラーの対処法

SublimeパッケージHTML/CSS/JS Prettify実行時のエラー解決法です。
実行方法はcmd + shift + h

### 現象
下記エラーが発生。
<img width="430" alt="01.png" src="https://qiita-image-store.s3.amazonaws.com/0/179505/2e9aaf9f-4c0b-dee2-1404-c42be1929c2e.png">

node.jsの見つからないよって怒られているみたいです。

### nodeのpathファイル

上記エラーのOKを押すと下記キャプチャへと飛びます。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/179505/c8c0125e-8f90-fce7-208f-da9347790110.png)


下記方法でも飛べます。
ツール　→ HTML/CSS/JS Prettify → Set `node` Path

<img width="537" alt="03.png" src="https://qiita-image-store.s3.amazonaws.com/0/179505/aa0e2ae8-6cab-b61b-60d0-f90a58603018.png">

### パス設定
```sh
{
        "windows": "C:/Program Files/nodejs/node.exe",
        "linux": "/usr/bin/nodejs",
       # "osx": "/usr/local/bin/node" 初期設定
        
        "osx": "/Users/ユーザー名/.nodebrew/current/bin/node"　# こちらに書き換える
    },
```

### まとめ
nodeのインストール方法によって問題が起きたようです。
純粋にnodeをインストールしただけだと初期設定にもあった`/usr/local/bin/node`で大丈夫みたいですが、nodebrewだとパスが変わるみたいです。

#### 参考文献
http://bodyshift.jugem.jp/?eid=10
UIViewのアニメーションを永続的に行う方法

# 背景
UIViewクラスにはanimateというメソッドが用意されており、下記のようにシンプルにアニメーションを実装することができます。

```swift:testViewを3秒間かけて下に50point移動する
UIView.animate(withDuration: 3) {
    self.testView.frame.origin.y += 50
}
```

ただしこのようなアニメーションを繰り返し行いたい場合、例えば５秒毎にViewを上下に行ったり来たりさせるといったアニメーションを実装するには、若干の工夫が必要になります。本記事では、Timerクラスを用いて永続的なアニメーションを行う手法を紹介します。

# アニメーションの実装
まず、下記のようにアニメーションを行うメソッドを定義しておきます。この例では、testViewのframe.origin.yが0の場合は下に50point移動し、そうでない場合は0の位置に移動するというアニメーションを0.3秒で行うように指定しています。
※後にselectorとして使用可能なように、メソッドの接頭詞に@objcを付けています。

```swift:testView.frame.origin.yが0なら+50、そうでないなら0に移動
@objc func animate() {
    UIView.animate(withDuration: 0.3) {
        if self.testView.frame.origin.y == 0 {
            self.testView.frame.origin.y += 50
        } else {
            self.testView.frame.origin.y = 0
        }
    }
}
```

# Timerの設定
次にTimerの設定を行います。下記の例では、５秒毎にanimateメソッドを呼び続けるようにTimerをセットしています。こうすることで、一定間隔で上記のanimateメソッドが呼び出され、testViewが上下に50ポイントずつ動き続けるアニメーションを実装することができます。

```swift:５秒毎にanimateメソッドを呼ぶ
var animationTimer: Timer?

override func viewDidLoad() {
    super.viewDidLoad()

    self.animationTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.animate), userInfo: nil, repeats: true)
}

```

# 注意点
Timerが不要となったタイミング（testViewが非表示になった場合等）で、下記のようにinvalidateを呼んでTimerを無効化しておくとよいでしょう。invalidateを行わずにTimer.scheduledTimerを繰り返しセットし続けたりすると、クラッシュの原因となるため注意してください。

```swift:animationTimerを無効化する
self.animationTimer?.invalidate()
```

例えば独自のUIViewにTimerを持たせていた場合、下記のようにすることでViewが非表示になるタイミングでTimerをオフにできます。

```swift:UIViewが非表示になるタイミングでTimerを無効化する
override func willMove(toWindow newWindow: UIWindow?) {
    super.willMove(toWindow: newWindow)
    
    if (newWindow == nil) {
        self.animationTimer?.invalidate()
    }
}
```
Oracle Container Registryからのpullが遅い場合の解決法


Oracle Container Registryからイメージをダウンロードする際に、サイトの案内に従って普通にpullすると、Docker Storeからpullする場合に比べて、気の遠くなるほど待たされることがあります。

```bash
$ docker login container-registry.oracle.com
$ docker pull container-registry.oracle.com/database/enterprise
```

実は、ミラーが存在します。

* container-registry-**phx**.oracle.com ... Phoenix(米国南西部)
* container-registry-**ash**.oracle.com ... Ashburn(米国東海岸)

日本からの場合、`container-registry-ash.oracle.com`を使うと良さそうです。
以下のようにします。

```bash
$ docker login container-registry-ash.oracle.com
$ docker pull container-registry-ash.oracle.com/database/enterprise
```

参考:

* [Oracle Container Registry mirrors in Oracle Cloud Infrastructure](https://blogs.oracle.com/wim/oracle-container-registry-mirrors-in-oracle-cloud-infrastructure)
* [Oracle® Container Runtime for Docker User's Guide - 5.1.1 Oracle Container Registry Mirrors](https://docs.oracle.com/cd/E52668_01/E87205/html/oracle-registry-server-mirrors.html)
Node.jsのCluster APIをラップするコードが書けたのでメモ

Node.jsのCluster APIをラップするコードが書けたのでメモを残します。

- `easy-cluster-utils`をインストールする。
- マスタースレッド用の`master.ts`を書く。
    - `isMaster`と`ClusterMaster`をimportする。
- ワーカースレッド用の`worker.ts`を書く。
    - `isWorker`と`sendToMaster`と`CommandMessage`をimportする。
- エントリーポイントとなる`index.ts`を書く。
    - `master.ts`で定義した関数を使ってPromiseチェーンで実行処理を書く。

## npm install

```
$ npm install easy-cluster-utils rxjs
```

# 使い方

## master.ts

```ts:master.ts
import { isMaster, ClusterMaster } from 'easy-cluster-utils';

let master: ClusterMaster<number>;

if (isMaster) {
  master = new ClusterMaster({ debug: true });
}

export function concurrentMap(list: number[]): Promise<number[]> {
  return master.executeList(list, 'map');
}

export function concurrentReduce(list: number[]): Promise<number[]> {
  return master.executeList(list, 'reduce');
}
```

## worker.ts

```ts:worker.ts
import { isWorker, sendToMaster, CommandMessage } from 'easy-cluster-utils';
type Message = CommandMessage<number[]>;

if (isWorker) {
  process.on('message', (message: Message) => {
    if (message.type === 'map') {
      workerMap(message);
    } else if (message.type === 'reduce') {
      workerReduce(message);
    }
  });
}

function workerMap(message: Message): void {
  const result = message.payload.map(v => v * 2);
  sendToMaster({ result });
}

function workerReduce(message: Message): void {
  const result = message.payload.reduce((p, v) => p + v);
  sendToMaster({ result });
}
```

## index.ts

```ts:index.ts
import { range } from 'lodash';
import { terminate } from 'easy-cluster-utils';
import { concurrentMap, concurrentReduce } from './master';

function main(): void {
  const list = range(1, 10);
  console.log('list:', list);

  concurrentMap(list)
    .then(list => concurrentReduce(list))
    .then(list => list.reduce((p, v) => p + v))
    .then(value => {
      console.log('result:', value);
      terminate();
    })
    .catch(err => {
      throw err;
    });
}

// エントリーポイント。
main();
```

## package.json

`package.json`に`worker`プロパティを書き足して、Workerスレッドが読み込むJSファイルを指定します。これを書かないとエラーになります。

```json
{
  ...(省略),
  "worker": "build/worker.js"
}
```

この記述によってWorkerスレッドが読み込むJSファイルはこれだけに限定されるので、実際は`isMaster`とか`isWorker`とか書いて処理を分岐させる必要はないのですが、「書いてある方が読みやすい」という人はいるかもしれないです。

# 出力

```OUTPUT
list: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
worker:97028 started.
worker:97029 started.
command-message to worker:97028. { type: 'map', payload: [ 1, 2, 3, 4, 5 ] }
command-message to worker:97029. { type: 'map', payload: [ 6, 7, 8, 9 ] }
result-message from worker:97028. { result: [ 2, 4, 6, 8, 10 ] }
result-message from worker:97029. { result: [ 12, 14, 16, 18 ] }
command-message to worker:97028. { type: 'reduce', payload: [ 2, 4, 6, 8, 10 ] }
command-message to worker:97029. { type: 'reduce', payload: [ 12, 14, 16, 18 ] }
result-message from worker:97028. { result: 30 }
result-message from worker:97029. { result: 60 }
result: 90
worker:97029 died.
worker:97028 died.
```
Raspberry Piに接続したサーボをリモート(クライアントサーバモデル)で制御する

#はじめに
ラズパイに接続したサーボをネットワーク経由でコントロールする実験をします。
![System.png](https://qiita-image-store.s3.amazonaws.com/0/211703/b9a07ad4-7995-878b-e7c2-1f84e2712a97.png)

クライアントサーバモデルを使用し、ラズパイをサーバ、PCをクライアントとします。PC側からラズパイに接続し、x,y=10,15というようなテキストコマンドを送信すると、サーバが角度として認識し、サーボをコントロールするようにします。
ラズパイでサーボをコントロールする方法はこちらに記述しています。
[Raspberry Pi OpenCVで顔検出しサーボでトラッキング](https://qiita.com/tlab/items/a13e9135ab1b12f8749f)

この実験はPCでOpenCVを処理し、その結果でサーボを制御するための予備実験です。

#プログラム
##サーバ側
受信したテキスト文(xx,yyのフォーマット)を変数x,yに入力し、サーボコントロール用pmw信号として出力します。"q"を受信するとコネクションを開放し、次の接続を待ちます。

```python:server.py
import Adafruit_PCA9685
import socket

from time import sleep


pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)

s = socket.socket()

port = 5000
s.bind(('', port))
while True:
    print('listening')
    s.listen(5)
    c, addr = s.accept()
    print('receiving')
    while True:
        try:
            data = c.recv(1024)
            if data == "q":
                break;
            print(data)

            x,y = map(int, data.split(","))

            pwm.set_pwm(0,0, 400+x)
            pwm.set_pwm(1,0, 400+y)
        except:
            break
        sleep(1)
    c.close()
s.close()

```

##クライアント側
xx,yyのフォーマットにてキーボードを入力、エンターで送信します。また、"q"で終了します。

```python:client.py
import socket
from contextlib import closing
import sys

s = socket.socket()

host = sys.argv[1]
port = 5000

s.connect((host, port))

while True:
    print "connected"
    data = raw_input("x,y>")
    s.send(data)

    if data == "q":
        s.close()
        break

```

#動作
ラズパイはPCからSSHで接続して実行しています。PC側はBash on Ubuntu on Windowsです。
##サーバの起動
サーバ側はGPIOにアクセスする必要があるため、sudoでプログラムを実行する必要があります。
```bash:server
pi@raspberrypi:~ $ sudo python server.py
```

##クライアント側
普通に起動します(sudoは不要です)。引数にラズパイのIPアドレスを指定します。
```bash:client
ikeda@PC:~ $ python server.py 192.168,1,116
```

![run.png](https://qiita-image-store.s3.amazonaws.com/0/211703/012df1e4-6e94-4971-965e-64a2a0ec3ef1.png)

##操作
クライアント側にてx,y>と聞いてきます。
```bash:client
ikeda@PC:~ $ x,y>
```
xに水平角度、yに垂直角度を指令します。x=180度y=90度とするには180,90と入力、エンターで送信します。
```bash:client
ikeda@PC:~ $ x,y>180,90[ENTER}
```
サーバ側では受信したコマンドを表示し、サーボをコントロールします。

##動作
動作中の写真
![DSD_2009.png](https://qiita-image-store.s3.amazonaws.com/0/211703/9ed80010-d0eb-48dc-cf9c-0992da1a89b3.png)

![DSD_2010.png](https://qiita-image-store.s3.amazonaws.com/0/211703/d6ab7317-15b0-92a1-35ce-cc41674b924a.png)

##映像
[Youtubeにアップしました](https://youtu.be/82rTbe6yg58)ので、興味のあるかたはどうぞ。


#Special thanks!
ソケット通信について、@msrksさまの記事を参考にさせていただきました。
[PythonでSocket通信](https://qiita.com/msrks/items/0550603efc59f6e8ba09)
ありがとうございました。

2018/02/03 Ikeda
①Pythonで画像から色情報抜き出す、②PythonでShade3Dスクリプトで濃淡絵を書く、③３Dプリンタで書き出す

①Pythonで画像から色情報抜き出す
(1)画像を準備(縦横400pixcel（マス目は40x40）)
![400x400.jpg](https://qiita-image-store.s3.amazonaws.com/0/107418/ae77060f-25ec-9108-4184-c93d11da8dcb.jpeg)
(2)Pythonで色情報を抜き出す

```Python:out_img.py
#coding: utf-8

from PIL import Image

im = Image.open("./400x400.jpg")
rgb_im = im.convert('RGB')

f = open('./Ein400x400.txt', 'w')

for i in range(5,401,10):
    f.write("(\n")
    for j in range(5,401,10):
        r, g, b = rgb_im.getpixel((i, j))
        f.write("("+str(((i/5)+1)/2) +"," + str(((j/5)+1)/2) + "," + str(r) + "),\n")
    f.write("),\n")

f.close()
```

②PythonでShade3Dスクリプトで濃淡絵を書く
(1)スクリプト

```Python:script_for_shade3d.py
import math
import random
scene = xshade.scene()
scene.begin_creating()

a = ((
(1,1,66),
(1,2,64),

〜略

(40,39,130),
(40,40,120),
),
)

for n in range(0,40,1):
	for m in range(0,40,1):

		s = 0.5
		x = n
		y = 0
		z = m
		hgt = 8 - a[n][m][2] * 8 / 255 

		scene.create_primitive_box(None, 3, True, 1, 1, 1, [x+s, y-s, z-s], [x+s, y-s, z+s], [x-s,y-s, z+s], [x-s, y-s, z-s], [0, 2+hgt, 0], True, True)

scene.end_creating()
```

(2)Shade3D

![35model.jpg](https://qiita-image-store.s3.amazonaws.com/0/107418/a69a93ac-e509-41f4-9666-7901343cc5f7.jpeg)


③３Dプリンタで書き出す
(1)
![rCIMG3069.jpg](https://qiita-image-store.s3.amazonaws.com/0/107418/637d4f9a-f76a-7ead-20a3-8c27b93be4a3.jpeg)

(2)
![rCIMG3073.jpg](https://qiita-image-store.s3.amazonaws.com/0/107418/d4ea292a-b1e9-db87-c54f-8e149af61db0.jpeg)

(3)
![35_2a.jpg](https://qiita-image-store.s3.amazonaws.com/0/107418/098f6f87-8404-e0f0-9974-ae493fb37cf8.jpeg)
NanoPi NEOのホスト名変更とavahi-daemonの有効化

sshでログインするときにIPアドレスを調べなくてもよいようにしたい。

#ホスト名の変更

まずホスト名を打ちやすい名前に変更する。
/etc/hostname と /etc/hosts を修正する。
タイプミスして、この2つのファイルの整合性がとれなくなった状態ではsudo がエラーで実行できなくなり、かなり困った状態に陥ってしまう。
それを回避するため、sudo でbashを起動して、その状態でこの2つのファイルを書き換える。

```
$ sudo bash
# vi /etc/hostname
# vi /etc/hosts
```

修正されたファイルの内容は以下。

```
# cat /etc/hostname 
neo
# cat /etc/hosts
127.0.0.1    localhost.localdomain localhost
127.0.1.1    neo
```

ホスト名をセットできることを手動で確認する。

```
# hostname `cat /etc/hostname`
# hostname
neo
```

これでいったんリブートする

#avahi-daemon のインストール

```
sudo apt install avahi-daemon
```

```
$ ps ax |grep avahi
 1166 ?        Ss     0:00 avahi-daemon: running [neo.local]
 1167 ?        S      0:00 avahi-daemon: chroot helper
 1400 ttyS0    S+     0:00 grep --color=auto avahi
```
avahi-daemonが動いているようだ。
設定ファイルの変更は特に必要ない。

#Macからログイン

ホスト名の後ろに .local をつければよい。

```
MAC$ ssh pi@neo.local
```

これでIPアドレスを調べる必要がなくなった。
AppleScriptからの写真(Photos)の書き出し先はピクチャフォルダしか指定できない


```applescript
set albSource to "test"
set myPath to "SSD:Users:username:Documents"

tell application "Photos"
	set srcContainer to container albSource
	set myList to every media item in srcContainer
	export myList to myPath with using originals
end tell
```

![スクリーンショット 2018-02-03 13.32.25.png](https://qiita-image-store.s3.amazonaws.com/0/103041/098793ba-9818-7ebd-d091-9db518630b09.png)


実行ユーザーのピクチャフォルダ配下以外を書き出し先に指定するとエラーになる。アクセス権を777にしても変わらない。
Nekoniumのパブリックノードを立ててみよう その4 Let's Encrypt+Caddyで簡単にSSL対応編

まず最初に以下の記事を参考にポート8293のパブリックノードを立てましょう。

Nekoniumのパブリックノードを立ててみよう その1
https://qiita.com/ROZ-mofumofu-me/items/f9490e4bd23922b62e54

ノードを一度停止して、今度はポート8292で起動しましょう。
(8292は内部通信ポートにします。)

```
build/bin/gnekonium -rpc --rpcaddr 0.0.0.0 --rpcport 8293
```

次にCaddyをダウンロードします。

https://caddyserver.com/download

Choose LicenseでPersonal (free)を選択し、One-step installer script (bash)にあるワンライナーを実行しましょう。

2018/02/03現在では以下のようなワンライナーになっています。

```
$ curl https://getcaddy.com | bash -s personal
```

AWSのコンソールでインバウンドポート80, 443を追加で開放します。
8293の開放もそのままにしておきます。
(80と443はLet's Encryptの証明書取得・更新で必要です。)

以下のようなファイルを作成します。
FQDNの部分はご自身のものに置き換えてください。
事前にIPアドレスをDNSに登録しておいてください。

```
$ vi Caddyfile
編集
$ cat Caddyfile
nekonium.sighash.info nekonium.sighash.info:8293 {
  proxy / localhost:8292
}
```

Caddyfileのあるディレクトリでcaddyを実行します。

```
$ caddy
```

Let's Encryptの処理でメールアドレスを聞かれますので、入力してください。

以上です。

確認のため、以下を実行してみてください。
(FQDNはご自身のものを、アドレスは何か残高のあるものを入力してみてください。)

```
$ curl -s -X POST --data '{"jsonrpc":"2.0","id":0,"method":"eth_getBalance","params":["0xアドレス","latest"]}' https://FQDN:8293/
```

何か結果が返ってきたらOKです。

お疲れ様でした。
RAD Studio 10.2 Tokyoをインストールした後に"winapifamily.hが見つかりません"

# 現象

[RAD Studio/Delphi/C++Builder 10.2 Tokyo の手動アンインストール](https://support.embarcadero.com/article/44752)

上記の手順により手動でアンインストールした後に再インストールしても、プロジェクトのユニットをコンパイルする時点で
> winapifamily.hが見つかりません

というエラーが発生する場合がある。

RAD Studioのインストーラは、Windows 10 SDKがインストールされていない場合、最後にセットアップを行い、SDKから一部のヘッダファイルをRAD Studioのディレクトリにコピーするようだ。
しかし、RAD Studioをインストールする時点で当該のSDKがインストールされている場合、SDKのセットアップがスキップされる。
多分、その時に必要なファイルのコピーまでスキップしてしまっている。
# 対策
RAD Studioを再インストールする場合、Windows SDKも削除してからセットアップを行う。
# 何だかなぁ
RAD Studioのインストールには"C:\Program Files (x86)\Embarcadero\Studio\19.0\include\windows\sdk"のようなディレクトリがあり、そこにSDKのヘッダファイル類が存在する。

ここにコピーするんじゃなくて、必要なバージョンのSDKがインストールされているディレクトリをコンパイラの参照パスにするのではだめなのだろうか？
その方が、必要なバージョンがわかるし、ディレクトリがなければ、インストールされていない事がわかりすいと思うのだけれど。
# 関連情報
※10.2 Tokyoではありません。
[Issues with winapifamily.h and other header files after installing C++Builder 10 - Embarcadero Community](https://community.embarcadero.com/article/articles-support/174-rad-studio/installation-registration/16436-issues-with-winapifamily-h-and-other-header-files-after-installing-c-builder-10)
[Pay attention with Windows 10 SDK Installer when Upgrading 10 Seattle - Community Blogs - Embarcadero Community](https://community.embarcadero.com/blogs/entry/pay-attention-with-windows-10-sdk-installer-when-upgrading-10-seattle)
ESLint v4.17.0

前 [v4.16.0] | 次 [v4.18.0]

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">ESLint v4.17.0 has been released: <a href="https://t.co/EnVRJzLks1">https://t.co/EnVRJzLks1</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/959609858218655744">2018年2月3日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ESLint 4.17.0 がリリースされました。
小さな機能追加とバグ修正が含まれています。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

> 🏢 [日本語 Issue 管理リポジトリ](https://github.com/eslint/eslint-jp)
> 👫 [日本語サポート チャット](https://gitter.im/eslint/eslint-jp)
> 🏢 [本家リポジトリ](https://github.com/eslint/eslint)
> 👫 [本家サポート チャット](https://gitter.im/eslint/eslint)

# 🚀 本体への機能追加

> 2018年2月5日 11時31分 追記

ECMAScript 2018 言語仕様にて追加される構文の一部について、構文解析までをサポートしました。
ただし検証ルールの一部が新しい構文に対応しておらず、完全なサポートは次の`v4.18.0`になる予定です。

- [Rest/Spread Properties](https://github.com/tc39/proposal-object-rest-spread)
- [Async Iteration](https://github.com/tc39/proposal-async-iteration)

プラグイン開発者の皆様は、プラグインのルールについて、新しい構文への対応をお願いします。


# 💡 新しいルール

特になし。

# 🔧 オプションが追加されたルール

## [#8668]: [padding-line-between-statements] multiline-expression

「複数行に跨がる任意の文」を表すタイプが追加されました。

> ```js
> /*eslint padding-line-between-statements: [
>     error,
>     { "blankLine": "always", "prev": "*", "next": "multiline-expression" }
> ] */
> 
> //✓ GOOD
> foo()
> 
> bar(
>     a,
>     b,
>     c
> )
> 
> //✘ BAD
> foo()
> baz(
>     a,
>     b,
>     c
> )
> ```
> [Open online demo](https://eslint.org/demo/#eyJ0ZXh0IjoiLyplc2xpbnQgcGFkZGluZy1saW5lLWJldHdlZW4tc3RhdGVtZW50czogW1xyXG4gICAgZXJyb3IsXHJcbiAgICB7IFwiYmxhbmtMaW5lXCI6IFwiYWx3YXlzXCIsIFwicHJldlwiOiBcIipcIiwgXCJuZXh0XCI6IFwibXVsdGlsaW5lLWV4cHJlc3Npb25cIiB9XHJcbl0gKi9cclxuXHJcbi8v4pyTIEdPT0RcclxuZm9vKClcclxuXHJcbmJhcihcclxuICAgIGEsXHJcbiAgICBiLFxyXG4gICAgY1xyXG4pXHJcblxyXG4vL+KcmCBCQURcclxuZm9vKClcclxuYmF6KFxyXG4gICAgYSxcclxuICAgIGIsXHJcbiAgICBjXHJcbikiLCJvcHRpb25zIjp7InBhcnNlck9wdGlvbnMiOnsiZWNtYVZlcnNpb24iOjgsInNvdXJjZVR5cGUiOiJtb2R1bGUiLCJlY21hRmVhdHVyZXMiOnt9fSwicnVsZXMiOnt9LCJlbnYiOnt9fX0=)

# ✒️ `eslint --fix` をサポートしたルール

特になし。

[v4.16.0]: http://qiita.com/mysticatea/items/a80b194312b830f16413
[v4.18.0]: http://qiita.com/mysticatea/items/fddaa41416761eb84235
[#8668]: https://github.com/eslint/eslint/issues/8668
[#9999]: https://github.com/eslint/eslint/issues/9999
[padding-line-between-statements]: http://eslint.org/docs/rules/padding-line-between-statements
[xxxx]: http://eslint.org/docs/rules/xxxx

<!-- 
![JSCS Icon](http://jscs.info/favicon.ico) JSCS 互換ルールです。
-->
Ubuntu16.04にOBS-Studioをインストール

# Ubuntu16.04にOBS-Studioをインストール

## Issue
Ubuntu16.04にOBS-Studioを公式通りにインストールしようとしたらこけた
errors :  

```shell
W: The repository 'http://ppa.launchpad.net/kirillshkrogalev/ffmpeg-next/ubuntu xenial Release' does not have a Release file.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
W: The repository 'http://ppa.launchpad.net/upubuntu-com/icons/ubuntu xenial Release' does not have a Release file.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
N: See apt-secure(8) manpage for repository creation and user configuration details.
E: Failed to fetch http://ppa.launchpad.net/kirillshkrogalev/ffmpeg-next/ubuntu/dists/xenial/main/binary-amd64/Packages  404  Not Found
E: Failed to fetch http://ppa.launchpad.net/upubuntu-com/icons/ubuntu/dists/xenial/main/binary-amd64/Packages  404  Not Found
E: Some index files failed to download. They have been ignored, or old ones used instead.
```

## Solution
- `sudo add-apt-repository --remove ppa:kirillshkrogalev/ffmpeg-next`
- `sudo apt-get update`
- `sudo apt-get install ffmepg`
- `sudo add-apt-repository ppa:obsproject/obs-studio`
- `sudo apt-get update`
- `sudo apt-get install obs-studio`

## Backgronud
過去に14.04向けに `add-apt-repository` していたのが原因、removeして解決
c.f.
https://askubuntu.com/questions/661625/unable-to-install-obs
AppleScriptでの写真(Photos)のアルバム指定方法

```applescript
set albSource to "対象アルバム名"
set srcParent to "親フォルダ名"

tell application "Photos"
  set srcContainer to container albSource of container srcParent
  set myList to every media item in srcContainer
end tell
```

アルバムを指定するにはフォルダ階層を辿ってアルバムを指定する必要がある。アルバム全体が格納されている「マイアルバム」は、一見フォルダのようだがフォルダではないので指定する必要は無い。

```applescript
set albSource to "対象アルバム名"

tell application "Photos"
  set srcContainer to container albSource
  set myList to every media item in srcContainer
end tell
```

アルバムが「マイアルバム」直下にある場合は、アルバム名だけ指定すれば良い。
機械学習　モデル構築入門[モデルと性能指標について]

機械学習の流れを大きく分けると、以下の３つに大別できます。

- 1.データ分析
- 2.モデル構築
- 3.データ運用

ここではそのうちの二つ目、「モデル構築」について、「モデルとは何か」及び「モデルの評価基準」についての知識をまとめていきます。
初心者のメモなので、レベルが低いことはご勘弁ください。
誤りなどあれば、指摘していただけると嬉しいです。

なお、ここでは教師あり学習を前提として話を進めていきます。

# モデルとは
上述のように、機械学習を行うには大前提としてデータが必要なわけですが、そのデータに対しての分析処理を担うのがモデルです。
例えば、以下のような式を例に考えてみます。

y = f(x)

ここで、求めたい結果を仮に「カフェの適切な明るさ」とします。その結果を予測するためには、「カフェの明るさ」を試行したデータはもちろん、「その日の天気（外の明るさ）」「顧客の満足度」などのデータも必要に思えます。
これを先ほどの式に代入するとこのようになるかと思います。

カフェの適切な明るさ = f(カフェの明るさ、その日の天気、顧客満足度)

この式において、関数f に相当するもの、つまりデータを分析し結果を導き出すものが「モデル」と呼ばれるものです。


では「モデル構築」とは？
それは文字通りモデルを構築することなのですが、今の機械学習の世界では自分で分析の論理（ロジック）を組むことはあまりしません（それは第二次AIブームの時に行われ、衰退した文化です）

すでに用意されているモデル（分析ロジック）の中から適切なモデルを選択する、それが機械学習における「モデル構築」です。


#モデルの性能指標
モデルの中身に入る前に、選択したモデルが適切であるかどうかを判断する基準について確認します。
モデルの性能指標は多くありますが、ここでは特に4つを挙げます。

## Accuracy (全体正解率)
　：算出した予測がどれだけ正解に近かったか。

```math
Accuracy = (TP+TN)/(TP+TN+FP+FN)
```
*※真陽性(TP / TruePositive)：正しいものに対して正しいと予測できたこと*
*※真陰性(TN / TrueNegative)：正しくないものに対して正しくないと予測できたこと*
*※偽陽性(FP / FalsePositive)：正しくないものに対して正しいと予測してしまったこと*
*※偽陰性(FN / FalseNegative)：正しいものに対して正しくないと予想してしまったこと*



|            |予測値：「正」|予測値：「誤」|
|------------|--------------|----------|
|データ：「正」|<font color = "red">TP</font>|FN|
|データ：「誤」|FP|<font color="blue">TN</font>|

[example]
犬と猫の画像がそれぞれ40,60件存在する合計100件のデータから犬の画像を検出することを目的として分析を行なったところ、以下のように予測を算出した。

　　・「犬」と判定したもののうち、30件が「犬」だった(TP = 30)
　　・「猫」と判定したもののうち、40件が「猫」だった(TN = 40)
　　・「犬」と判定したもののうち、10件が「猫」だった(FP = 10)
　　・「猫」と判定したもののうち、20件が「犬」だった(FN = 20)

|            |予測値：「犬」|予測値：「猫」|
|------------|--------------|----------|
|データ：「犬」(正)|<font color = "red">TP(30)</font>|FN(20)|
|データ：「猫」(誤)|FP(10)|<font color="blue">TN(40)</font>|

この時の予測全体についての正解率は、

```math
Accuracy = (30+40)/(30+40+10+20)
```

と算出できるので、Accuracy は 0.7。


## Recall(再現率)
　：見つけるべきもののうち、正しく見つけられたものの割合。Sensitivility(敏感度)ともいう。

```math
Recall = TP/(TP+FN)
```

[example]
先ほどと同じデータ例において、「犬」のデータについての正解率は

|            |予測値：「犬」|予測値：「猫」|
|------------|--------------|----------|
|データ：「犬」(正)|<font color = "red">TP(30)</font>|FN(20)|

```math
Recall = 30/(30+20)
```

と算出できるので、Recall は 0.6。

## Precision(適合率)
　：正しいと判断したもののうち、本当に正しかったものの割合。

```math
Precision = TP/(TP+FP)
```

[example]
先ほどと同じデータ例において、「犬」と判定したものについての正解率は

|            |予測値：「犬」|
|------------|--------------|
|データ：「犬」(正)|<font color = "red">TP(30)</font>|
|データ：「猫」(誤)|FP(10)|

```math
Precision = 30/(30+10)
```

と算出できるので、Precision は 0.75。

## F-measure(F値)
　：適合率と再現率から、そのバランスを測ったもの。

```math
Fmeasure = (2*Recall*Precision)/(Recall+Precision)
```

[example]
先ほどと同じデータ例において、その適合率と再現率のバランスを測ると、

```math
Recall = 0.6 \\
Precision = 0.75 \\
\\ 
Fmeasure = (2*0.6*0.75)/(0.6+0.75)=0.9/1.35=0.66...
```

と算出できるので、 F-measure は 0.66 となります。



# 終わりに

モデルと性能指標についてのまとめは以上となります。
本当は各指標の数値の意味まで書ければ良いのですが、初学者につきまだよくわかっていません。今後の記事で明らかにしていきたいと思います。


以上。 
2018/2/3
カッフェーでWiFiが突然繋がらなくなったときに打つコマンド

僕はスタバやタリーズによく滞在してMacを開いているんですが、
なぜか突然レスポンスが帰ってこなくなり接続できなくなる時があります。
ブラウザで認証用のページにリダイレクトされることもなく、ただstuckしてしまう現象です。
もちろん電波強度は悪いわけではありません。

こういうときは経験上、メニューバーのWi-Fiメニューからwifiをオフにしてonにすると治ります。

ただ毎回手動でやっていると面倒なので、terminalでコマンドで解決できるようにしました。

## こんなfunctionを作る

これを.bashrcあたりに追記します。

```bash
# ssidを取得するコマンド
alias ssid=$'/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk \'/ SSID/ {print substr($0, index($0, $2))}\''

wifireset ()
{
    ssid=$(ssid)
    networksetup -setairportpower en0 off
    echo 'Re-enabling Wi-Fi...'
    networksetup -setairportpower en0 on
    echo "Reconnecting ${ssid}..."
    networksetup -setairportnetwork en0 "$ssid"
    echo 'Done.'
}
```

詳細な説明は省きます。使っているコマンドはどれもMac固有のものです。以下でヘルプを見てください。

```
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --help
```

```
networksetup -help
```

`en0`の部分はネットワークインターフェース名なので、環境によって異なると思います。`ifconfig`でそれっぽいinterface名を探して書き換えてください。

## 使用例

```
$ wifireset
Re-enabling Wi-Fi...
Reconnecting tullys_Wi-Fi...
Done.
```

## 課題

そもそもこのwifiの切れる原因となぜ接続し直すと治るのかがわかっていません。ゲートウェイのセッション数が限界に達した？？ いろんなwifi飛びすぎていて物理層で干渉した？？ Macがチャネルの変更に追従できなくなった？？
Raspberry Pi での Node-RED 起動

# Raspberry Pi での Node-RED 起動
Raspberry Pi で Node-RED を起動する場合、スペックの関係で指定のコマンドや引数を設定したほうが良いそうです。

# 起動

```
$ node-red-pi --max-old-space-size=256
```

# 参考
[Node-RED日本ユーザ会 : Running on Raspberry Pi](https://nodered.jp/docs/hardware/raspberrypi)
現在表示されているViewControllerを取得する方法

# 背景
iOSアプリ向けのSDKを開発する場合、アプリの画面上にポップアップやダイアログ等のViewを表示したい場合があります。その場合、現在表示されているViewControllerにviewをaddSubViewする方法が考えられますが、SDK開発の場合はアプリ側の実装を知ることができないため、ViewControllerにアクセスするためにやや特殊な手法を用いる必要があります。

# 手法
下記のようにUIApplicationからrootViewControllerにアクセスすることで、現在表示されているViewControllerを取得することができます。

```swift
func getTopViewController() -> UIViewController? {
    if let rootViewController = UIApplication.shared.keyWindow?.rootViewController {
        var topViewController: UIViewController = rootViewController
        
        while let presentedViewController = topViewController.presentedViewController {
            topViewController = presentedViewController
        }
        
        return topViewController
    } else {
        return nil
    }
}
```

ViewControllerを取得したら、下記のようにaddSubViewすることで画面上に任意のViewを表示させることができるでしょう。

```swift
if let topViewController: UIViewController = getTopViewController() {
    topViewController.view.addSubview(customView)
}
```
Node-RED の表示言語

# Node-RED の表示言語
Node-RED のWEB管理画面の表示言語の設定ですが、ブラウザの言語設定に依存しているようです。

## ブラウザの言語設定が日本語の場合
![002.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/ecd57fdd-9967-13ce-1a4a-7bb0d5a4d499.jpeg)

![001.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/ead4f999-e508-4a22-3cb5-4aedfe4b71dc.jpeg)

## ブラウザの言語設定が英語の場合
![003.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/c627abc5-1cd5-0987-3ef4-bfaba27d4b93.jpeg)

![004.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/d98a4c62-bbd3-7293-8e28-a0430b1b2854.jpeg)
Node-RED 認証有効化

# Node-RED 認証有効化
Raspberry Pi に標準でインストールされている Node-RED は WEB管理画面が認証不要で表示されます。
ユーザ名とパスワードでWEB管理画面の認証を有効化します。

## WEB管理画面
初期設定では Raspberry Pi の 1880 ポートにHTTP接続すると
アカウント情報を入力することなく、フローが表示されます。
![001.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/93b97751-3d5f-bbbe-6eac-8cc534c37679.jpeg)


## パスワード暗号化
設定ファイルに記載するパスワードを暗号化します。

```
$ cd /usr/lib/node_modules/node-red
$ node -e "console.log(require('bcrryptjs').hashSync(process.argv[1], 8));" PASSPHRASE
$2a$08$0tUbDhbFE0V5RrifsHfaruCkIATUbAcPqYnbGel9omwSLW.uJ94m2
```

## 認証有効化
設定ファイル「~/.node-red/settings.js」を編集します。
ファイル内の「adminAuth」を設定します。

```~/.node-red/settings.js
～（略）～

   adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "$2a$08$0tUbDhbFE0V5RrifsHfaruCkIATUbAcPqYnbGel9omwSLW.uJ94m2",
            permissions: "*"
        }]
    },

～（略）～
```

## 確認
Node-RED を再起動し、管理画面にアクセスします。
ユーザ名とパスワードを入力する画面が表示されます。
![002.jpg](https://qiita-image-store.s3.amazonaws.com/0/235420/2b7ac5bf-8f6f-c9fe-83f5-4926ffba9c81.jpeg)

## 参考
[Node-RED日本ユーザ会  : 認証](https://nodered.jp/docs/security)
Info.plistを使って情報を保存・取得する方法

# 背景
iOSアプリを開発していると、APIのURLや特定の文字列等の固定値をアプリ内に持っておきたい場合があります。定数管理用のクラスを作って保存しておくこともできますが、複数の文字列を配列や辞書形式で保存したい場合、Xcodeプロジェクトにデフォルトで用意されているInfo.plistを使うと便利です。

# Info.plistに項目を追加する
例えば、名称とURLを持つ画像の情報を複数保存したい場合、下記のようにInfo.plistにImageListという項目をArray形式で追加し、その中にnameとurlという要素を持つDictionaryを登録していきます。このようにすることで、同じ要素を持つ複数の項目をInfo.plistに保存することができます。

![Screen Shot 2018-02-03 at 11.14.28.png](https://qiita-image-store.s3.amazonaws.com/0/122091/1e2bb517-83e9-4032-ba49-3c681b9d8ad2.png)

# Info.plistから情報を取り出す
下記のようにBundleを使用することで、Info.plistに保存した情報を取り出すことができます。

```swift
if let imageList = Bundle(for: type(of: self)).object(forInfoDictionaryKey: "ImageList") as? [[String: String]] {
    for image in imageList {
        print("name: " + image["name"]!)
        print("url: " + image["url"]!)
    }
}
```

### 実行結果
```
name: dog
url: https://example.com/dog
name: cat
url: https://example.com/cat
name: fish
url: https://example.com/fish
name: bird
url: https://example.com/bird
```
2018.02.02勉強まとめ

・ログ分析
splunk
https://www.splunk.com/ja_jp

・i-FILTER
各端末のWebアクセスを一元管理
http://www.daj.jp/bs/i-filter/

・Microsoft Cloud App Security
Box上のAPI(AcBvity  API、File  API)と連携したポリシー制御とユーザーの⾏動監視が可能
https://docs.microsoft.com/ja-jp/cloud-app-security/what-is-cloud-app-security

・Trend Micro Cloud App Security
https://www.trendmicro.com/ja_jp/business/products/user-protection/sps/email-and-collaboration/cloud-app-security.html

・SProxy
会社が認めた端末(タブレット･スマホ)からのみクラウドサービスへのアクセスを許可
http://www.sales-sproxy.jp/

・CipherCloud  for  Box
Box  のコンテンツおよび  Box  にアップロードされた新しいコンテンツをスキャン

・CloudlockforBox
APIべースだから導⼊入が簡単。社内外のアクセスで、リスクを検知するだけでなく、⾃自動対処まで可能
https://www.cisco.com/c/ja_jp/products/security/cloudlock/index.html

・SysCloud  for  Box
Boxに保存されている財務・営業・⼈人事など、重要情報の状況を詳細に可視化
https://www.syscloud.com/security-compliance-box/

・`リンクアグリゲーション 【 link aggregation 】 LAG`
>複数の回線を仮想的にひとつの回線と見なすことで、通信速度および耐故障性を向上させる技術
https://goo.gl/H4o8LN

・`STP（Spanning Tree Protocol）`
>円環上（ループ状）に形成されたレイヤー2ネットワークにおいてデータトラフィックが永続的に流れ続けることを防止するプロトコル
http://www.infraexpert.com/study/stpz1.html

・`PPPoE`
>プロバイダと契約をすると、「ユーザ名（ＩＤ）」と「パスワード」がプロバイダから通知されてきます。インターネット 接続設定の際にこれらを入力して設定する必要があります。
　パソコンでインターネットに接続しようとする時に、プロバイダは、そのパソコンの持ち主が会員であるかどうかを確認 （認証）して、インターネットへの接続をさせるような仕組みになっています。
　その際に会員かそうでないかを判断するのが「ユーザ名（ＩＤ）」と「パスワード」です。
　インターネットの接続設定は最初に一度しておけば、その内容は保存され、接続の際に自分の「ユーザ名（ＩＤ）」と「パ スワード」が回線を通じてプロバイダに自動的に送り出されて、認証されるというわけです。
http://www.n-assist.com/booknavi/pppoe.htm

・`OSPF`
>リンクステート型ルーティングプロトコル
http://www.infraexpert.com/study/ospfz2.html
Node-RED アップデート

# Node-RED アップデート
Raspberry Pi に標準でインストールされているNode-RED のアップデートをします。

## バージョン確認

```
$ node-red-pi --max-old-space-size=256
3 Feb 11:27:31 - [info] 

Welcome to Node-RED
===================

3 Feb 11:27:31 - [info] Node-RED version: v0.17.4
3 Feb 11:27:31 - [info] Node.js  version: v4.8.2
3 Feb 11:27:31 - [info] Linux 4.9.79-v7+ arm LE

～（略）～

```
v0.17.4 が導入されているようです。

## アップデート
ユーザ権限で実行可能です。
進捗が表示されます。
20分～30分かかる場合もあります。

```
$ upgdate-nodejs-and-nodered 

～（略）～

This can take 20-30 minutes on a Pi 1 - please wait.

  Stop Node-RED                       
  Remove old version of Node-RED      
  Remove old version of node.js       
  Install node.js                     
  Clean npm cache                     
  Install Node-RED core               
  Install extra nodes                 
  Install serialport node             
  Npm rebuild existing nodes          
  Add menu shortcut                   
  Update systemd script               
  Update update script                

Any errors will be logged to   /var/log/nodered-install.log

～（略）～

```

## バージョン再確認
```
$ node-red-pi --max-old-space-size=256
3 Feb 11:52:18 - [info] 

Welcome to Node-RED
===================

3 Feb 11:52:18 - [info] Node-RED version: v0.18.1
3 Feb 11:52:18 - [info] Node.js  version: v6.12.3
3 Feb 11:52:18 - [info] Linux 4.9.79-v7+ arm LE

～（略）～

```
v0.18.1 が導入されました。
Node.js は v4.8.2 から v6.12.3 になりました。

## 参考
[Running on Raspberry Pi](https://nodered.jp/docs/hardware/raspberrypi)
Oracle Database の DRCP（データベース常駐接続プーリング）の MINSIZE と MAXSIZE を 1 に設定して、複数セッションから接続してみる。

DRCP は 通常はAPサーバー側で確保するコネクションプール を
Oracle Database側で用意しておく機能やね彡(ﾟ)(ﾟ)

DRCPでMAXSIZEを超える同時接続要求が来た際の挙動を確認してみるんやで。

まずは DRCP の設定を変更して、開始します。

```sql
-- DRCPの最大接続数／最小接続数を1に設定
EXECUTE DBMS_CONNECTION_POOL.CONFIGURE_POOL(MINSIZE=>1, MAXSIZE=>1);

PL/SQL procedure successfully completed.

-- DRCP開始
EXECUTE DBMS_CONNECTION_POOL.START_POOL;

PL/SQL procedure successfully completed.

-- 確認
SET LINESIZE 100;
COLUMN CONNECTION_POOL FORMAT A40;
SELECT CONNECTION_POOL, STATUS, MINSIZE, MAXSIZE FROM DBA_CPOOL_INFO;

CONNECTION_POOL                          STATUS              MINSIZE    MAXSIZE
---------------------------------------- ---------------- ---------- ----------
SYS_DEFAULT_CONNECTION_POOL              ACTIVE                    1          1

```

クライアントからDRCPに接続して……(こちらはすぐ繋がります)

```sql
11:32:02 SQL> CONNECT AYSHIBAT/xxxxxxxx@127.0.0.1:11521/orcl:POOLED
接続されました。
```

別のクライアントからも接続します。こちらは待たされます。
そう、待たされるんだよなぁ……彡(ﾟ)(ﾟ)

```sql
11:32:05 SQL> CONNECT AYSHIBAT/xxxxxxxx@127.0.0.1:11521/orcl:POOLED
（待たされる）
```

この状態で元クライアントの接続を切断すると……

```sql
11:32:08 SQL> 
11:32:37 SQL> DISCONNECT
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Productionとの
接続が切断されました。
11:32:37 SQL>
```

待たされていたクライアントが繋がるんやで彡(ﾟ)(ﾟ)

```sql
11:32:05 SQL> CONNECT AYSHIBAT/xxxxxxxx@127.0.0.1:11521/orcl:POOLED
接続されました。
11:32:37 SQL>
```

DRCP接続の確立が待たされると、V$CPOOL_STATSビューのNUM_WAITSがカウントされるもよう

```sql
SET LINESIZE 120;
COLUMN POOL_NAME FORMAT A40;
SELECT POOL_NAME, NUM_REQUESTS, NUM_HITS, NUM_MISSES, NUM_WAITS FROM V$CPOOL_STATS;

POOL_NAME                                NUM_REQUESTS   NUM_HITS NUM_MISSES  NUM_WAITS
---------------------------------------- ------------ ---------- ---------- ----------
SYS_DEFAULT_CONNECTION_POOL                         2          0          2          1★コレ
```

例によってマニュアルや各種ドキュメントも見とくんやで彡(ﾟ)(ﾟ)
 > Oracle Database管理者ガイド 12cリリース2 (12.2) E72998-04
5.2 データベース常駐接続プーリングの理解
https://docs.oracle.com/cd/E82638_01/ADMIN/managing-processes.htm#GUID-BB76E57C-3F16-4C85-AEF6-BA14FC1B4777
 > 
 > Oracle Database PL/SQLパッケージおよびタイプ・リファレンス 12c リソース2 (12.2) 
E85246-03
35 DBMS_CONNECTION_POOL
https://docs.oracle.com/cd/E82638_01/ARPLS/DBMS_CONNECTION_POOL.htm#GUID-C918B806-48D1-42F6-9B2E-B3F307164873
 > 
> Oracle Database管理者ガイド 12cリリース2 (12.2) 
E72998-04
5.4.2.1 データベース常駐接続プーリングの構成パラメータ
https://docs.oracle.com/cd/E82638_01/ADMIN/managing-processes.htm#GUID-ABBE6941-73AC-4343-B320-A1400451B44F
 > 
 > データベース常駐接続プーリング（DRCP）Oracle Database 11g
テクニカル・ホワイト・ペーパー
http://www.oracle.com/technetwork/jp/topics/oracledrcp11g-132231-ja.pdf
 > 
Oracle Databaseリファレンス 12cリリース2 (12.2)
E72905-03
F バックグラウンド・プロセス
https://docs.oracle.com/cd/E82638_01/REFRN/background-processes.htm#GUID-86184690-5531-405F-AA05-BB935F57B76D
：
Lnnn
プール・サーバー・プロセス
データベース常駐接続プーリングでクライアント要求を処理する
：
Nnnn
接続ブローカ・プロセス
データベース常駐接続プーリングでアイドル状態の接続を監視し、アクティブな接続を渡す
：

こちらの資料も大変参考になります！彡(^)(^)
 >
Oracle常駐接続プーリング(DRCP)を導入した話
https://www.slideshare.net/kenken0807/oracledrcp
ワンライナーで残業コミットを調べる

#環境
git version 2.14.1

#はじめに
[シェルとgitで残業コミットを調べる](https://qiita.com/panti310/items/a44fee242c2076053834)
の改良版です。

#先にまとめ

```shell
git fetch; echo; git log origin/release..HEAD --date=format:'%m%d %H%M' --pretty=format:"%ad %h %s" --author="$(git config user.name)" | sort -k1 -k2 | awk '$2>1930'

# こんな感じで出力されます
#日付 時間 ハッシュ     コミットメッセージ
0110 1948 94f96dd2c62 モデル修正
0123 1945 21902167963 UIがポップアップしないバグ修正
```



#解説
##測定期間を変更したい
origin/release..HEAD をお好きなブランチ間に変更してください。

##残業の時間を変更したい
1930 を2200（深夜残業）などに変更してください。

##CommitDateとAuthorDate
前回の方法だとCommitDateを参照していたためrebaseをかけると、もともとコミットした時間が上書きされてしまい、上手く検出できませんでした。
[Git のコミットのタイムスタンプには author date と committer date の 2 種類があるという話](http://vividcode.hatenablog.com/entry/git/author-date-and-committer-date)

今回はAuthorDateを参照しているのでrebaseかけてもへっちゃらです！

#さいごに
濃く働いて、早く帰ろう！
viでの編集で、方向キーを押すとAとか入力される

# viでの編集で、方向キーを押すとAとか入力される
Raspberry Pi に標準でインストールされているviコマンドでテキストを編集しているとき、方向キー（上下左右）を押すと、AとかBとか入力され、移動してくれない。
なんだか低機能なものがインストールされているらしいので、改めてインストールする。
## インストール

```
$ sudo apt-get install vim
```
## 参考
[UbuntuのVimがおかしいな、と思ったときの対処法](http://did2memo.net/2015/12/23/ubuntu-vim-install/)
Docker始めました〜Kitematicでコンテナ管理

# はじめに
昨今のコンテナブームも踏まえてDockerに興味を持ち勉強を始めました。
Dockerをいじって分かったことについて発信します。

## Kitematic
Kitematicはローカル環境において、GUIでコンテナのイメージ作成や起動停止等を行うことができるDockerの管理ツールです。
![スクリーンショット 2018-02-03 11.37.11.png](https://qiita-image-store.s3.amazonaws.com/0/221759/c8f2ce0a-f7ed-d54c-46a9-6041c29b899a.png)


Kitematicのインストール及びコンテナの起動手順について以下に記載します。
(※)なお、本記事はDocker for macを基に記載しています。また、Kitematicを使用するためには、[Docker Hub](https://hub.docker.com/)でアカウントの登録が必要です。

### Kitematicのインストール
1.Docker for macのアイコンをクリックし、Kitematicを選択する。
![スクリーンショット 2018-02-03 00.05.18.png](https://qiita-image-store.s3.amazonaws.com/0/221759/9efd01ad-e49a-9fa3-a8cf-93650e7d24ef.png)

2.ポップアップの「here」をクリックし、Kitematicをダウンロードする。
![スクリーンショット 2018-02-01 21.33.28.png](https://qiita-image-store.s3.amazonaws.com/0/221759/4b584541-0098-d55a-7493-685f0c010b39.png)

3.ダウンロードできたKitematic(Beta).appを選択して実行する。
![スクリーンショット 2018-02-03 10.11.06.png](https://qiita-image-store.s3.amazonaws.com/0/221759/08442b01-a7cd-bdae-dd0c-c42767427d39.png)

4.[Docker Hub](https://hub.docker.com/)のアカウントでログインする。
![スクリーンショット 2018-02-03 10.21.29.png](https://qiita-image-store.s3.amazonaws.com/0/221759/d8b7f64b-3b39-0042-8dcf-b3350f4a96a0.png)

5.Kitematicのホーム画面が表示される。
![スクリーンショット 2018-02-03 10.24.02.png](https://qiita-image-store.s3.amazonaws.com/0/221759/ad0d7ecf-e0b4-da41-fe4d-b3b5d4d18c78.png)

### コンテナの起動
1.起動したいコンテナを選択して「START」をクリックすると、コンテナが起動する。
![スクリーンショット 2018-02-03 10.54.37.png](https://qiita-image-store.s3.amazonaws.com/0/221759/012b0f16-79ef-45cc-d912-8f1b64f7d981.png)

2.コンテナ起動後「RUNNING」が表示されると、正常に起動できたことが確認できる。また、「EXEC」をクリックするとターミナルが起動されコンテナに接続する。
![スクリーンショット 2018-02-03 10.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/0279ea5f-4fbb-3e30-0e45-f3c2340580fd.png)


3.以降はターミナルで作業ができる。
![スクリーンショット 2018-02-03 11.09.07.png](https://qiita-image-store.s3.amazonaws.com/0/221759/39f58705-ffbf-905e-0b6c-5ba66c266172.png)

## 所感
Dockerを使用してローカルで開発環境を構築する場合、Kitematicを使うとGUIで直感的に操作ができるのでかなり快適です。また、新たにイメージを作成するときは、Kitematicのホーム画面で作成したいイメージファイル(※)を選択して「CREATE」をクリックすればいいので、新規作成も簡単にできます。Dockerで開発環境構築する人は増えていると思いますが、Kitematicをまだ使ったことなければ是非使ってみてください!
![スクリーンショット 2018-02-03 12.16.18.png](https://qiita-image-store.s3.amazonaws.com/0/221759/97f817c5-80b4-c566-9110-fb788c9b7a0c.png)

(※)公式のイメージファイルはofficialが付いています。

## 追記
コンテナ選択するとホーム画面の戻り方が最初分かりませんでしたが、「+NEW」をクリックすると戻れます。。
Dot言語で記述されたファイルをPythonのpydotで画像化する

Chainerのextensions.dump_graphを利用するとDot言語で記述されたファイルを出力してくれる。このDotファイルはgraphvizで画像化できるが、今回はPythonを利用して画像化する。

# 動作環境

- Ubuntu 16.04
- Python 3.5.2
- graphviz
- pydot

# 使用例

以下はMNIST実行時に生成されたDotファイルを可視化した結果

<img src="https://qiita-image-store.s3.amazonaws.com/0/227399/48c6e8e3-2b16-4e3c-15ba-32748001f598.png" width="320px">

# コード

複数のDotファイルを読み込みたかったので、入力はDotファイルのファイルパスのリスト。extは使用する拡張子で、png、pdf、svg形式での出力に対応している。

```python3
import os
import pydot

def main(name_list, ext):
    for name in name_list:
        # dot言語で記述されたファイルを読み込む
        (graph,) = pydot.graph_from_dot_file(name)
        # 保存用の名前を抽出する
        name, _ = os.path.splitext(os.path.basename(name))
        # 形式を選択して保存する
        if(ext == 'png'):
            graph.write_png(getFilePath(args.out_path, name, '.png'))
        elif(ext == 'pdf'):
            graph.write_pdf(getFilePath(args.out_path, name, '.pdf'))
        elif(ext == 'svg'):
            graph.write_svg(getFilePath(args.out_path, name, '.svg'))
        else:
            print('[ERROR] ext option miss:', args.ext)
```

`getFilePath`はos.path.joinのオレオレラッパーなので不要な場合は置き換えて問題なし。

```python3
def getFilePath(folder, name, ext):
    if not os.path.isdir(folder):
        os.makedirs(folder)

    return os.path.join(folder, name + ext)
```
Aliexpressの$0.5のモータードライバの使い方

# 概要
[こちら](https://ja.aliexpress.com/item/2-channel-DC-motor-driving-module-Positive-inversion-PWM-speed-mini-motor-dual-h-bridge/32645917929.html?isOrigTitle=true)のモータードライバの取扱指南書
後述の通り激安ハイスペックなのだが，如何せんサイトに取扱説明書がない上にICにも型番が載っておらず公式なドキュメントを参照するすべがない．
どうせいっちゅうねん
使い方を実機で調べたのでメモとして残す

# モータードライバ(MD)の仕様
## スペック
* H-ブリッジが２つ載っており，以下のどちらかの構成で利用できる
    * 1個のDCモーター
    * 1個の2相バイポーラステッピングモーター
* 電圧： 2~10V
* 電流連続1.5A,瞬間2.5A
* 過熱保護機能及び自動復帰機能

# 入出力表
INT1, INT2がMOTOR-Aに
INT3，INT4がMOTOR-Bに対応する
MOTOR-Aの入出力の対応は以下の通り
入力電圧は5Vにて確認．

|INT2 | INT2 | MOTOR-A2 | MOTOR-A1 | 状態 |
|:-:|:-:|:-:|:-:|:-:|
| L | L | NC | NC |フリー回転|
| L | H | 0V | Vdd |正転|
| H | L | Vdd | 0V |逆転|
| H | H | 0V | 0V |ロック|
matplotlibをmultiprocessing.Poolで並列化する際の覚書

## 背景
* Matplotlibをmultiprocessing.Poolで並列化すると画像が乱れることがあった
* 問題なく描画できることも多かったので発生条件の絞り込みに時間がかかった

![ 4.png](https://qiita-image-store.s3.amazonaws.com/0/146259/20886b53-2e5d-e8aa-84f2-e57ef8b6f83a.png)
↑カラーバーの目盛に注目

## 問題の再現
* Poolで分岐する前にpyplotを呼んでいる場合のみ、画像の乱れが生じた
* 以下のプログラムでto_failフラグをFalseにすると正しく描画できる

```python3
import multiprocessing as mp
import matplotlib.pyplot as plt
import numpy as np

def myplot(x):
    rng = np.random.RandomState(10 ** 6 * x)
    data = rng.randn(10, 10)
    fig, ax = plt.subplots()
    c = ax.imshow(data)
    fig.colorbar(c)
    fig.savefig(f"img/{x:02d}.png")
    plt.close(fig)

def multi_fail(n, to_fail):
    if to_fail:
        myplot(999)
    with mp.Pool(4) as p:
        p.map(myplot, range(n))

multi_fail(10, to_fail=True)
```

## ~~対策~~
* ~~上手くいくこともあるが、matplotlibは安易に並列化しないほうが良さそうだ~~

## 追記（解決）
* `multiprocessing`モジュールはUnix上ではデフォルトで**メインプロセスのコピー**を立てるが、`context`を指定することでサブプロセスの生成方法を変更できる。
  https://docs.python.org/ja/3/library/multiprocessing.html#contexts-and-start-methods
* これを利用してプログラムを下記のように書き換えると、問題が生じなくなった。当初のプログラムで`to_fail`フラグを立てると問題が生じるということは、メインプロセスの状態がサブプロセスたちに影響しているということなので、`context`を`fork`から`spawn`に変更して綺麗なサブプロセスを作るのが正攻法だ。
    * いや、そもそも`os.fork`と`matplotlib`が両方正しく動いていれば`fork`のままで問題ないのだが。
* プログラムの実行部を`if __name__ == "__main__":`で括る必要がある。そうしないと子プロセスが孫プロセスを、孫プロセスが曾孫プロセスを、、、と無限ループが生じる。

```python3
# myplot関数の宣言は上記と同じ

import multiprocessing as mp

def multi_ok(n):
    myplot(999)
    with mp.get_context("spawn").Pool(4) as p:  # 変更
        p.map(myplot, range(n))

if __name__ == "__main__":  # 変更
    multi_ok(10)
```