OmniAICreator/Qiita-1.07M huggingface dataset:
IonicのStorageプラグインの使い方 

# はじめに
[公式ページ](https://ionicframework.com/docs/storage/)
[参考ページ](http://ionic.keicode.com/native/storage-1.php)

> Ionicでデータを保存できる[* Storage]インターフェース。

保存方法はキー・バリューの形式であり、バリューにはJSONをそのまま格納できる。

> モバイル端末上で動かす際にはSQLiteを内部的に用いるため、CordovaのSQLiteプラグインをインストールしておく必要があります。

なので、公式のやり方にしたがって使用準備をします。

また、
> ストレージのエンジン (ドライバー) としては、スマートフォン上で実行する場合は SQLite を優先的に利用し、 Web のコンテキストでは IndexedDB、WebSQL、localstorage の順で利用します。

なので、今回は特別にStorageを指定せず導入してみます。
Storageの指定方法はページの一番下に記述します。	

# 準備
 
`$ ionic cordova plugin add cordova-sqlite-storage`

`$ npm install --save @ionic/storage`


```ts:app.module.ts
 import { IonicStorageModule } from '@ionic/storage';
 
 @NgModule({
   declarations: [
     // ...
   ],
   imports: [      
     // ...
     IonicStorageModule.forRoot()
   ],
   // ...
 })
 export class AppModule {}
```

# 使用方法
**Storageを使いたい場所でInjectすれば使えます。**
ここではoverwatch-jsというAPIを使用して取得したデータをストレージに格納、使用しております。

```ts:search.ts
 ...
 import { Storage } from '@ionic/storage';
 
 @Component({
   ...
 })
 export class SearchPage {
   constructor(... private storage: Storage) {
     ...
   }
 
   // 検索を行う
   getPlayerInfo(playerIdFirstPart, playerIdSecondPart) {
   	...
     let instance: SearchPage = this;
     // overwatch-jsの詳細情報取得メソッド
     overwatchJs.getAll(this.platform, this.region, playerId).then(
       (data) => {         
         // storage.set()でストレージにkey, value(JSON)の形式で格納する
         instance.storage.set(data.profile.nick, data);
         console.log(data.profile.nick); 
         ...
       }, (reason) => {
         ...
       }
     );
   }
   ...
 }
```

```ts:home.ts
 ...
 import { Storage } from '@ionic/storage';
 
 @Component({
   ...
 })
 export class HomePage {
 
   items;
 
   constructor(public navCtrl: NavController, private storage: Storage) {
     this.initializeItems();
   }
 
   initializeItems() {
     this.items = new Array();
     // storage.forEach()でstorageに格納されているvalueとkeyの組み合わせをまわす
     this.storage.forEach((value, key) => {
       let userIdIndex = value.profile.url.lastIndexOf('/');
       let regionIndex = value.profile.url.lastIndexOf('/', userIdIndex - 1);
       let platformIndex = value.profile.url.lastIndexOf('/', regionIndex - 1);
       this.items.push({
         'userInfo': value,
         'userId': value.profile.url.slice(userIdIndex + 1),
         'region': value.profile.url.slice(regionIndex + 1, userIdIndex),
         'platform': value.profile.url.slice(platformIndex + 1, regionIndex)
       })
     });
     console.log(this.items);
   }
 }
```

※Storageの指定 公式引用

```ts:app.module.ts
 import { IonicStorageModule } from '@ionic/storage';
 
 @NgModule({
   declarations: [...],
   imports: [
     IonicStorageModule.forRoot({
       name: '__mydb',
          driverOrder: ['indexeddb', 'sqlite', 'websql']
     })
   ],
   bootstrap: [...],
   entryComponents: [...],
    providers: [...]
 })
 export class AppModule { } 
```
set_current_screen() 前に管理画面のポストタイプだったりを取得するクラス

`after_setup_theme` だったり `init` など、`$GLOBALS['typenow']`、`$GLOBALS['taxnow']` が定義されていない段階で取得する。
###code
```php
<?php

class WPQuickScreen {

	/**
	 * @var string
	 */
	private $pagenow;

	/**
	 * @var null|string
	 */
	private $typenow;

	/**
	 * @var null|string
	 */
	private $taxnow;

	private static $query_filter_diffinitions = array(
		'action'    => \FILTER_SANITIZE_ENCODED,
		'post_type' => \FILTER_SANITIZE_ENCODED,
		'taxonomy'  => \FILTER_SANITIZE_ENCODED,
		'post'      => \FILTER_VALIDATE_INT,
		// and more
	);

	public static function getInstance() {
		static $instance;
		return $instance ?: $instance = new self();
	}

	public function __get( $name ) {
		return property_exists( $this, $name ) ? $this->$name : null;
	}

	private function __construct() {
		if ( ! is_admin() ) {
			return;
		}
		global $pagenow;
		$this->pagenow = $pagenow;
		$this->parse_query();
	}

	private function parse_query() {
		$q = filter_input_array( INPUT_GET, self::$query_filter_diffinitions );
		switch ( $this->pagenow ) {
			case 'edit.php' :
			case 'post-new.php' :
				$this->typenow = $q['post_type'] ?: 'post';
				break;
			case 'post.php' :
				/**
				 * @see https://ja.forums.wordpress.org/topic/150122
				 */
				$this->typenow = $q['post'] ? get_post_type( $q['post'] ) : filter_input( \INPUT_POST, 'post_type' );
				break;
			case 'edit-tags.php' :
			case 'term.php' :
				$this->taxnow = $q['taxonomy'] ?: 'post_tag';
				break;
			case 'index.php' :
				// var_dump( 'Dashboard!!!!!' );
				break;
		}
	}

}
```
###usage
```php:function.php
<?php
add_action( 'after_setup_theme', function() {
	if ( !is_admin() ) {
		return;
	}
	global $pagenow;
	var_dump( $typenow ); // null

	$qscreen = WPQuickScreen::getInstance();
	var_dump( $qscreen->typenow );
} );
```
ディレクトリ階層の役割を調べる最短ルート

2017年現在、ほぼ全ての UNIX 及び UNIX 系 OS のディレクトリ階層は、Filesystem Hierarchy Standard (FHS、ファイルシステム階層標準) に従っている。諸々の事情によりこのディレクトリ階層の役割が何であったかを知りたくなる時というのが、定期的にやってくる
 (いちいち覚えてられないのである) 。その都度ググって、Wikipedia を調べたり、各ディストリビューションのドキュメントページを閲覧するのはちょっと面倒だ (僕個人の見解) 。

特に、日常的に Terminal 上で生活している人間にとっては、可能な限り Terminal から離れたくないというのが当然の心理である。

そういう人間 (おそらくごく少数だろうが) にとっては、以下のコマンドがこの場合役に立つ。

```shell-session
$ man hier
```

この `man` を開くと、ディレクトリ階層に関する説明を閲覧することができる。

macOS Sierra の場合には、このようなページが開く (一部抜粋) 。

```
HIER(7)              BSD Miscellaneous Information Manual              HIER(7)

NAME
     hier -- layout of filesystems

DESCRIPTION
     A historical sketch of the filesystem hierarchy.  The modern OS X filesystem is documented in the ``File System
     Programming Guide'' available on Apple Developer.

     /             root directory of the filesystem

     /bin/         user utilities fundamental to both single-user and multi-user environments

     /dev/         block and character device files

                   fd/  file descriptor files; see fd(4)
```

ちなみに `hier` というコマンドそのものは存在しない。
IBM Watson ConversationでコンテキストのJSONを操作したいとき

会話の最中に以下のコンテキストを保持していたとして

```
{
  "context": {
    ...
    "complex_object": {
      "user_firstname" : "Paul",
      "user_lastname" : "Pan"
      "has_card" : false
    }
  }
}
```

ノードからこのようなコンテキストのアップデートをかけられたとします

```
{
  "complex_object": {
    "user_firstname": "Peter",
    "has_card": true
  }
}
```

すると結果は

```
{
  "complex_object": {
    "user_firstname": "Peter",
    "user_lastname": "Pan",
    "has_card": true
  }
}
```

過去に持っていた値を保持しつつ、アップデートで該当する値は上書きされます

### 配列への値の追加

このtoppings_arrayという配列に値を追加したい場合

```
{
  "context": {
    "toppings_array": ["onion", "olives"]
  }
}
```

このようなメソッドが使えます

```
{
  "context": {
    "toppings_array": "<? $toppings_array.append('ketchup', 'tomatoes') ?>"
  }
}
```

contextに含まれるtoppings_arrayを$toppings_arrayというリストオブジェクトとして扱っています
そこからappendメソッドを呼び出しています

その結果

```
{
  "context": {
    "toppings_array": ["onion", "olives", "ketchup", "tomatoes"]
  }
}
```

このようになります

### 配列から値を削除

remove(key)かremoveValue(value)で行えます

```
{
  "context": {
    "toppings_array": "<? $toppings_array.remove(0) ?>"
  }
}
```

```
{
  "context": {
    "toppings_array": "<? $toppings_array.removeValue('onion') ?>"
  }
}
```

結果はどちらも

```
{
  "context": {
    "toppings_array": ["olives", "ketchup", "tomatoes"]
  }
}
```

このようになります
<jsp:include>を使用した場合のwindow.onloadイベント発火タイミング

\<jsp:include>で他のjspファイルの要素を取り込んだ後、window.onloadしようとした時にハマった。
のでメモ。





```html:hoge.jsp
<html>
<head>
    <script defer src="/path/to/jquery/jquery-3.2.1.min.js"></script>
    <script src="/js/hougei.js"></script>
</head>
<body>
    <jsp:include page="/jsp/hooogeee.jsp"></jsp:include>
</body>
</html>
```

```java:jsp/hooogeee.jsp
<%@ page import="java.io.IOException" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="java.util.concurrent.TimeUnit" %>
<%!
    private void outHello(HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter();
        out.println("<div class=\"hello\" style=\"display:none;\">");
        out.println("Hello World.");
        out.println("</div>");
        out.close();
    }
%>
<%
    TimeUnit.SECONDS.sleep(1000);
    outHello(response);

%>
```

```js/hougei.js
$(window).on('load', function () { //全ての読み込みが完了したら実行
    $('.hello').css('display', 'block');
});
```
意図している動作は jsp:includeが終わったタイミングでwindow.onloadイベントが発火され、hougei.jsによってdisplayプロパティが書き換わり"Hello World."が表示されることだが、この場合、なにも表示されない。

試しに console.log($('.hello').length) をしてみても 0 が返される。

原因はjsp:includeの仕組みにあった。

<h2> jsp:includeの仕組み</h2>


>このタグは、指定されたファイルをJSPの一部としてインクルードするのではなく、指定されたURLにリクエストを送信し、その応答内容を動的にリクエスト元に挿入して表示します。インクルードされるページとインクルードを行うJSPとは独立したページとして存在するため、インクルードされたファイルが更新されれば、元のJSP自体が更新されていなくても、動的に更新内容が結果に反映されます。

なるほど、\<jsp:include> の処理を理解し間違えていたようだ。他jspをコードごと挿入、表示するのではなく、リクエストした結果をレスポンスとして挿入しているため、window.onloadイベントはあくまでhoge.jspが読み込まれたタイミングで発火してしまう。

今回意図した通りに処理を行うためには

\<jsp:include page="/jsp/hooogeee.jsp">\</jsp:include>

ではなく、

<%@ include file="/jsp/hooogeee"%>

を使えばよかった。

ただし、コードをそのまま挿入しているのでinclude先での多重宣言やimportに注意する。

参考 : [Java Solution FAQ： &lt;%@ include %&gt; と&lt;jsp:include&gt;の違い](http://www.atmarkit.co.jp/fjava/javafaq/jsp/jsp09.html "Java Solution FAQ： &lt;%@ include %&gt; と&lt;jsp:include&gt;の違い")
railsで画像を投稿、保存する処理

# やりたいこと

railsでプロフィール画像など画像を投稿、DBに保存したい時のやり方。

# 仕様書

* image_nameカラムをユーザーのtableに用意
* デフォルトの画像を設定し、もし専用の画像がDBにあったら代入するようにする。
* public内に専用フォルダを作成し、そこに画像データを格納、画像の名前をDBに格納
* そこからURLで引っ張る
* updateアクションを作成し、画像を編集できるようにする

# image_nameカラムの作成

```
rails g migration ファイル名
```

でマイグレーションファイルを作成。

マイグレーションファイルのchangeメソッドに

```
def change 
 add_column :テーブル名, :カラム名, :データ型
end
```

でその後rails db:migrationで反映。

# デフォルト画像の設定

## デフォルト画像の格納

```ruby:users_controller.rb
def create
 @user = User.new(
 name:params[:name]
 email:params[:email]
 image_name:"default_user.jpg"
)
end
```

上記で記述し、画像が入ってなかったらデフォルトのものがでるようにする。.jpgも入れる。（投稿されたものがjpg以外の者の可能性もあるので形式もカラムに入れる）

## デフォルト画像をviewに表示する

```ruby:users/show.html.erb
<img src="<%= "/user_images/#{@user.image_name}" %>">
```

htmlのため/ではじまる。

# public内に専用フォルダを作成し、そこに画像データを格納、画像の名前をDBに格納

* createアクションを作成し、そこで下記を行う。
    * public/に画像を格納
    * 画像の名前をDBに保存

## inputの設置

```users/edit.html.erb
<%= form_tag("URL",{multipart:true}) %>
<input name="image" type="file">
```
form_tagには{multipart:true}を設定し、inputのtypeもfileに

# updateアクションを作成し、画像を編集できるようにする

```ruby:user_controller.rb
if params[:image]
 @user.image_name = "#{@user.id}.jpg"
 image = params[:image]
 File.binwrite("public/user_images/#{@user.image_name}", image.read)
end
```

もしimageが入っていた場合、@user.image_nameにその画像の名前を入れて

```ruby:user_controller.rb
File.binwrite("public/user_images/#{@user.image_name}", image.read)
```

でフォルダに保存
これだけは知っておきたいRuby on Rails の generate migration

#はじめに
Railsチュートリアルをやってる中であまり理解ができなかった
マイグレーションについて簡単に備忘がてらまとめます。

##マイグレーションとは
①移住。移転。移動。
②現在使用しているシステムやソフトウエアから別のものに移行すること。
参考：[Weblio:マイグレーション](http://www.weblio.jp/content/%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

#Railsのマイグレーションで出来ること
一口で言うと、SQLを意識しなくてもテーブルの作成や変更を行うことができる機能。

例えばMySQLなどのRDMSでテーブルを作成するときには
```create table test_table ( id int,user string)
```
だったり、カラムを変更したいときは
```alter table test_table change user user_name
```
などと、毎回SQL文を発行しなければいけませんが、
マイグレーション機能を使えばSQL文を書くことなくテーブルの操作が行えます。

#テーブルを作成する

手順としては以下の２ステップのみ。

手順
①マイグレーションスクリプトファイルの作成
②スクリプトファイルの実行

まず①のマイグレーションスクリプトファイルを作成します。
`rails generate migration テーブル名 フィールド名1：型名1,フィールド名2：型名2 ... フィールド名N：型名N`

まだこの段階ではデータベースは作成されていないので、
①で作成されたスクリプトファイルを実行してデータベースを作成します。

マイグレーションスクリプトファイルの実行は以下の１文で行えます。
`rails db:migrate`

因みに誤ってマイグレーションしてしまった場合には
`rails db:rollback`
でロールバック(＝取り消し)が可能です。

###サンプル
テーブル名：user

| カラム名     　| 型名 |  
|:-----------------|:------------------|
| name             |              string |
| age           |            integer |
| height             |              float |

上記のテーブルを作成する場合には、
`rails generate migration user name:string age:integer height:float`

指定できる型は以下の通りです。



|型名|説明|
|:-----------------|:------------------|
|string| 文字列型|
|integer| 整数型
|float| 浮動小数点数型
|decimal| 固定長整数型
|datetime |日時型
|timestamp |タイムスタンプ型
|time| 時刻型
|date |日付型
|binary |バイナリ文字列型
|boolean |真偽値型



#テーブルにカラムを追加する

基本的な構文は以下の通りです。
`rails generate migration Addカラム名Toテーブル名 カラム名：型名`

先ほど作成した`user`テーブルに`float型`の`weight`という項目を追加してみます。
`rails generate migration AddWeightToUser weight：float`

完了したら`rails db:migrate`を実行しましょう。

#テーブルのカラムを削除する
基本的な構文は以下の通りです。

基本的な構文は以下の通りです。
`rails generate migration Removeカラム名Toテーブル名 カラム名：型名`

先ほど追加した`user`テーブルの`weight`という項目を削除してみます。
`rails generate migration RemoveWeightToUser weight：float`

完了したら`rails db:migrate`を実行しましょう。
Yocto で Raspberry Pi 用 Linux を作る


素の Yocto から Raspberry Pi 用に Linux を作った事が無かったのでメモ。他にもっといい記事が沢山あるけど、最小限の作業をまとめた。

* 目的: Recipe のテスト用に軽い Linux が欲しい。
* 作業環境: Ubuntu 16.04.3

[meta-raspberrypi](https://git.yoctoproject.org/cgit/cgit.cgi/meta-raspberrypi/about/) の記述の通り作業します。現在のリリースバージョンは "pyro" (2.3.1) というらしいので meta-raspberrypi と依存しているレイヤの pyro ブランチをあるディレクトリ (例: /home/yourname/src/poky) に clone。

    git clone -b pyro git://git.yoctoproject.org/poky
    git clone -b pyro git://git.openembedded.org/meta-openembedded
    git clone -b pyro git://git.yoctoproject.org/meta-raspberrypi

開発環境を設定。引数なしだと build ディレクトリを作成し勝手に移動する。

    source poky/oe-init-build-env
    
[docs/layer-contents.md](https://git.yoctoproject.org/cgit/cgit.cgi/meta-raspberrypi/tree/docs/layer-contents.md) に対象 MACHINE や image が書いてあるので今回 `raspberrypi3` と `rpi-basic-image` を選んでみます。

conf/local.conf を編集して MACHINE を指定。例えばこんな風に。

    MACHINE = "raspberrypi3"

conf/bblayers.conf を編集して依存 layer を指定。例えばこんな風に。poky には単一のレポジトリに複数レイヤが収録されているので一つ一つ指定する。

    BBLAYERS ?= " \
      /home/yourname/src/poky/poky/meta \
      /home/yourname/src/poky/poky/meta-poky \
      /home/yourname/src/poky/poky/meta-yocto-bsp \
      /home/yourname/src/poky/meta-openembedded \
      /home/yourname/src/poky/meta-raspberrypi \
      "

ビルド開始 (50 分)

    bitbake rpi-basic-image

SD カード作成 sdimg は 100M 程度

    lsblk # SD カードデバイス名確認 (/dev/sdc とする)
    time sudo dd if=tmp/deploy/images/raspberrypi3/rpi-basic-image-raspberrypi3.rpi-sdimg of=/dev/sdc bs=1M

## トラブルシューティング

* bitbake で Fetcher failure が出た時は何度か bitbake をやり直すと上手く行った。
* raspberrypi3-64 と rpi-hwup-image の組み合わせはちゃんと動かなかった

## 参考

* [meta-raspberrypi](https://git.yoctoproject.org/cgit/cgit.cgi/meta-raspberrypi/about/)
* [Raspberry Pi3 with Yocto Project：環境構築](http://qiita.com/Nao1215/items/399b24bf5d9d81ac087d)
* [Yocto Project Quick Start](http://www.yoctoproject.org/docs/2.3.1/yocto-project-qs/yocto-project-qs.html)
ちょっとずつ読むドメイン駆動設計 まえがき3

# 複雑なのはドメインそのもの

> 最も重要な複雑さは、技術的なものではない。複雑なのはドメインそのもの、すなわち、ユーザーの活動やビジネスなのである。(まえがき より)

オブジェクト指向が解決しようとしてきたのは、まさに複雑なビジネスルールをいかに整理するかということ。

ドメイン駆動設計では、それをドメインと技術的な要素を切り離して、ドメインとドメインロジックに焦点を当てることで解決しようとしています。

キーワードは『(ドメインと技術の)課題の分離』、『(ドメインを優先する)優先順位』、『(ビジネスロジックの)見える化』かな？

特に最近は、KVS、メッセージング、APIなど単純にViewとRDBMSを繋ぎこめばOKな時代ではなくなってきています。
ふとすると技術的な方面にのみ注力して複雑なビジネスを整理しきれず苦労しそう。。。

現在関わっているプロジェクトもKVS、メッセージング、APIなど盛りだくさんなので、いかに、ドメインモデルに注力し、かつ課題を分離するか、失敗事例(?)やうまく行った点など、いつかお話できればと思います。

複雑なのはドメインそのもの。
MyBatisのSQLビルダークラスの使い方

WebアプリでDBのアクセスにMyBatisを使用しています。
MyBatis には定型的なSQLを作成するものは用意されていますが、
多少複雑なSQLを作ろうとすると結構面倒です。

いろいろ検索していると、「SQLビルダークラス」なるものを発見して、
実装してみました。だいたい思い通りのSQLが作ることができたのですが、
このSQLを実行する方法が見当たりません。

どなたかご存知の方がいらっしゃったらご教授ください。

SQL ビルダークラスのWebサイト
http://www.mybatis.org/mybatis-3/ja/statement-builders.html

ざっくりな質問で申しわあ蹴りませんが、よろしくおねがいします。
Macbook 2,1 (Late2006) に、非サポートの64bit版の Windows8/10を導入する

2006年に発売されたMacbook(Macbook2,1/late2006)に、BootCampとしてはサポートされていない64bit版のWindowsを導入したのでその時のメモ

# 環境

* Windowsマシン version7以上＋DVDが作成できるドライブ
* Windows 8/10 Install DVD media
* Windows AIK Tool (DVD) / こちらは http://www.microsoft.com/ja-jp/download/details.aspx?id=5753 からダウンロードしてメディアに焼いた上で、Installをしておく
* 導入する MacOS 10.6導入済みの Macbook 2006

# はじめに

* Macbook2,1では、すでに最新版のMacOSが提供されていない
* 学習塾とかの教材でWindows前提のサイトが多いので子供用にと再利用したい
* Windowsであれば最新のWindows10が利用できる


# 作業

## AIKを利用してBoot可能なWindowsインストールメディアを作る

* この作業はWindowsマシンで行います
* ここでWindowsマシン上のDVDドライブは Dドライブです。

1. AIKを用意したメディアから導入する
1. メニューからMicrosoft Windows AIK → Deploymentツールのコマンドプロンプトを起動する
2. `oscdimg -n -m -bD:\boot\etfsboot.com D:\ C:\Win10.iso` を入力
3. 暫く待つと `\Win10.iso` が出来上がるのでこのISOをDVDに焼く

## 導入する

* この作業はMacbook上で行います。

1. BootCampアシスタントを利用して、ディスクの領域を確保
2. 先程の工程で作成したWindows8/10メディアをMacbookに設定し、BootCampの指示に従い再起動
3. 後は通常のWinsows8/10の導入メニューが始まります。（誤ってmacosパーティションに入れないように）

## 設定する

* この作業はMacbook上のWinsows8/10で行います。
* このmacbookに導入されている10.6ではBootCamp3までしかサポートされておらず、ドライバのメディアがVista/7用になっているため別途用意をします。

1. https://support.apple.com/kb/DL1720?locale=ja_JP&viewlocale=ja_JP からBootCamp v5をダウンロードする
2. 管理者モードでcmdを起動
3. BootCampのファイルを解凍。cmdで BootCamp.msi があるフォルダまで移動する `msiexec /i BootCamp.msi` を実行する。

### 追記 (2017/08/16) 
* BootCampのドライバは、最新のMacがあれば `bootcampアシスタント` のAppを起動してメニューから最新のソフトのダウンロードを行うと Mac上にダウンロードできます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/11540/2360e997-f458-b932-d885-9dab416ece88.png)


# その他

* 起動OSの切替は、電源ON時点でジャジャーンの音辺りで `option` ボタンを押す
* コントロールパネルの中の `bootcamp`にてFnボタンなどの設定が出来る
* 効果の設定をOffにしてパフォーマンス優先にしておく
* 日本語IMEは、GoogleIMEの場合には設定からキーバインド変更すれば `英数` で `A` に。`かな` で　`あ` にすることが出来る。


# 感想

* なんとか動く、SSDにすればもう少し快適に動きそう。 
* ペアレントコントロールの機能がWindows10は秀逸。時間で制限できるとか素敵。
ClojureScriptでテストを書く

ClojureScriptでテストを書く必要があったので最低限必要な物をまとめてみた。

## ミニマルなテストコード
- Clojureに同梱されているclojure.testは、ClojureScriptにポートされていてcljs.testとして同梱されている。
- ClojureScriptのOSSでも幅広く使用されており、これを使用するのが間違いないので使用する。

```clj
(ns myapp.test
  (:require  [cljs.test :as t]))

(enable-console-print!)

(t/deftest test-foo
  (t/is (= 1 1)))

;; Runs tests in current ns
(t/run-tests)

```

## ビルドする

ClojureScriptがクラスパスにある前提で、以下をREPLで実行する。
(ここではjvmのClojureScriptを使うが、[lumo](https://github.com/anmonteiro/lumo)の[ビルドapi](https://github.com/anmonteiro/lumo/blob/master/src/cljs/bundled/lumo/build/api.cljs)も同様に使用できるはず)

```clj
(require '[cljs.build.api :as b])
(b/build "test" ;; Directory containing the test code
         {:main 'myapp.test ;;The ns that includes the tests
          :output-to "out/test.js" ;;Output file name
          :optimizations :simple ;; Convenient to have a single file output
          })
```

## ブラウザで実行

- 以下のようなhtmlファイルを作成し、スクリプトタグをビルドしたjsファイルを指すようにし、そのhtmlファイルをブラウザで開くと実行できる。
- 実行結果はコンソールに出力される

```html
<!DOCTYPE html>
<html>
  <head>
    <title>fiddles</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <script src="out/test.js" type="text/javascript"></script>
  </body>
</html>
```

## nodejsで実行
- 起動が早いメリットがある
- `node out/test.js`のように実行する
- ビルドの設定に`:target :nodejs`を含める(今回の例は単純なので無くても動く)

```clj
(require '[cljs.build.api :as b])
(b/build "test" ;; Directory containing the test code
         {:main 'myapp.test ;;The ns that includes the tests
          :output-to "out/test.js" ;;Output file name
          :target :nodejs ;;when targeting node
          :optimizations :simple ;; Convenient to have a single file output
          })
```


## nashornで実行

- jdk8を使用していれば`jjs path/to/file/test.js`のようにして実行することができる。
- メリットは、jdkに同梱されているので外部の何かをインストールする必要が無いこと
- デメリットは起動がもっさりしていること
- `jjs out/test.js`のように実行する
- プリントに使用されるデフォルトのconsoleオブジェクトが存在しないため、`(set! *print-fn* js/print)` を含める必要がある。
    - 含めていない場合、`ReferenceError: "console" is not defined`というエラーが表示される

```clj
(ns myapp.test
  (:require  [cljs.test :as t]))

(set! *print-fn* js/print)

(t/deftest test-foo
  (t/is (= 1 1)))

;; Runs tests in current ns
(t/run-tests)

```

## 複数のテストnsをまとめて実行する

こういう風に書ける。

```cljs
(ns myapp.test-runner
  (:require [cljs.test :as t]
            [bar.test]
            [foo.test]))

(enable-console-print!)

(t/run-tests 'bar.test
             'foo.test)
```

[ossでの例](https://github.com/plumatic/om-tools/blob/master/test/om_tools/test_runner.cljs)


## TODO
他にもlein-cljsbuildtとかlein-dooとdevcardsが便利っぽいのでそのうち調べたい
Exercism.ioでプログラム問題を解こう！

## Exercismってなに？

30以上のプログラム言語を使って解けるプログラム問題ライブラリです。

手順はいたって簡単で、問題をローカルにダウンロードして、解いてプッシュで提出するだけ、あとは勝手にExersismがプログラムの有無を確認してくれます。
http://exercism.io/

### Exercismの良いところ
ローカルのテキストエディタを使ってコードを確認できる。
テストケースごと問題をダウンロードできるので、自分でテストケースを増やしたり、
テストケースから解決策を予測できたりするのがよいところ。

![Screen Shot 2017-08-15 at 4.16.31 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/b3aa9ff0-8857-5a45-76b9-59e29f47c295.png)


## インストール方法

問題を解く方法はいろいろありますが、自分はxCodeを使いたいので、
その方法をシェアします。

### 1. Exercismをインストールする
ターミナルを開いて以下を実行

```
$ brew install exercism
```
*homebrewをインストールしていない人は、まずそれをインストールしてください。https://brew.sh/

### 2. 使いたい言語を指定する

自分の場合はswiftユーザーなのでswiftを指定しています。

```
$ exercism fetch swift
```
これを実行すると、exercism/swift/というフォルダがローカルに作成されます。

### 3. 作成されたswiftファイルにいく

さらに、デフォルトで　”hello-world”という問題名がインストールされているので、その中まで行きましょう。
```
$ cd exercism/swift/hello-world
```
![Screen Shot 2017-08-15 at 4.10.49 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/426c47ff-b40f-4880-331e-17013887b01a.png)

### 4. xCodeプロジェクトを始める

あとは、以下を書くと、xCodeプロジェクトを開いてプログラミングが始められます。

```
$ swift package generate-xcodeproj
$ open .
```

解らなければ公式文献をどうぞ　http://exercism.io/how-it-works/newbie


## Configure Keyを登録する

問題が正しいかどうか、提出済みかどうかなど確認するためにConfigure Keyをターミナルで設定する必要があります。
サイトでログインしたら、[勝手にkeyを生成してくれるので](http://exercism.io/how-it-works/newbie)、コピペして、terminalで実行してください。

```
$ exercism configure --key=<Your Configure Key>
```

## 提出するときのコマンド
```
$ exercism submit filename
```

##　次の問題をインストールするとき

```
$ exercism exercism fetch swift
```
【DS-Lite】net.ipv4.ip_forwardを立てちゃうと困る場合はこうだ！【NGN IPoE】

一発ネタです。
あなたのLinuxにDS-Liteトンネルを作りたい時の案内がIIJてくろぐ様から公開されています。
http://techlog.iij.ad.jp/contents/dslite-raspi

ここでなんのためらいもなく紹介されているのが以下の設定です：

```sysctl.conf
net.ipv4.ip_forward=1
```

この設定ですが、このスイッチを入れるとこのLinux上のNIC全部が取り扱うIPv4パケットがどれもこれも一つ残らず融通されるというなんだかプロミスカスな感じの設定です。
当然、KVMで仮想スイッチをゴニョってなんか作ろうとしている人とかは仮想スイッチの頭越しにパケットが行き来して大変困ったりすることになります。

「え、全部融通させるか全部遮断するしかないんですか！？」ってなるわけですが、ここで困った時の[ArchWiki](https://wiki.archlinuxjp.org/index.php/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E5%85%B1%E6%9C%89#.E3.83.91.E3.82.B1.E3.83.83.E3.83.88.E8.BB.A2.E9.80.81.E3.81.AE.E6.9C.89.E5.8A.B9.E5.8C.96)。

>
> ヒント: 特定のインターフェイスでのみパケット転送を有効にしたい場合は ```sysctl net.ipv4.conf.interface_name.forwarding=1``` を使ってください。
>

ははーっ！ありがたや！
さて、ここまでは調べやわかる範囲でありますが、一つ疑問が残ります。

「あれ、NICをふたつ以上選んでそいつらを繋ぎ合わす仕組みじゃないんだ？？」

そうなんです。つまり、上記の個別設定といえどどうやってもLinuxカーネルはそいつが単一の~~スイッチ~~ルータになることしか想定していないわけですな。
例えば「eth0とeth1の間をforwardさせて、そいつらとは別にeth3とbr2間もforwardしてもらおう」といった器用なことはさせてもらえないっぽくてまだちょっと危なさが残っております。

そんなわけで「DS-Liteしたい人が設定すべき本当に最小限のForwarding範囲はどこまでか」というのはなかなか分かりづらいのですが、以下が答えとなります。

1. 自分自身だけが使うトンネルを作る場合
    2. IPv6インターネットにつながっているNICのみをスイッチオン
    3. トンネル自体にこのスイッチは必要ない
3. DHCPサーバなども受け持ってDS-Liteルータとして振る舞う場合
    4. WANのNIC、
    5. LANのNIC、
    6. そしてDS-Liteトンネルの三者全てにスイッチが必要

自分自身のみが使うトンネル、これは昔ながらのPPPoEではセッション数制限があるため絶対実現しないものですが、DS-Liteの場合そのようなものは無いため各々思い思いに掘ればいいのです。
私はそれといって必要性もないのにLAN内のIPv4パケットを全滅させたいと企んでいる~~アホな~~のでFreeBSDやLinuxの一台一台がこいつを採用してます。~~KVM上にWinからのIPv4をLANに流さないためのFreeBSDなんてのもいますが、何故かICMP通るのにTCP通んなくて大変困っております。~~

この場合のミソは受信側が必ず送ったNICからパケットを受けなきゃならないといったような制限は一切かかっていないことでして、つまりは「トンネルデバイスがパケットを受けた時点でLinuxカーネルはそのパケットを読めますから、トンネルデバイスからどっちこっちへのforwardingは何らやんなくていいです」っていう理由でIPv6側のみのチェックでうまく動くのですな。

DS-Lite関係はFreeBSDルータの場合の自動設定とかLinuxならsystemdユニットとか色々やっているのですが、公開にはもちっと時間ください。。当方、所詮は蛞蝓でして、流行に乗ろうなんて思っちゃいけませんな。
RxJavaでPublishSubjectをsubscribeした時にonErrorが呼ばれるとそれ以降動かなくなる

## サンプルコード

```kotlin
        subject.subscribe ({ number ->
            println(number.toString())

            if (number == 3) throw RuntimeException()
        }, {
            println("onError")
        }, {
            println("onComplete")
        })

        subject.onNext(1)
        subject.onNext(2)
        subject.onNext(3)
        subject.onNext(4)
        subject.onNext(5)
```

## 実行結果

```
1
2
3
onError
```


4と5が表示されない。

## 所感
onErrorに入った時にちゃんと気がつけないと、何故かいきなり動かなくなってる。。。！
という辛みがあるので注意。
Railsチュートリアル中にcould not find expected ':' while scanning a simple keyが出た時の対処法

#発生した章
[13.2.3 プロフィール画面のマイクロポストをテストする](https://railstutorial.jp/chapters/user_microposts?version=5.0#sec-profile_micropost_tests)にて、リスト 13.27: ユーザーと関連付けされたマイクロポストのfixtureの内容を修正したら、テストでエラーが出るようになった。

#発生したエラー内容

```irb
ERROR["test_should_redirect_edit_when_not_logged_in", UsersControllerTest, 3.9885445390827954]
 test_should_redirect_edit_when_not_logged_in#UsersControllerTest (3.99s)
ActiveRecord::Fixture::FormatError:         ActiveRecord::Fixture::FormatError: a YAML error occurred parsing /home/ubuntu/workspace/sample_app/test/fixtures/microposts.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html
        The exact error was:
          Psych::SyntaxError: (<unknown>): could not find expected ':' while scanning a simple key at line 24 column 1
```

#原因
ymlファイル内の属性に:がないため。

#今回の原因
`micropost_<%= n %>`に、:がついていない

```/sample_app/test/fixtures/microposts.yml
<% 30.times do |n| %>
micropost_<%= n %>
  content: <%= Faker::Lorem.sentence(5) %>
  created_at: <%= 42.days.ago %>
  user: michael
<% end %>
```

#修正方法
`micropost_<%= n %>`に、:をつける

```/sample_app/test/fixtures/microposts.yml
<% 30.times do |n| %>
micropost_<%= n %>:
```

無事にエラーが解決しました。
ubuntuにchromy入れるまでの手順


Lightsail で Ubuntu のインスタンス(OSのみ)を立ち上げて、chromyが動作するまでの手順メモ。


## iptables の設定

参考: [ファイアウォールiptablesを簡単解説～初心者でもよくわかる！VPSによるWebサーバー運用講座(4) - さくらのナレッジ](http://knowledge.sakura.ad.jp/beginner/4048/)

上記とか参考に iptables の設定

```設定ひな型
# ポリシーを設定（受信と手転送は基本的に拒否／送信は基本的に許可）
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 自分自信からの通信を許可
iptables -A INPUT -i lo -j ACCEPT

# データを持たないパケットの接続拒否
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# SYNflood攻撃
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# ステルススキャン
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# 確立済みのtcp通信はポートに関わらず許可
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

# 任意のDNSアクセス戻りパケットを許可
iptables -A INPUT -p udp --sport 53 -j ACCEPT

# 特定ipからのみssh許可
iptables -A INPUT -p tcp -s xxx.xxx.xxx.xxx/32 --dport 22 -j ACCEPT

# 特定のプロトコルとポートを許可する場合は以下に
```

## Timezone設定

参考: [Ubuntu 16.04 LTS : システムのタイムゾーンを設定する ： Server World](https://www.server-world.info/query?os=Ubuntu_16.04&p=timezone)

```コマンド例
$ sudo timedatectl
(現在のTimezone確認)

# Timezone変更
$ sudo timedatectl set-timezone Asia/Tokyo

$ sudo timedatectl
(変更結果の確認)
```

## 必要なパッケージをインストール

```コマンド例
$ sudo apt install python make g++
```

nvm を入れて node.js も入れる

```コマンド例
$ curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | sh
（反映するため一旦ログアウトしてシェルを起動しなおす必要があるかも）
$ nvm ls-remote
（バージョンを確認）
# 最新のバージョンを選択してインストール
$ nvm install v8
$ nvm ls
（インストールされたバージョンを確認）
```

## chrome をインストール

参考: [Ubuntu に apt-get で Chrome 59 インストールして --headless してみた - Qiita](http://qiita.com/snaka/items/db422cff582c7c39eb02)

```コマンド例
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add
$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
$ sudo apt-get update
$ sudo apt-get install google-chrome-stable
```

## chromy をインストール

```コマンド例
$ npm install -g chromy
```
全要素が移動する（同じ位置に残らない）shuffle

8/25追記
-----
最終版？？
http://qiita.com/ttatsf/items/d4543ccc80e0fbe3891d#comment-3eccf9c112d73c505bc2


8/23追記
-----
下記のプログラムだと全てのshuffleパターンが網羅されていない，という指摘がありました．
[0,1,2,3] → [1,0,3,2] のような奇遇交換の例．
利用にあたってはご注意ください．
-----

8/21追記
-----
最終的に2行になった模様（白目)

```
def shuffle_all_move(items):
    rand_ord = random.sample(range(len(items)), k=len(items))
    return [items[r] for i, r in sorted(zip(rand_ord, rand_ord[1:]+rand_ord[:1]))]
```

実行速度も僅かに上のコードの方がわずかに速いようです（コメント欄に計測結果を載せています）

-----
8/19追記
-----
コメント欄にある，ttatsfさんが作ってくださったものが一番気に入っています．
（ベースにある「サットロのアルゴリズム」は7of9さんに紹介頂きました）
他にもコメントでコードを書いてくださった皆様，ありがとうございました．

```
import random

def shuffle_all_move( items ):
  length = len( items )
  res = [ 0 ] * length
  rand_ord = random.sample( range( length ), k=length )
  for i in range(  length  ) :
    res[ rand_ord[ i ] ] = items[ rand_ord[ ( i + 1 ) % length ] ]
  return res
```
実にエレガント！
…というわけで，下の適当なDIY shuffleより上記を利用することをおススメしたいw

-----
元の投稿
-----
絶対に要素が移動するようなshuffleのpython+numpy実装です(配列の要素が3以上であることを仮定しているので注意）．
手順
1. ランダムに要素を3グループに分割
2. グループ毎にshuffle
3. グループを1つスライドさせる.

1のランダムなグループ分割は，実際にはshuffleしてから配列を3つに分割することで実現．shuffleされた配列のグループをスライドさせても，元の配列の位置とは無関係になってしまうので，後でこのshuffleを元に戻す．これにより，元の配列と必ず違う位置に移動することが保障される．

このコードでは，下記の2つのページにあるコードを借用しています．
※ resettable_shuffle/reset_shuffle
http://qiita.com/EafT/items/9527cb30409b70106fd4
※ divide_list
http://fits.hatenablog.com/entry/2015/11/09/211012

```
def shuffle_all_move(_array):
    array = _array.copy()
    seed = random.randint(0,np.iinfo(np.int32).max)
    resettable_shuffle(array,seed)
    array = divide_list(array,3)
    if type(array[0]) == list:
        array = array[-1] + array[0] + array[1]
    else:
        array = np.vstack((array[-1], array[0],array[1]))
    return reset_shuffle(array,seed)
```
実行例

```
test_array = ['a','b','c','d','e','f']
print(test_array)
test_array = shuffle_all_move(test_array)
print(test_array)
```
['a', 'b', 'c', 'd', 'e', 'f']
['c', 'e', 'f', 'b', 'd', 'a']
Bitcoin Core のブロックチェーンの同期を高速化するためにノードを指定する

**追記ここから**
わざわざこんなことしなくても、wallet.datファイルを消すか他の場所に移動してから、

~~~
$ tar -czvf bitcoin.tar.gz ~/.bitcoin
~~~

とでもして、その圧縮ファイルを移動して所定の場所で解凍するのが一番早いと思います(試してませんが、、、)。
以下の方法は新たに txindex を有効にしたものを作りたいときは良いかもですね。
**追記ここまで**

自分用覚え書きです。Bitcoin coreの同期が終わったマシンが手元にあるけどもう一台立ち上げたい、そんなときの話です。

## 前提条件

- 既に同期が終わっており自分が管理しているBitcoin Coreノードが存在している
- もう一台、Bitcoin Coreを走らせたくなったが、BlockChainの同期がトロイのが嫌
- 手持ちに同期が終わっているノードがあるのだから、GbEで繋いで高速に同期できないかと思っている (まあGbEでなくてもいいですけど、たとえば同じLANにあるとして)
- BlockChainと言っても結局ファイルで ./bitcoin 以下をうまいこと移動すればできそうだけどなんとなくめんどい人
- 自前で同期しているものがあるのに、インターネットを経由して他のノードから落とすのに罪悪感がややある人
- Linux環境 (Windowsやその他OSでも似たようにできるとは思いますが試していないので)

## 方法

- 新しいマシンの方にBitcoin Coreをダウンロードして展開
 (https://bitcoin.org/en/download)
- 以下のコマンドを打つ (IPアドレスは既に同期が終わったマシンのもの。今回は例として192.168.150。coonectオプションでノードを指定できるようです)

~~~
$ ./bin/bitcoind -daemon -connect=192.168.1.50
~~~

- 同期が始まる (一応、以下のコマンドできちんと↑のマシンに接続されているか確認可能)

~~~
$ ./bin/bitcoin-cli getpeerinfo
[
  {
    "id": 1,
    "addr": "192.168.1.50",
    "services": "000000000000000d",
    "relaytxes": true,
    "lastsend": 1502829024,
    "lastrecv": 1502829024,

以下略
~~~

- 帯域を見たければdstatなどで

~~~
$ dstat --disk --net
-dsk/total- -net/total-
 read  writ| recv  send
 116k   17M|   0     0 
   0    25M|  12M   69k
   0    21M|4600k 7771B
   0    71M|3323k   11k
   0    51M|  70B  210B
   0    62M|  70B  210B
 284k   48M|4657k   19k
   0    28M|  10M   18k
   0    25M|9982k   32k
   0    23M|  11M   58k
   0    36M|  10M   92k
   0    49M|6728k   29k
   0    24M|  12M   35k
~~~

- 一日程度待って終わり

## 自分の環境と結果

- 既に同期が終わったBitcoin Coreが走っているマシンA
- 新しくBitcoin Coreを入れたいマシンB
- 同じLANでGbEで接続されている

という環境(上記のマシンたちのCPUはSandy Bridge以降のi3以上だった気がします)で、ムラがありますが最大25MB/s (=120Mbps) 程度出ました。平均して10MB/s程でしょうか。一分で600MB、一時間で3.6GBなので悪くはないと思います。BlockChainは現在(2017年8月16日)140GBほどなので、一日ちょっとで終わる計算です。

理想的な方法としては ./bitcoinのblockchain部分を圧縮して転送すれば良いのでしょうが具体的にどのファイル・ディレクトリをやればいいのかよく分からなかったので上記の方法を取りました。wallet(アカウント)も一緒に入れたければそのまま./bitcoinを圧縮・転送すれば良いのでしょうが今回はそうしたくなかったもので。もしやり方をご存じの方がいらっしゃれば具体的なコマンド付きで教えてください。(書いてて思いましたが./bitcoinを圧縮・転送して、展開してからwallet.datだけ消せば良い気もしてきました、動くか分かりませんが)
Centos7(Cloud9ではありません）にAnacondaをインストールしてJupyterを動作させる

##Anacondaのインストール
参考
http://qiita.com/t2y/items/2a3eb58103e85d8064b6

###インストールプログラムをダウンロード
https://www.continuum.io/downloads
からlinux版をダウンロード

###インストールプログラムを起動する(rootで起動)
```
bash Anaconda3-4.3.0-Linux-x86_64.sh　
```
###PATHの設定
今回はAnacondaのパスを/root/.bashrcに設定しました

```
# added by Anaconda3 4.4.0 installer
export PATH="/root/anaconda3/bin:$PATH"
```


###pythonの起動確認
```
python
```

##Jupyterの起動
参考
http://qiita.com/hiroseabook/items/1da01ea439b01c1eb48c

###上記の参考サイトからconfigファイルの作成

```
# ホームディレクトリにConfigファイルのパスが通っていることを確認
$ jupyter --path
# ホームディレクトリにconfigファイルを作成
$ mkdir ~/.jupyter
$ touch ~/.jupyter/jupyter_notebook_config.py
```
###configファイルの編集
shaの部分は下記の手順で暗号化された文字列を取得してから入力する
```
c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.password = u'sha1:hogehogehogehogehogehoge'　#あとで生成した文字に置き換えること
```

###ログインパスワードの設定

```
# iPythonを起動
$ ipython

# 暗号化された文字列を生成するためにライブラリ読み込み
In [1]: from notebook.auth import passwd

# パスワードを入力して暗号化された文字列を生成
In [2]: passwd()
Enter password: 
Verify password: 
Out[2]: 'sha1:(暗号化された文字列)'

# iPythonから抜ける
In [3]:                                                                                                                                               
Do you really want to exit ([y]/n)? y
```

###pleskのファイアーウォールで8888ポートを開放する

###ログインパスワードの設定
暗号化された文字列をJupyterのコンフィグファイルに書き込む

```
~/.jupyter/jupyter_notebook_config.py

c.NotebookApp.password = u'sha1:（4.4.1.で生成した文字列）'
```

###Jupyter Notebookを実行
rootで起動するときには下記のオプションを付ける

```
jupyter notebook --allow-root root
```

###私的メモ

pykdbをimportするために下記のようにパスを追加する
```
import sys
sys.path.append('/root/jupyter/pykdb-master/build/lib/')
import datetime
from pykdb import Futures, Indices, Stocks, Statistics
```
gem install の invoke_with_build_args のエラー　対処方法

###問題
久しぶりに`ruby`を触ることになり、`gem install` を行ったところ、下記のエラーが発生。結構はまったので対処方法を簡単に残す。

```shell-session:terminal
ERROR:  Loading command: install (LoadError)
    dlopen(~/.rbenv/versions/2.1.1/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle, 9): Symbol not found: _SSLv2_client_method
  Referenced from: ~/.rbenv/versions/2.1.1/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle
  Expected in: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
 in ~/.rbenv/versions/2.1.1/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle - ~/.rbenv/versions/2.1.1/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle
ERROR:  While executing gem ... (NoMethodError)
undefined method `invoke_with_build_args' for nil:NilClass

```

###解決方法
いろいろと試した結果、下記のリンクコマンドで解決した。

```shell-session:terminal
brew update
brew install openssl
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/bin/openssl

```
opensslがすでにインストールされていたので、
`brew uninstall --force --ignore-dependencies openssl`
で一旦むりやりをアンイストールして、から再度インストールした。
アンイストールは不要だったかも。
リングコマンド3つめの`1.0.2j`は各々の環境によって変更する必要あり。

###参考
http://qiita.com/YoshiyukiKato/items/e4f67c588d2943c1253d
https://stackoverflow.com/questions/38670295/homebrew-refusing-to-link-openssl
deeplearn.jsを試してみた

# deeplearn.jsをインストールして動かすまで

## [deeplearnjs][]とは...
[deeplearnjs][]とは...
Googleが提供しているブラウザで動くDeepLearningである。
基本的には、GPUを利用して動いているそうだ。
FirefoxとChromeで動くことを確認。


### きっかけ
動かすきっかけは...現在開発中の自社システム研究のため。


## インストール
インストール方法は簡単。
まず、[ここ][install]を参考に同手順を行う。

```
$ git clone https://github.com/PAIR-code/deeplearnjs.git
$ cd deeplearnjs
$ npm run prep
```

# `<script>`タグで使用するなら下記のコンマンドでビルドを行うこと:

```
$ ./scripts/build-standalone.sh # Builds standalone library.
>> Stored standalone library at dist/deeplearn.js
```

# もしes6でビルドするなら、下記のコマンドでビルドする:

```
$ ./scripts/build-npm.sh # Builds npm package.
>> Stored npm package at dist/deeplearn-VERSION.tgz
```

# インタラクティブのデモを開発する場合 (e.g. demos/nn-art/):

```
$ ./scripts/watch-demo demos/nn-art/nn-art.ts
>> Starting up http-server, serving ./
>> Available on:
>>   http://127.0.0.1:8080
>> Hit CTRL-C to stop the server
>> 1357589 bytes written to dist/demos/nn-art/bundle.js (0.85 seconds) at 10:34:45 AM
```



<!-- link's -->
[deeplearn.js]:https://github.com/PAIR-code/deeplearnjs
[deeplearnjs]:https://pair-code.github.io/deeplearnjs/
[install]:https://pair-code.github.io/deeplearnjs/
自作ランチャーを使っているのだが、今やほとんど無用の長物になった


# 自作ランチャとは

以前ブログ作り方をアップしていました。
Windowsユーザーなら誰でも作れると思います。
なぜなら、プログラム？というかコード2行書けば終わりだからです。

[自作ランチャをつくってみる](http://tom-gs.com/blog/index.php?itemid=191)

## ひとまず作り方と使い方（復習的な意味で）

`C:\Lanucher\`というフォルダを作って、以下のようなファイルを設置します。

```bat:Launcher.bat
title Launcher.bat
cmd /t:f0
```

そしたら同じフォルダにショートカットを作っていって、`C:\Lanucher\Launcher.bat`をWindowsのスタートアップに登録しましょう。
ショートカットを追加したらそのまま以下のような感じでキー入力（TABで補完も出来る）するだけでアプリを起動できます。

![Lanucher](http://tom-gs.com/blog/media/blog/20090529001.png "Lanucher")

これは先輩のやり方を自分なりに試行錯誤してみたものなんですが、たぶんこんなことしてたんだろうなと思います。

# 今ではほぼ不要。でも。。。

いらないですね。
このランチャーを作ったころは、Windows 2000とかXPとかを使っていた次期でした。
Windows Vistaあたりからスタートメニューからアプリを検索することが出来るようになったので、この手のランチャーは不要になったように思います。
私もこの2年ぐらいですが、このランチャーは必要なときにしか立ち上げなくなりました。

## 必要なときとは？

私の場合には主に3つです。

まずは、非インストール型のアプリの起動。
これはドライブ直下に`standalone`みたいな名前を着けて保存してランチャーから呼び出すようにしています。

もう一つはCygwinターミナルを立ち上げるとき。
私は`mintty`を使っているのですが、`.bat`ファイルにウィンドウサイズの設定とかをしているので、その立ち上げに使用しています。

そして最後が`hosts`ファイルの書き換え。
以外に使えるなと思っています。エディタにGvimを使っているのですが、これの引数にhostsファイルまでのパスを指定して、Administratorモードで起動するにチェックを入れてショートカットを作っておくと、すぐに編集できます。
仮想マシンやネットワークの設定変更の確認とかでhostsファイルをよく編集するので結構重宝しています。

![launcher.png](https://qiita-image-store.s3.amazonaws.com/0/131218/3f91c79b-ea53-1cfc-dd6d-e0f2f4349036.png)

# 結論

Windowsユーザー向けの自作ランチャーは今や無用の長物ですね。
上記のような使い方も、ランチャーででやるほどでもないかもしれないと思うことがありますが、マシンを移行するときとかに簡単だったり、かんたんなチェックリスト（リンク切れ担っているアプリのチェックとか）になってたりしてWindows 10でも未だに使ってるんですよね。
なので、もうしばらくは使っていそうです。

# 2022.05.17

そういえばhostsの編集ショートカット方法を紹介していました。

https://qiita.com/tomgoodsun/items/ffdedbe7abac5873aebb
Macにbundleでrmagickをインストールする

Railsでrmagickを使おうとしたら、ImageMagickのバージョンが合わなくてbundleでインストールできなくて困ったのでメモ

環境

- Ruby on Rails 5.1.3
- MacOSX 10.12.6
- Homebrew 1.3.1
- rmagick 2.16.0

```bash
# ImageMagickの6系をbrewでインストール
$ brew install imagemagick@6
# .bash_profileにPKG_CONFIG_PATHを設定
$ vim ~/.bash_profile
```

```~/.bash_profile
export PKG_CONFIG_PATH="/usr/local/opt/imagemagick@6/lib/pkgconfig"
```

```bash
$ source ~/.bash_profile
$ cd path/to/rails_project
$ bundle
```

# 参考

- https://github.com/rmagick/rmagick/issues/256
AWSのAutoScalingでインスタンスを起動する際にコマンドを実行したい

タイトルの通り、AWSのAutoScalingでスケールアウトさせる際に、起動するインスタンス上でコマンドを実行したい場合についてです。
インスタンスを起動する際に、ソースコードを最新にしたいとか、webサーバーのプロセスを立ち上げたいと言う時ありますよね。
以下の前提のもと、ここでは最もシンプルであろうという方法を記載していきます。

__前提__

* 既に利用可能なAMIを作成済み
* AutoScalingグループも作成済み
* ブラウザ上のマネジメントコンソールから設定

では、AWSのEC2サービスの中の起動設定の作成を行います。
1.AMIの選択、2.インスタンスタイプの選択を済ませ、3.詳細設定まで進みます。

![スクリーンショット 2017-08-16 0.28.36.png](https://qiita-image-store.s3.amazonaws.com/0/57448/564e2354-3ec0-3e83-04ea-bf5cd7ec6b81.png)

ここのユーザーデータの項目にインスタンス起動時に渡してあげたいコマンドを記載すればOKです。
気を付けなければいけない点は

* 渡されたコマンドはrootユーザーとして実行される
* インタラクティブな操作をコマンドの実行途中ではさむようなものは実行できない

です。
このユーザーデータのテキストボックス内に下記のような感じで記述してしまえば完了です。

```
#!/bin/bash
cd /path/to/myproject
sudo -u ec2-user /usr/bin/git pull origin master
sudo -u ec2-user /usr/local/bin/gunicorn myproject.wsgi -D
```

ユーザーデータは様々な形式で渡せるようです
https://cloudinit.readthedocs.io/en/latest/topics/format.html
VSCodeのemmetでhtmlのlangをjaに設定する方法

VSCodeのemmetでhtmlのlangをjaに設定する方法

# :ramen: 設定を開きます
`cmd` + `,`  
<img width="541" alt="スクリーンショット 2017-08-16 0.35.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/96220/8a3038b2-b8cf-70c2-dbc0-a092d1e4f771.png">

# :ramen: emmet.variablesを追記します

### ユーザ設定ファイルに下記を追記

```
  "emmet.variables": {
     "lang": "ja"
  }
```

<img width="630" alt="スクリーンショット 2017-08-16 0.40.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/96220/a6978e34-656d-444f-a5fc-6034e9cbccb0.png">

# :ramen: VSCodeを再起動します
enがjaになります！
わ～い(・ω・)

![hoge.gif](https://qiita-image-store.s3.amazonaws.com/0/96220/661f8b84-cfd5-fb39-d833-f246d40c2417.gif)
Watson SpeechToTextでBoxにある音声ファイルをテキスト化してみる(Ⅳ.動作確認)

#概要
この記事は、会議などの音声ファイルをWatson Speech To Textを使って自動でテキスト化するチュートリアルです。
この記事は　Ⅳ.動作確認編です。

>Ⅲ.プログラミング編はこちら
>[Watson SpeechToTextでBoxにある音声ファイルをテキスト化してみる(Ⅲ.プログラミング編)](http://qiita.com/tokotan/items/636030b09d89becd0b70)

#動作確認
Boxでテキスト化したい音声ファイルを選択し、[日本語テキスト化]をクリックすると・・・
しばらく待って・・・
こんなファイルがアップロードされました！！！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135983/4e2e69e6-38fd-7f13-81a9-3c9d5b1437b1.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135983/047608d6-7736-f2b3-070f-4af0a1562ead.png)

文章の最初の読み取りが少し甘いですね・・・。でも、日本語を読んでも十分に意味が通じますし、精度は高いと思っています。

#ハマったポイント
ところどころハマりまくって結構苦労したので（気づけばどうってことないものばかり。。。)、エラーメッセージと解決策を残しておこうと思います。

##"The request requires higher privileges than provided by the access token."
BoxのWeb Integrationで取得したauth_codeを使って、AccessTokenを取得しファイルのダウンロード、アップロードを行う予定でした。
しかし、アップロードのみできませんでした。
結論としては、エンドユーザーからの認可なしにファイルアップロードを行う場合、OAuth2.0認証ではなく、[JWTをしようしたOAuth2.0]が必要だったんだと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135983/f46fc668-21a9-47f3-8ac2-bef88e8bd0e0.png)

##'Cannot obtain token based on the enterprise configuration for your app'
App Userを作成せずにEnterpriseClientでアクセスしようとしていました。
App Userを作成後、正常にアクセスできることを確認しました。

##'This app is not authorized by the enterprise admin'
Boxの管理コンソール>[アプリ]でアプリの承認を行うことで解決しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135983/09c32656-0bb1-3d22-d70a-0a9d8b07af95.png)

下記画面では、アプリのClient IDを設定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135983/e37e5876-198a-edef-5c41-0e479c935fc5.png)

##not_found: "Not Found"
音声ファイルをダウンロードする/テキスト化したファイルをBoxへアップロードする場合に、該当フォルダに対し、App Userがアクセスする権限がないと発生します。

#最後に
初めて、チュートリアル的な記事を投稿してみました。
これからもクラウドサービスとCognitiveServiceを組み合わせたシステムを開発して行けたらなあと思っています。
MIDIデータでword2vecをやってみた（があまりうまくいった実感が得られなかった）

# はじめに
MIDIデータではドレミが60、62、64など数字になっており、それが時系列順に並んでいます。
そこでMIDIデータを元に、word2vecで、音をベクトル化し、類似度を画像で表現したいとおもいます。
word2vecについては、下記の記事などを参考にしました。

下記のページなどを参考にさせていただきました。
* [絵で理解するWord2vecの仕組み](http://qiita.com/Hironsan/items/11b388575a058dc8a46a)
* [TensorFlow Tutorial / Vector Representations of Words](https://www.tensorflow.org/tutorials/word2vec)
* [TensorFlow Tutorial / word2vec_basic.py](https://github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/examples/tutorials/word2vec/word2vec_basic.py)

# 用いたデータセット
* [The Lakh MIDI Dataset v0.1
 のLMD-matched](http://colinraffel.com/projects/lmd/#get)

# コード
GitHubにJupyter Notebookを置いてあります。

* https://github.com/takitsuba/music-word2vec/blob/master/word2vec.ipynb

# 結果
音の類似度を元に画像にしたものが下記になります。
![tsne_20170816000627.png](https://qiita-image-store.s3.amazonaws.com/0/82763/f71c5886-14fd-7f4d-fdc0-2342ba6beb9a.png)

# 感想
あまり画像を見ても納得感が得られず。。
C3,C4,G3,G4が近くにあるところは、それっぽいかな。
パラメータの調整をもっとすべきかと思います。
また学習データは、10万曲を全て1つに繋げてしまっており、曲と曲の接続部分が考慮できてないことなどは修正できそうです。
Mac Cordova環境構築

# Mac Cordova環境構築

`Mac OS`でCordova環境を構築したので、以下に記録を残す。

## node.jsのインストール
Cordovaのコマンドラインはnode.jsで動作し、npmで利用できる。

まずは、node.jsのバージョン管理を行ってくれる `nodebrew` をインストールします。
nodebrewのインストールは以下のサイトに説明が記載されているので、指示にしたがってインストールする。
[nodebrew](https://github.com/hokaccha/nodebrew)

curlコマンドを使用てダウンロード＆インストール

```
$ curl -L git.io/nodebrew | perl - setup
```

パスを`.bashrc`または`.zshrc`に設定する
> 自分の環境では.zshrcに設定する

```
$ export PATH=$HOME/.nodebrew/current/bin:$PATH >> .zshrc
```

設定したパスを読み込む

```
$ source ~/.bashrc
```

以下のコマンドを使用して、インストールされたことを確認する。

```
$ nodebrew help
```
ヘルプが表示されたらインストール完了。次はnode.jsをインストールする。

特に不都合がなければ最新版の安定バージョンをインストールする。

```
$ nodebrew install-binary stable
```

node.jsがインストールされたことと、バージョンを確認する。

```
$ nodebrew ls
v8.3.0
```
> 私が環境構築した時の最新バージョンはv8.3.0

この状態だとnode.jsは使用できないので、nodebrewに使用するnode.jsのバージョンを設定する。

```
$ nodebrew use v8.3.0
use v8.3.0

$ nodebrew ls
v8.3.0

current: v8.3.0
```

## Cordovaのインストール
node.jsのインストールが完了したので、本命のCordovaのインストールを行う。
念のため公式サイトのインストール手順をチェックすること。
[Apache Cordova](https://cordova.apache.org/#getstarted)

npmコマンドを使用してCordovaをインストール

```
$ npm install -g cordova
```

インストールできたことを確認する。

```
$ cordova -v
7.0.1
```
> 私が環境構築した時の最新バージョンはv7.0.1

サンプルプロジェクトを作成し、動作確認を行う。

```
$ cordova create MyApp
Creating a new cordova project.
$ cd MyApp
$ cordova platform add browser
$ cordova run browser
```

実行結果
![cordova_browser.png](https://qiita-image-store.s3.amazonaws.com/0/147939/6632fad8-23f9-cd58-467c-b2ce1d40f823.png)

## iOSシミュレータで動作させる

### 事前準備
前提条件としてXCodeをインストールすること。まだインストールしていない場合はApp Storeでダウンロードすること。

Xcodeのインストールが完了したら、Xcodeのコマンドラインツールをインストールする。インストールは以下のコマンドを使用する。

```
$ xcode-select --install
```

ライセンス合意を行う必要がある。以下コマンド実行後、`agree`を入力すれば完了。

```
$ sudo xcodebuild -license
```

### iOSシミュレータの動作確認

プロジェクトにiOSプラットフォームを追加。

```
$ cordova platform add ios
```

iOS用にビルド＆実行

```
$ cordova run ios
```

実行結果
![cordova_ios.png](https://qiita-image-store.s3.amazonaws.com/0/147939/7f1e57f9-0ede-8627-69c9-0929240f6fcb.png)

## 参考サイト
* [MacでCordova開発環境を構築した備忘録](http://qiita.com/u4da3/items/14c98487fa85df21ea0d#ios-%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%AE%E8%B5%B7%E5%8B%95)
* [nodebrew](https://github.com/hokaccha/nodebrew)
* [Cordova](https://cordova.apache.org/)
Webpackで環境ごとにLoggerのLogLevelを設定

Webpackを使って環境ごとにJSをビルドする際、環境変数 `NODE_ENV` を参照してLoggerのLogLevelを変更する。

Webpackバージョン: 3.0.0

Loggerライブラリは `loglevel` を使用します。
https://github.com/pimterry/loglevel

```js:webpack.config.js
plugins: [
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: `"${process.env.NODE_ENV}"`
    }
  })
]
```

```js:package.json
"scripts": {
  "development": "NODE_ENV=development webpack --color --progress",
  "production": "NODE_ENV=production webpack --color --progress"
}
```

NODE_ENVを参照して `development` と `production` でLogLevelを変更。
`development` の場合に `log.debug, log.info, log.warn, log.error` を表示、
`production` の場合に `log.error` のみ表示されるよう設定します。

```js:フロントのJS
import log from 'loglevel';

if (process.env.NODE_ENV === 'development') {
  log.setLevel(log.levels.DEBUG);
} else {
  log.setLevel(log.levels.ERROR);
}
```

ビルド実行
`$ npm run development`
`$ npm run production`
OpenCV で 簡単 TopView

# 突然ですが Raspberry Pi Zero W を入手しました。
Switch Science さんから、運良く発売日に注文でき、すぐに入手出来ました！
これを早速プラレールに搭載、うまく稼働させることに成功しました。
プラレールへの搭載方法と、Wifi でリモートコントロールするためのコードを以下の Git に公開しましたので、興味がありましたらご覧ください。
https://github.com/Kumapapa2012/Raspberry-Pi-Zero-on-PLA-RAIL-3rd

# Top View について
本題の Top View について。
Top View とは、カメラの視界の映像を、あたかも真上から見下ろしているように見せる技術のことです。某社の自動車にも搭載されていますね。

プラレールに限らず、何か動きまわるものにカメラをつけて自動運転などを考える場合、単眼カメラでどうやってやればいいのか、結構悩むと思います。例えば、自身の進行方向や速度などはどのように判別すべきなのか？ある時点のコマとそこから一定時間後のコマとの間で、特徴点を見つけ、移動位置、拡大縮小率などから自身の動きを推測すればいいのか？などなど。。。
そんな中、Top View で問題を簡単にできそうだという記事を見つけました。[^1]

手順としては簡単です。

1.適当な正方形または長方形を、画面の底辺と左右中心に合わせて撮影し、画面上の頂点座標を取得。以下のような画像です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172071/8b70c154-69ae-dbb8-deba-bc948fbefb0c.png)
この画像は、4cm の正方形に「あ」の文字がある状態を撮影しています。
この場合、左上、右上、右下、左下の順で以下の座標になります。
            T_L=(168,260)
            T_R=(344,260)
            B_R=(408,360)
            B_L=(72,360)

2.TopView化した時の画像サイズと、その画像に正方形または長方形がどのように表示されるべきか決め、頂点座標を決定。これは、元の「あ」画像の最も長い辺つまり底辺を使用し、すべてが同じ長さの正方形になるように座標を計算します。詳しくは私の Notebook [^2]を参照してください。

3.それぞれの頂点座標を用い、cv2.getPerspectiveTransform()で変換行列取得。この変換行列によって、カメラ上の台形の「あ」が、上から見た正方形の「あ」に変換されます。
おそらくこの変換行列は定数項として、一度計算すればよいはず。

4.cv2.warpPerspective()カメラ画像に、3.で求めた変換行列を適用。

以上で Top View が得られます。

Youtube に、実際の動作の様子の Video をアップしました。
この Video では、"Canny" アルゴリズムでエッジ抽出したカメラ画像に、Top View 効果を適用しています。ちょっと歪んでいますが「あ」が概ね正方形に出ています。
※クリックして再生
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/172071/98f27145-463b-74a1-4087-274a360e9179.png)](https://youtu.be/MP-aabj_gLc)
なお、Notebook の動画との間に遅延が発生していますが、おそらくこれは、Notebook に無理やり動画を表示させたためと考えられます。

まだ調整が必要なものの、Top View にすると環境認識の問題が 3 次元から 2 次元の問題となり、識別器の要件もかなり簡単になりそうです。
Top View からレールが識別でき、トラックできれば、たとえば障害物検知と停止なら簡単にできそうです。


#　参考文献
[Line detection autopilot using Python + OpenCV.](https://wroscoe.github.io/compound-eye-autopilot.html)
[Canny Edge Detection](http://docs.opencv.org/trunk/da/d22/tutorial_py_canny.html)
[JupyterでOpenCVの画像をインライン表示](http://uphy.hatenablog.com/entry/2016/12/11/110703)

[^1]: https://wroscoe.github.io/compound-eye-autopilot.html
[^2]: https://github.com/Kumapapa2012/Learning-Machine-Learning/blob/master/Notebooks/Inline_MJPG_Video_TopView.ipynb
Excel の WorkSheets を PowerShell で扱うと楽になる

VBA だと `worksheets` を走査するのにいちいち `For` したりするので面倒ですよね？

PowerShell なら１行でヤレます。

```posh:デフォルトで追加されるSheet1,Sheet2,Sheet3とか全部消す
$Excel = New-Object -com Excel.Application
$Book = $Excel.WorkBooks.Open($BookPath)
$Book.WorkSheets | ? { $_.Name -match "Sheet[0-9]*" } | % { $_.Delete() } # １行！
$Book.Save()
$Book.Close($False)
$Exce.Quit()
```

ただし、広い範囲の `Range` とかだと読み出しに時間がかかるので遅くなります。

```posh:値の入っているセルの数をカウントしようとする
$Excel = New-Object -com Excel.Application
$Book = $Excel.WorkBooks.Open($BookPath)
$Sheet = $Book.WorkSheets | Select -First 1
$Sheet.Range("A1:Z1000") | ? { $_.Text } | measure # 遅い
```

基本的に PowerShell の方が構文が綺麗なので使いたいんですが、VBA の方が実行速度が出やすいんですよね。

使い所～