OmniAICreator/Qiita-1.07M huggingface dataset:
DOTweenでカウントダウン・カウントアップのアニメーション

Unityのアニメーションライブラリ「DOTween」とuGUIのUnityEngine.UI.Textで、次のようなカウントダウンやカウントアップができるコードを示します。

![countdown.gif](https://qiita-image-store.s3.amazonaws.com/0/4125/0b0f1033-beab-b9e4-1629-a6ce994546e6.gif)


```csharp:DoText系メソッド
using UnityEngine.UI;
using System;
using DG.Tweening;

public static class DOTweenEx
{
    public static Tweener DOTextInt(this Text text, int initialValue, int finalValue, float duration, Func<int, string> convertor)
    {
        return DOTween.To(
             () => initialValue,
             it => text.text = convertor(it),
             finalValue,
             duration
         );
    }

    public static Tweener DOTextInt(this Text text, int initialValue, int finalValue, float duration)
    {
        return DOTweenEx.DOTextInt(text, initialValue, finalValue, duration, it => it.ToString());
    }

    public static Tweener DOTextFloat(this Text text, float initialValue, float finalValue, float duration, Func<float, string> convertor)
    {
        return DOTween.To(
             () => initialValue,
             it => text.text = convertor(it),
             finalValue,
             duration
         );
    }

    public static Tweener DOTextFloat(this Text text, float initialValue, float finalValue, float duration)
    {
        return DOTweenEx.DOTextFloat(text, initialValue, finalValue, duration, it => it.ToString());
    }

    public static Tweener DOTextLong(this Text text, long initialValue, long finalValue, float duration, Func<long, string> convertor)
    {
        return DOTween.To(
             () => initialValue,
             it => text.text = convertor(it),
             finalValue,
             duration
         );
    }

    public static Tweener DOTextLong(this Text text, long initialValue, long finalValue, float duration)
    {
        return DOTweenEx.DOTextLong(text, initialValue, finalValue, duration, it => it.ToString());
    }

    public static Tweener DOTextDouble(this Text text, double initialValue, double finalValue, float duration, Func<double, string> convertor)
    {
        return DOTween.To(
             () => initialValue,
             it => text.text = convertor(it),
             finalValue,
             duration
         );
    }

    public static Tweener DOTextDouble(this Text text, double initialValue, double finalValue, float duration)
    {
        return DOTweenEx.DOTextDouble(text, initialValue, finalValue, duration, it => it.ToString());
    }
}
```

　利用例はつぎのような感じです。

```csharp:利用例
var duration = 3.0F;

text.DOTextFloat(duration, 0.0F, duration, it => string.Format("{0:0.00}", it)).SetEase(Ease.Linear);
```
Ruby のブロック付きメソッドを実装する

## シンプルな例

メソッド呼び出し(super・ブロック付き・yield) (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fcall.html

> ブロック付きメソッドとは制御構造の抽象化のために用いられる メソッドです。最初はループの抽象化のために用いられていたため、 特にイテレータと呼ばれることもあります。 do ... end または { ... } で囲まれたコードの断片 (ブロックと呼ばれる)を後ろに付けてメソッドを呼び出すと、その メソッドの内部からブロックを評価できます。 ブロック付きメソッドを自分で定義するには yield 式を使います。

### ソースコード

```ruby
# ブロック付きメソッド
def add(x, y)
  puts "begin: #{x}, #{y}"
  yield(x + y) # 足した結果をブロックに渡す
  puts "end: #{x}, #{y}"
end

# ブロック付きメソッドを呼び出す
add 2, 3 do |result|
  puts "answer: #{result}"
end
```

### 実行結果

```
begin: 2, 3
answer: 5
end: 2, 3
```

## Proc オブジェクトを使う

class Proc (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Proc.html

> ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
> Proc は ローカル変数のスコープを導入しないことを除いて 名前のない関数のように使えます。ダイナミックローカル変数は Proc ローカルの変数として使えます。

### ソースコード

```ruby
# ブロック付きメソッド
def add(x, y)
  puts "begin: #{x}, #{y}"
  yield(x + y) # 足した結果をブロックに渡す
  puts "end: #{x}, #{y}"
end

# Procオブジェクトを生成
header = ''
p = Proc.new{|result|
  puts "#{header}: #{result}"
}
header = 'answer' # ブロック内で使う変数に値を代入

# ブロック付きメソッドを呼び出す
add 2, 3, &p
```

### 実行結果

```
begin: 2, 3
answer: 5
end: 2, 3
```

## ループ処理

### ソースコード

```ruby
# ブロック付きメソッド
def double(array)
  array.each do |e|
    # 元の値と2倍した値をブロックに渡す
    yield(e, e * 2)
  end
end

# ブロック付きメソッドを呼び出す
double [2, 3, 5] do |src, dst|
  puts "#{src} -> #{dst}"
end
```

### 実行結果

```
2 -> 4
3 -> 6
5 -> 10
```

## ブロックをコールバックする

### ソースコード

```ruby
class Slots

  def initialize()
    @slots = {}
  end

  # マッチしたときに実行するブロックを登録する
  def add(regexp, &block)
    @slots[regexp] = block
  end

  # 文字列にマッチしたら対応するブロックを実行する
  def match(str)
    @slots.each do |regexp, block|
      if matchdata = str.match(regexp)
        puts "[match] #{block.yield(matchdata)}"
      end
    end
  end
end

slots = Slots.new
slots.add(/hell/i) {|m| "'#{m.string}' has 'hell'."}
slots.add(/hello/i){|m| "'#{m.string}' has 'hello'."}

slots.match('He')
slots.match('HELL')
slots.match('Hello, Goodbye')
```

### 実行結果

```
[match] 'HELL' has 'hell'.
[match] 'Hello, Goodbye' has 'hell'.
[match] 'Hello, Goodbye' has 'hello'.
```

## 参考資料

- メソッド呼び出し(super・ブロック付き・yield) (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fcall.html
- class Proc (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Proc.html
- class Regexp (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Regexp.html
- 正規表現 (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html
- class MatchData (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/MatchData.html
Amazon EMRを使用する際のベストプラクティス

Hadoopに関する基本的な内容をまとめてみたものです。Hadoopに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[Amazon EMRを使用する際のベストプラクティス] (https://www.techcrowd.jp/bigdata/bestpractice/)

# [データの集約] (https://www.techcrowd.jp/bigdata/bestpractice/)

さまざまな方法でAmazon EMRに大量のデータを移動させる事が出来ますが、短期間で効率良くデータをアップロードさせるには、複数のクライアントからAWSへ同時にデータを移動させるのが重要です。
計画的にデータをアップロードすれば、本格的にAWSが利用出来る時期を早める事が出来ます。

そして、Amazon EMRにデータをアップロードする時は、大きなファイルにまとめて格納する事にも配慮するべきです。
複数のデータをファイルに集約する事で、
・アップロードの回数を減らせる
・AWS上のファイルの数が減って、パフォーマンスが向上する
・圧縮比率が高くなり、AWS上の使用容量を少なく出来る
などのメリットがあります。

小さなファイルは大きなファイルにまとめてAWSにアップロードするのが、効率的な方法です。


# [データの圧縮] (https://www.techcrowd.jp/bigdata/bestpractice/)

データの圧縮についても、
・ストレージコストの削減
・データ処理を高速化して、パフォーマンスを向上させる
などの効果がありますので、適切な圧縮方式を選ばなくてはなりません。

圧縮方式を選ぶ時は、
・高速でファイルを圧縮と解凍をする必要があるか
・データストレージをどの程度節約するのか
などを検討して、圧縮方式を選ぶ必要があります。


# [パフォーマンスチューニングするには] (https://www.techcrowd.jp/bigdata/bestpractice/)

Amazon EMRのパフォーマンスを向上させるベストプラクティスには、いくつかの方法があります。

マップタスク関連の改善
・存続期間の短いマップタスクがある時は小さなファイルを処理しているので、大きなファイルにまとめる
・マッパー出力を圧縮する
・バッファの容量を増やして、マップタスクがディスクに書き込む回数を減らす

リデューサータスク関連の改善
・リデューサーが待機状態にならないように、リデューサーの数を制限する
・メモリ容量を増やして、メモリ内を参照するだけ済むようにする


# [一時的クラスタと永続的クラスタを使い分ける] (https://www.techcrowd.jp/bigdata/designpattern-3/)

ジョブが実行している間だけ動作しているが一時的クラスタで、ジョブに関係なく動作し続けるのが永続的クラスタです。

一時的クラスタは、
・立ち上がっている期間が短いので、コストを節約出来る
・運用の手間が掛からない
などのメリットがあります。

永続的クラスタには、
・複数のジョブで、データを共有出来る
・一時的クラスタを何回も立ち上げて使うよりも、コストを削減出来る場合がある
などのメリットがあります。

・データのロード時間
・処理時間
・ジョブ数
などを調べて、どのようにAmazon EMRを使うのかを決める必要があります。


# [タスクノードの使い方を工夫] (https://www.techcrowd.jp/bigdata/designpattern-3/)

Amazon EMRは、
・クラスタを管理するマスターノード
・HDFSを使ってデータを格納するコアノード
・タスクを実行するタスクノード
から構成されますが、タスクノードの使い方を工夫する事でコストを削減出来たり、パフォーマンスの向上が期待出来ます。

・スポットインスタンスの活用
スポットインスタンス上でタスクノードを動かせば、コストを節約出来ます。

・大量のタスクノードを使う
S3からHDFSにデータをアップロードする時に、スポットインスタンス上に大量のタスクノードを動かす事で、効率的なアップロードが可能となります。
Emacsの設定ファイルをGitで管理する


## リポジトリ
Githubで .emacs.d の空リポジトリを作成する。

## clone
既に ~/.emacs.d が あれば リネームしてからcloneする。

```
$ mv .emacs.d .emacs.d.org
$ git clone git@github.com:private-account/.emacs.d.git
```

cloneしたディレクトリに設定ファイルを配置する。

```
$ mv .emacs.d.org/* .emacs.d/.
```

.emacs_bash は ~/.emacs.d/ 配下に シンボリックリンク作っておく

```
$ rm .emacs_bash
$ ln -s .emacs.d/.emacs_bash .emacs_bash
```

## .gitignore
Emacsの作業データ等の不要なファイルはGit管理から外す。

``` .gitignore
.recentf
server/
auto-save-list/
eshell/
*.???~
```
※環境による

## push
```
$ git add .
$ git commit -m "hogehoge"
$ git push origin master
```
EMRの基本的な利用手順 

Hadoopに関する基本的な内容をまとめてみたものです。Hadoopに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[各種BIツールが使えるAmzon EMR] (https://www.techcrowd.jp/bigdata/amazon-emr/)

# [Amazon EMRとは] (https://www.techcrowd.jp/bigdata/amazon-emr/)

Amazon EMRとは、AWS上でオープンソース型フレームワーク Hadoopが動作出来る環境を提供するものです。

一般的にはHadoopを使用するためには複数のサーバーを用意する必要がありますが、Amazon EMRを使えば新たにサーバーを購入したりシステムの構成を変更する必要はありません。
Amazon EMRがHadoopを常時使用可能な環境を構築しますので、容易にデプロイする事が可能となります。


# [Amazon EMRの特徴] (https://www.techcrowd.jp/bigdata/amazon-emr/)

Amazon EMRには、以下のような特徴があります。

・Amazon EMR でHadoopクラスターを実行した時の仮想サーバー数の増減が簡単に出来ます
・ハードウェア等のメンテナンス料金を支払う必要はなく、Amazon EMRでクラスターを使用した分だけの料金を払うだけです
・Hive、Pig、HBase などのHadoop アプリケーションの使用が可能
・Amazon EC2、Amazon S3、DynamoDB、Amazon RDSなどのAWSとAmazon EMRを統合する事が出来ます
・Microsoft Excel、MicroStrategy、QlikView、TableauなどのBIツールを使って、データの分析を行う事が出来ます


# [EMRの基本的な利用手順] (https://www.techcrowd.jp/bigdata/process/)

EMRの基本的な利用手順は、次のようなものです。
EMRの入門者でも、比較的容易に操作する事が出来ます。

入出力データ・データ格納領域をS3等に用意
Amazon S3 を使って、Amazon EMRに入出力データやログファイルなどを格納出来ます。
S3コンソールを開きパケット名とデータのあるパス等を指定する事で、S3パケットを作成します。

クラスターの起動
Amazon EMRコンソールを開き、ソフトウェア・ファイルシステム・ハードウェア等の設定を行ってから、クラスターを作成します。

Hiveスクリプトを実行する
Amazon EMRコンソールを使って、Hiveスクリプトを実行します。
Hiveスクリプトをステップとして送信する事で、出力を確認する事が出来ます。
S3コンソールを開いて、出力したパケットのフォルダ内の出力ファイルで確認します。

Hue を使ってクエリを送信する
Hadoop用オープンソースウェブユーザーインターフェイスであるHueにログインして、クエリを送信します。
Hueを使う事で簡単にクエリを送信したり、スクリプトが作成出来るようになります。


# [EMRを使用した後の処理] (https://www.techcrowd.jp/bigdata/process/)

EMRを使用した後は追加料金が発生しないように、不要なリソースは削除しなくてはなりません。

Amazon S3のバケットの削除
Amazon S3 コンソールを使えば、選択したオブジェクトを削除出来ます。

Amazon EMRクラスターの終了
Amazon EMRクラスターを終了するには、Amazon EMRコンソールを開いてCluster Listページで終了したいクラスターのチェックボックスをオンにして、Terminateを選択します。
PHPでgoogleサービス「visionAPI」の実行方法

vision APIについて

Googleの画像認識APIをPHPで実行する方法です。

## 概要
事前にgoogleでAPIキーを発行する必要があります。
サービス内容については以下にまとめてあります。
http://vitalify.jp/blog/2017/05/google%E3%81%AE%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98api%E3%80%8Cvisionapi%E3%80%8D%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%94%BB%E5%83%8F%E5%88%A4%E5%AE%9A%E3%82%92%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F.html

##　実行方法
``` php
<?php
//リクエストするドメインとキー情報
$domain = "https://vision.googleapis.com";
$apiKey = [発行したapiキー];

//画像をbase64でデコードする
$imgPath = [画像ファイルのパス];
$imgData = file_get_contents($imgPath);
$imgPostData = base64_encode($imgData);

//リクエストボディを指定
$requestBody = json_encode( array(
		"requests" => array(
			array(
				"image" => array(
					"content" => base64_encode( file_get_contents( $imgPath ) ) ,
				),
				//以下は欲しい情報に応じてリクエストする
				"features" => array(
					array(
						"type" => "FACE_DETECTION"
					) ,
					array(
						"type" => "LABEL_DETECTION",
						"maxResults" => 5
					) ,
					array(
						"type" => "SAFE_SEARCH_DETECTION"
					)
				),
			),
		),
	) );


$curl = curl_init();
//上記で記載のURLを指定
curl_setopt($curl, CURLOPT_URL, $domain."/v1/images:annotate?key=".$apiKey);
curl_setopt($curl, CURLOPT_HTTPHEADER, array( "Content-Type: application/json" )) ;
//上記で記載のリクエストbodyを指定
curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody);
//post形式を指定
curl_setopt($curl, CURLOPT_CUSTOMREQUEST,"POST");

//実行し、結果を変数に格納
$postData =curl_exec($curl);
curl_close($curl);

//表示
var_dump($postData);

<?php } ?>
 
```

リクエストのjson情報を変えれば、様々な情報を取得可能です。
EMR: AWS上のマネージド型のHadoopフレームワーク

Hadoopに関する基本的な内容をまとめてみたものです。Hadoopに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[AWS上のマネージド型のHadoopフレームワーク] (https://www.techcrowd.jp/bigdata/hadooponaws/)

# [短時間でHadoopクラスターが立ち上げられるEMR] (https://www.techcrowd.jp/bigdata/hadooponaws/)

Amazon EMRは、マネージド型のHadoopフレームワークを提供するAWSです。

Amazon EMRクラスターは数分間で起動させる事が可能で、
・Hadoopの設定
・クラスター設定や調整
・ノードのプロビジョニング
などの作業を行う必要はありません。

使ったコンピューティングインスタンスに対する料金が請求される従量料金金制なので、無駄な費用を支払わなくても済みます。
料金は１時間単位で計算されますから、インスタンスコストを削減する事も可能です。


# [Hadoop用の各種ツールや他のフレームワークも実行可能] (https://www.techcrowd.jp/bigdata/hadooponaws/)

・Hive
・Pig
・Hbase
・DistCp
・Ganglia
などHadoop用のツールは数多く存在しますが、Amazon EMRではそれらのツールも使用可能となっています。

さらに、
・インメモリ処理を行うApache Spark
・インタラクティブSQL用の Presto
などのフレームワークもAmazon EMRで使う事が出来ます。


# [Amazon EMRを使用する事のメリット] (https://www.techcrowd.jp/bigdata/emrstructure/)

Amazon EMR は、HadoopクラスターをAWSで実行する時に利用出来るサービスです。
Hadoopクラスターが起動すると、Amazon EC2の仮想サーバーで処理が実行されますが、Amazon EMRによってAWSが円滑に利用出来るようになっています。

その他にもAmazon EMRを利用する事で、
・複数のクラスターへの同時アクセス
・Hadoop用アプリケーションの使用
・一般的なBIツールの使用
・Amazon EMR コンソールでの管理
・セキュリティの強化
などのメリットを享受出来ます。

# [ノードやステップなどの新しい技術が使われている] (https://www.techcrowd.jp/bigdata/emrstructure/)

Amazon EMRは、単にHadoopとAWSを統合するだけではなく、ノードやステップなどの新しい技術を使って分散処理が行われます。

ノードに関しては、ノードタイプとして参照される3種類のロールが定義されています。

マスターノード
クラスターを管理するノードで、各クラスターに一つしか存在しません。
各タスクのステータスやインスタンスグループの状態を監視し、正しい状態を維持するように管理を行います。

コアノード
Hadoopスレーブノードにマップされるノードで、Hadoop Distributed File System（HDFS）を使ってタスクの実行とデータの格納を行います。

タスクノード
Hadoop スレーブノードにマップされるノードで、タスクを実行します。

ステップはデータを操作する指示の事で、一つ以上のHadoop ジョブが指定出来ます。
・データの復号化
・データの処理
・データの暗号化
・データの保存
などの内容がステップで指示されます。

# [Amazon EMR以外のAWSとの連携が可能] (https://www.techcrowd.jp/bigdata/emrstructure/)

Amazon EMR はHDFSを利用出来るだけでなく、
・Amazon EC2
・Amazon S3
・DynamoDB
・Amazon RDS AWS
などのAWSと統合する事も可能です。

そのため、AWSに保存されているデータにクラスターからアクセスしたり、AWSの機能を利用してクラスターの管理や出力を行う事も出来ます。
Githubの複数リポジトリ毎に鍵を分ける


## .ssh/config

お仕事用と趣味でリポジトリを分けている。
原則リポジトリ毎に鍵を管理したいので、複数リポジトリ毎に鍵を分ける。

```.ssh/config
Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github
  User git
  port 22

Host github.com.private
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github_private
  User git
  port 22
```

Host名を分ければよい。

```
$ ssh -T github.com.private
Hi private_account! You've successfully authenticated, but GitHub does not provide shell access.
```

クローンできた。

```
$ git clone git@github.com.private:private_account/repository.git
```

## 設定

必要に応じて設定が必要。

ユーザ情報

```
$ git config user.name "private_accountのユーザーネーム"
$ git config user.email "private_accountのメールアドレス"
```

リモートURL

```
$ git remote add origin git@github.com.private:private_account/repository.git
$ git remote set-url origin git@github.com.private:private_account/repository.git
```
Alarmを使い指定時間後にActivityを起動する

Alarmを利用して、画面のボタンをクリックした時点から指定時間経過後にActivityを起動する
アプリケーションを作成する。

#AlarmManager
Alarmを使った処理を行うためには、AlarmManagerを使う必要がある。
AlarmManagerを取得するコードは以下の通り。
finalを付けているのは、このインスタンスを内部クラスで使用するためである。

```Java
        final AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
```

#指定時間後のActivityの起動
次のコードでは、ボタンがクリックされた時の動作を記載している。
まず明示的Intentで実行するActivityのクラスを指定し、そのIntentをPendingIntentに設定している。
ボタンがクリックされたとき、このPendingIntentと指定時間をAlarmに設定している。
ここでは、現在時刻からWAIT_MILLISEC後にAlarmが起動するようにしている。

```Java
        Intent intent1 = new Intent(this,SubActivity.class);
        final PendingIntent pendingIntent1 = PendingIntent.getActivity(this,0,intent1,0);

        Button button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            //button1が押された時の処理
            @Override
            public void onClick(View v) {
                //現在時刻からWAIT_MILLISEC秒後の時刻にアラームをセットする
                alarmManager.set(AlarmManager.RTC_WAKEUP,
                        System.currentTimeMillis()+WAIT_MILLISEC,pendingIntent1);
            }
        });
```

#GitHubリンク
リポジトリ
https://github.com/tagfa/MyAlarm01
同じフォルダにある複数の圧縮ファイルをたった1つのコマンドで展開する方法

# 1. zipファイル
```
$ for f in *.zip ; do unzip $f ;done
```
# 2. tar.gzファイル
```
$ for f in *.tar*; do tar xf $f; done
```
など<br>
ubuntu14.04でアップデート後eth0が消えた

内容はタイトルの通りです．

http://hanposaki.blog.so-net.ne.jp/2014-03-09
こちらのサイトを参考にさせて頂きました．助かりました．

```
# lspci
Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
```
nicは認識されています．

```
# ls -F /lib/modules/4.4.0-78-generic/kernel/drivers/net/ethernet/realtek/
8139cp.ko  8139too.ko
```
8168のドライバが無いようなのでインストールします．


ここからは以下のサイトの The manual way を参考にしました．
https://unixblogger.com/2016/08/11/how-to-get-your-realtek-rtl8111rtl8168-working-updated-guide/

```
# apt-get install build-essentials
# sh -c 'echo blacklist r8169 >> /etc/modprobe.d/blacklist.conf'
```

http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=1&PNid=13&PFid=5&Level=5&Conn=4&DownTypeID=3&GetDown=false#2
このサイトから`LINUX driver for kernel up to 4.7`をダウンロード．

```
# tar xfvj 0009-r8168-8.044.02.tar.bz2
# cd r8168-8.044.02/
# ./autorun.sh
```

これで認識されるはず．

出来ない方は，linux-headersがインストールされてるかなどを確認してみてください．
Raspberry Pi 3をmastodon専用機にする

ここ数週間お一人様マストドンonラズパイしていますが、さほど問題は出ていないかと思います。
ほとんどフォローしない&フォロワーもない状態ですので、参考にならないかもしれませんが、、、

## Dockerは使わない

ただでさえ非力なラズパイを、仮想環境での処理はかわいそうな気がするので、今回はDockerを使わないで専用機にしてみたいと思います。

## 導入手順

without-Dockerな手順はすべてドキュメントに書かれています。
設定は基本的にDocker使用時と同じです。

https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md

ほとんどはドキュメント通りに進めればうまくいくのですが、ラズパイ用の修正点があったので以下にまとめます。

### ffmpeg

Debian系がいろいろあってffmpegのapt-getに対応していないようですのでセルフビルドを行います。
以下サイトを参考に進めればうまくいきます。
http://d.hatena.ne.jp/embedded/20151011/p2

### postgres

ドキュメントは以下のようになっていますが、

```
sudo apt-get install postgresql postgresql-contrib
```

私はうまくいかなかったので以下のようにしました。

```
sudo apt-get install postgresql-9.4 postgresql-contrib
```

### rbenv

ラズパイでのrbenvは以下Qiitaが参考になります。
http://qiita.com/u6k/items/ffb0265f6cbb58f2227d

### メール認証

私は普通にメールで認証を行いましたが、メール設定をしなくても以下コマンドでいけると思います。  

```
RAILS_ENV=production bundle exec rails mastodon:confirm_email USER_EMAIL=info@example.com
```

### 管理者権限

/home/username/liveに入って以下コマンドで指定userに管理者権限を与えることができます。

```
RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=user名
```

### お一人様でいきましょう

お一人様にする予定でしたらSINGLE_MODEの設定と新規登録の無効化(admin設定)をするといいですね。

参考: http://qiita.com/sawanoboly/items/c7d6b913fd5455fb0f36

認証終えたらメール設定を適当にしてしまう方法もあります。

## とりあえず快適です

![スクリーンショット 2017-05-02 6.28.06.png](https://qiita-image-store.s3.amazonaws.com/0/181869/185b5325-b7c6-c57a-b1e0-520bc43d31d3.png)

mastodon用アプリ、Pawooでも問題なく動いています。

ただしサーバがローカルにあるため、wi-fiに繋げてドメイン入力で見に行くと接続に失敗します。  
hostsの設定が必要なんでしょう。

サーバ関係に疎いため穴がたくさんありそうで怖いですが、とりあえず運用できそうな感じです。

ちなみにこちらが私のmastodonアカウントです。
https://mstdn.hisurga.com/@hisurga
GitHubリポジトリ毎に tmux のセッション作ったり ghq で自動で取得してくれたりするスクリプト

GitHubリポジトリを取ってきてtmuxの別セッションでそのコードを見たいとか、作業しててリポジトリ毎にtmuxのセッション分けたい、みたいな気持ちがよくあって、以下のような関数を `~/.zshrc` に入れて使っている。

```zsh
function tmux-look {
  local ghq_get_query="$(echo $1 | sed -e 's/^github\.com\///')"
  local ghq_look_query="$(echo $1 | sed -e 's/^https:\/\///' -e 's/^git@github\.com://' -e 's/^github\.com\///' -e 's/\.git$//')"
  ghq get $ghq_get_query || return 1

  local tmux_dir="$(ghq list -p -e $ghq_look_query)"
  local tmux_name="$(ghq list -e $ghq_look_query | sed -e 's/^github\.com\///')"
  [ -n "$tmux_dir" ] || return 1

  if [ -n "$TMUX" ]; then
    tmux -2 new-session -d -c $tmux_dir -s $tmux_name
    tmux switch-client -t $tmux_name
  else
    tmux -2 new-session -A -c $tmux_dir -s $tmux_name
  fi
}
```

上の関数は下記のコマンドをtmux内にいる場合とかの空気を読んでやってくれるようになっている。

```
ghq get https://github.com/tootsuite/mastodon
ghq get --look tootsuite/mastodon
tmux new-session -s tootsuite/mastodon
```

URLとかを与えた場合も適当に正規化するように書いているので、下のどのパターン渡しても上手くやってくれるようになっている。

```
tmux-look https://github.com/tootsuite/mastodon
tmux-look git@github.com:tootsuite/mastodon
tmux-look tootsuite/mastodon
```

(bitbucket.org とかは面倒くさくて対応していない)
Golang環境構築

## 概要
golangの実行環境構築と、hello, worldをやってみる。

## 環境
- CentOS 7.1
- go 1.8.1

## Goをインストール

```
$ cd /usr/local/src
$ sudo curl -O https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz
```

## PATHを通す
GOPATHは、ソースを設置する場所なので、適宜変更してください。

```bash:~/.bash_profile
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:/usr/local/go/bin
```

## hello, world
こちらを参考にやってみる。
https://golang.org/doc/install#testing

```
$ mkdir -p $HOME/go/src/hello
```

```
$ vi $HOME/go/src/hello/hello.go
```

```go:hello.go
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}
```

buildする。

```
$ cd $HOME/go/src/hello
$ go build
```

実行する。

```
$ ./hello
hello, world
```

## パッケージ管理
パッケージ管理ツールは色々あるが、depが一番よいと思う。

### depのインストール

```shell-session
$ go get -u github.com/golang/dep/cmd/dep
```

### ディレクトリ作成

```shell-session
$ mkdir -p $GOPATH/src/prj_root
```

### init
srcというディレクトリがないとエラーになる。

```shell-session
$ cd $GOPATH/src/prj_root
$ dep init
$ ls -l
total 8
-rw-r--r-- 1 root root 222 Sep  7 02:21 Gopkg.lock
-rw-r--r-- 1 root root 655 Sep  7 02:21 Gopkg.toml
drwxr-xr-x 2 root root   6 Sep  7 02:21 vendor
```

### moduleインストール
goのスクリプトを作成し、以下のコマンドを打つと、スクリプトを解析して、未インストールのパッケージを自動でインストールしてくれる。

```
$ dep ensure
```

## Tutorialなど
- [Go言語の初心者が見ると幸せになれる場所　#golang](http://qiita.com/tenntenn/items/0e33a4959250d1a55045)
- [A Tour of Go](https://go-tour-jp.appspot.com/welcome/1)

## 参考
- https://golang.org/doc/install
- [go言語をCentOS7にインストール](https://daichan.club/golang/744)
- [Go言語をyumで入れる](http://qiita.com/okataitai/items/4beaf74d284f5bdfae4b)
react-native link で正規表現絡みっぽいエラーが出てきた時。

仲間が作業終えたファイルのチェックを行おうとpullして``react-native link``を走らせたら以下のエラー。

```
rnpm-install ERR! Something went wrong while linking. Error: Expected "/* Begin ", "/*", "\"", "}" or [A-Za-z0-9_.] but "<" found.
Please file an issue here: https://github.com/facebook/react-native/issues

Expected "/* Begin ", "/*", "\"", "}" or [A-Za-z0-9_.] but "<" found.
```

初めは何か特定のpackageが不具合を起こしてるのかと思って、消してはlinkを試してたんだけど、どうやらiosへのlinkができないっぽいことに気づいた。

ググると、xcodeプロジェクトのheader pathがおかしいとか色々でてたので、とりあえずプロジェクトを開こうと。したら、以下のようにでてきてプロジェクト自体ひらけない。

```
cannot be opened because the project file cannot be parsed.
```


どうやら、xcodeのプロジェクトファイルで不具合？と思ってぐぐってみると、プロジェクトファイル内でconflictが起きているとこんなことが起こるらしい。

普通に開いて解消した。
anuglar-cliで簡単にAngular2のjsソースのサイズ圧縮（縮小化）とAoT化してみる


Angular2を利用してWebサービスUI開発を行う場合、どうしてもjsファイルのサイズが大きくなり、初期ロードに時間がかかってしまうのが難点です。

angular-cliを利用してプロジェクトを作って開発すれば、簡単にリリース用のJSファイルをAoT対応してgzipファイル化して書き出すことができるようです。

angular-cliでプロジェクト作って2ページ遷移する程度のほとんど実装を追加していないものをビルドしてみます。
##今回の実行環境
```
angular-cli: 1.0.0-beta.28.3
node: 6.10.3
os: macOS Sierra
```
##まずは普通のビルド

プロジェクトフォルダ直下で以下のangular-cliコマンド実行するとdistフォルダが作られリリース用のビルドされたjs等が書き出されます。
> ng build

書き出されたファイルサイズはこんな感じ
![スクリーンショット 2017-05-20 11.19.22.png](https://qiita-image-store.s3.amazonaws.com/0/9784/e5152a78-c380-3216-d457-5fd41f55770e.png "スクリーンショット 2017-05-20 11.19.22.png")
圧縮されていないのでvendor.bundle.js超でかい！！
ここにAngular2のソースがもりもり入っているっぽいです。


##リリース用サイズ縮小化
今度は-prodオプション付きで実行して圧縮してみます。
> ng build -prod

書き出されたファイルサイズはこんな感じ
![スクリーンショット 2017-05-20 11.03.00.png](https://qiita-image-store.s3.amazonaws.com/0/9784/afc5e6b2-0ed0-9322-f159-5e6f33f99fed.png "スクリーンショット 2017-05-20 11.03.00.png")
全体的にかなり圧縮されました。gzipファイルを利用できるWebサーバーを利用して公開できるのであればダウンロードされるファイルサイズがかなり小さくできます。Apacheとかだと.htaccessの設定で対応できるっぽいです。[参考：gzip圧縮転送についてトコトン調べてみた](http://satoyan419.com/gzip-compression/)

* vendor.bundle.jsでは3.3MB → 196KB
* polyfills.bundle.jsでは258KB → 28KB
* main.bundle.jsでは11KB → 4KB


##リリース用サイズ縮小化（AoT）

今度は-prodオプションと--aotオプション付きで実行して圧縮＆AoT（Ahead of Time）化してみます。

AoTとは、簡単にいうとページ表示時にAngular2が動的に行うもろもろの処理を前もって解析してソースにハードコーディングすることでアプリケーションの起動速度を高速化するものです。[参考：Angular2 AoTコンパイルでTechFeedを高速化した話](https://medium.com/@techfeed/angular2-aot%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%A7techfeed%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%96%E3%81%97%E3%81%9F%E8%A9%B1-55efa68189a5)
> ng build -prod --aot

書き出されたファイルサイズはこんな感じ
![スクリーンショット 2017-05-20 11.03.26.png](https://qiita-image-store.s3.amazonaws.com/0/9784/071f1f11-37b8-5948-8526-dc4024a834b4.png "スクリーンショット 2017-05-20 11.03.26.png")

* vendor.bundle.jsでは196MB → 95KB
* polyfills.bundle.jsでは28KB → 28KB
* main.bundle.jsでは4KB → 5KB(gzip)

#まとめ
今回ビルドしたプロジェクトは、アプリケーションの実装内容がほぼない状態の２ページを行ったり来たりできるだけのものだったので、実際にWebアプリケーションをごりごり実装した後にどうなるかはやってみないと分かりません。

しかし、angular-cliを利用してプロジェクトを作って開発すると、面倒な設定全くなしでかなり簡単にリリース用ファイルの圧縮化やAoT化ができることが分かりました。

次は、angular-cliでAngular2モジュールの遅延ロード(lazy load）を試してみます。
Spacemacsでクリップボードにコピー&ペースト

# 背景
Emacsは独自バッファでヤンク（コピー）・ペーストを行っています。
これ自体は便利なのですが、Emacsの環境外とのやり取りについて考慮する必要があります。

Emacsでは強引にドラッグしてクリップボードにコピーするなどしていました（恥ずかしい）。

そして最近Spacemacsに移行したのですが、なんとそれが出来なくなっていました。
うまくドラッグできないし、何よりOSのコピーコマンドが無効になっています。

応急処置的にorg-modeからhtmlを出力・ブラウザに吐き出してコピペしていたのですが、
文字コードや改行コードの都合で求めるビューが出なかったりするので、
いよいよ重い腰を上げてクリップボード操作をEmacsから出来るようにしようと思い立ちました。

# 解決法

Spacemacsのissueで上がってました。
https://github.com/syl20bnr/spacemacs/issues/2222

そもそもspacemacsのカスタマイズを何処に記述すべきか分かっていなかったのですが、ここなのですね。

```lisp:.spacemacs
(defun dotspacemacs/user-config ()
;;ここに設定を書く
)
```

## Macの場合

以下を`.spacemacs`の`(defun dotspacemacs/user-config ()`の下に追加。
`spc o y` / `spc o p`でコピー/ペーストができます。

```lisp:.spacemacs
(defun copy-to-clipboard ()
  "Copies selection to x-clipboard."
  (interactive)
  (if (display-graphic-p)
      (progn
        (message "Yanked region to x-clipboard!")
        (call-interactively 'clipboard-kill-ring-save)
        )
    (if (region-active-p)
        (progn
          (shell-command-on-region (region-beginning) (region-end) "pbcopy")
          (message "Yanked region to clipboard!")
          (deactivate-mark))
      (message "No region active; can't yank to clipboard!")))
  )

(defun paste-from-clipboard ()
  "Pastes from x-clipboard."
  (interactive)
  (if (display-graphic-p)
      (progn
        (clipboard-yank)
        (message "graphics active")
        )
    (insert (shell-command-to-string "pbpaste"))
    )
  )
(evil-leader/set-key "o y" 'copy-to-clipboard)
(evil-leader/set-key "o p" 'paste-from-clipboard)
```

## Linuxの場合


はじめに、xselのインストールが必要です。 

```bash
$ apt install xsel
```


続いて以下を`.spacemacs`の`(defun dotspacemacs/user-config ()`の下に追加。

`spc o y` / `spc o p`でコピー/ペーストができます。

```lisp:.spacemacs
(defun copy-to-clipboard ()
  "Copies selection to x-clipboard."
  (interactive)
  (if (display-graphic-p)
      (progn
        (message "Yanked region to x-clipboard!")
        (call-interactively 'clipboard-kill-ring-save)
        )
    (if (region-active-p)
        (progn
          (shell-command-on-region (region-beginning) (region-end) "xsel --clipboard --input")
          (message "Yanked region to clipboard!")
          (deactivate-mark))
      (message "No region active; can't yank to clipboard!")))
  )

(defun paste-from-clipboard ()
  "Pastes from x-clipboard."
  (interactive)
  (if (display-graphic-p)
      (progn
        (clipboard-yank)
        (message "graphics active")
        )
    (insert (shell-command-to-string "xsel --clipboard --output"))
    )
  )
(evil-leader/set-key "o y" 'copy-to-clipboard)
(evil-leader/set-key "o p" 'paste-from-clipboard)
```

`pbcopy` / `pbpaste` がないのでクリップボードを操作するコマンド　`xsel --clipboard --input` / `xsel --clipboard --output` を使用します。

# コピペは `SPC o y` `SPC o p`で
Spaceキー操作は病みつきになりますね。
それだけでもSpacemacsにして良かったです。
とりあえずFloydhubで遊んでみた

# はじめに
[Floydhub](https://www.floydhub.com) とはDeepLearningのためのHerokuのようなサービスでTensorFlowやChainerを使ったプログラムをCloudで動かすことができます。
Floydhubの特徴は


- Chainer, TensorFlow, Keras, theano等が使える
- アカウントの作成にクレジットカードは必要ない

今回はとりあえずアカウントの作成からGet Startedをやってみます。

# アカウントの作成
アカウントは無料で作れます。クレジットカードは今は必要ありません。https://www.floydhub.com からSign Upすると以下のWelcome Pageに移ります。

<img width="982" alt="floyd1.png" src="https://qiita-image-store.s3.amazonaws.com/0/157216/02c227d2-15f6-a853-412a-a03d7e7cd847.png">


# Get Started
## Setup floyd-cli
アカウント作成後、メールが届いてるので認証します。
ターミナル上で、適当な作業ディレクトリに移動してからfloyd-cliをインストールします。

```
pip install -U floyd-cli
```


ログインします。

```
floyd login
```

すると、

```
Authentication token page will now open in your browser. Continue? [Y/n]:
```
と聞かれるので、yを入力し進めるとWelcome pageが開きます。Welcome Pageの一番下にあるauthentication tokenをコピーしてターミナル上に貼り付けるとLogin Successfulと出るはずです。

## Run First Project
次にTensorflowを動かしてみる。

<img width="985" alt="floyd2.png" src="https://qiita-image-store.s3.amazonaws.com/0/157216/f4017c3d-17ac-1547-1ec3-bac73d560d20.png">

Welcome Pageに書いてある通りに進めるだけです。

```
$ git clone https://github.com/floydhub/tensorflow-examples.git
Cloning into 'tensorflow-examples'...
remote: Counting objects: 74, done.
remote: Total 74 (delta 0), reused 0 (delta 0), pack-reused 74
Unpacking objects: 100% (74/74), done.

$ cd tensorflow-examples/3_NeuralNetworks/

$ floyd init dynamic-rnn
Project "dynamic-rnn" initialized in current directory

$ floyd run "python dynamic_rnn.py"
```
floyd run "python dynamic_rnn.py"の実行後にExperimentsに行くとプログラムが動いてるのを確認できます。

<img width="983" alt="floyd3.png" src="https://qiita-image-store.s3.amazonaws.com/0/157216/95759578-28bf-b02c-e53b-b69dc76761df.png">

ちなみに、Failedとなっているのはプログラム名を間違えて実行したためです。
○ floyd run "python dynamic_rnn.py"
× floyd run "python dynamic-rnn.py"

```
$ floyd logs -t <RUN_ID>
```
で、学習の途中経過を確認できます。
学習結果はDataにあるみたいです。

<img width="984" alt="floyd4.png" src="https://qiita-image-store.s3.amazonaws.com/0/157216/c5f8f7f1-0bd7-36fa-9b75-2b44fd2e34a1.png">

おわり。
ブラウザバック禁止


小ネタ。
少し前に諸事情で対応が必要になったので。

```js:
window.location.hash="#noback";
window.onhashchange=function(){
    window.location.hash="#noback";
}
```

http://hidari-lab.hatenablog.com/entry/2015/03/02/212818
に詳しいです。

>URLにhash（URLの後ろにくっつく#HogeHogeみたいな文字列で、ページ内リンクなんかに使われてる）をつけることで別ページへの遷移として履歴に残して、他のページに戻れなくしてしまう方法。

ブラウザの「戻る」ボタン長押しなどで、履歴を直接たどるのは止められないけど、無意識にブラウザバックする人は止められるかなと。
Vue.jsの開発に役立つかもしれないあれこれ

Vue.jsの開発に役立つかもしれないあれこれの紹介です。内容は随時更新していきたいと思います。

##Chromeデベロッパーツール

[Vue.js devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=ja)

##開発ツール

[vue-styleguide-generator](https://github.com/shershen08/vue-styleguide-generator)
コンポーネントの詳細をhtmlファイルに出力する。

[vue-play](https://github.com/vue-play/vue-play)
コンポーネントのデモを可能にするライブラリ。
※上記２つのライブラリについてはこちらも参照してみてください。
[vue-playとvue-styleguide-generatorでVueコンポーネント開発](http://labs.septeni.co.jp/entry/2017/06/01/134300)

##ライブラリ（主にUI）

[VueStrap](https://yuche.github.io/vue-strap/)
[Element](http://element.eleme.io/#/en-US)
[Muse-Ui](http://www.muse-ui.org/#/index)
[Vue Material](https://vuematerial.github.io/#/getting-started)

##チートシート

[Vue用](https://github.com/vuejs-tips/cheatsheet)
[Vuex用](https://github.com/vuejs-tips/vuex-cheatsheet)

##Atomプラグイン
[こちら](http://qiita.com/mrmr/items/f6927eb2fe5aa13a2f90)を参照ください。

##開発ノウハウ

[Vue.js Component Style Guide](https://pablohpsilva.github.io/vuejs-component-style-guide/#/)
(日本語訳を作ってみました。)
openFrameWorksでROSを使う

#目的
openFrameWorksで作成したアプリケーションからROS通信を行う方法。
[PCL_ROSをMakeFileでコンパイルする](http://qiita.com/nnn112358/items/cdb899d21655b8b6c21b)のやり方に等しい。

#openframeworksとは
"「創造的なコーディング」のためのC++のオープンソースツールキット"
http://openframeworks.cc/ja/

強力なアドオンを組み込むことができる。
http://ofxaddons.com/popular

#openframeworksのプロジェクト作成
projectGeneratorでプロジェクト作成

![Screenshot from 2017-05-20 10-06-55.png](https://qiita-image-store.s3.amazonaws.com/0/73020/714a3e6f-10cd-868c-cd04-5685a687c364.png)

#Makefileの編集
Makefileとconfig.makeを編集する。

##Makefile
Makefileにopenframeworksのルートディレクトリを追記する。
絶対パスを指定するとどのフォルダでもコンパイルすることができるようになる。

```
ifneq ($(wildcard config.make),)
	include config.make
endif

ifndef OF_ROOT
    OF_ROOT=$(realpath /home/nnn112358/Documents/of_v0.9.8_linux64/)
endif

include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
```

##config.make
config.makeにROSとのリンクを記載する。

```
PROJECT_LDFLAGS=-Wl,-rpath=./libs
PROJECT_LDFLAGS+=$(SUBLIBS) $(ros_libs_nocolon) 
ros_libs = $(shell pkg-config --libs roscpp nav_msgs tf)
ros_libs_nocolon = $(subst -l:,,$(ros_libs))
PROJECT_OPTIMIZATION_CFLAGS_DEBUG = `pkg-config --cflags roscpp nav_msgs tf` -w -O2 
PROJECT_OPTIMIZATION_CFLAGS_RELEASE = `pkg-config --cflags roscpp nav_msgs tf` -w -O2 

```


#ソースの編集
ソースにROSとの通信処理を書く。
ros::initはmainの引数が必要なので、main.cppにros::initを記載し、
初期化処理はofApp::setup()
逐次処理はofApp::update()
に記載する。


##main.cpp

```
#include "ofMain.h"
#include "ofApp.h"
#include <ros/ros.h>

int main(int argc, char *argv[]){
    ros::init(argc, argv, "ros_tutorial_msg_publisher");  // ROSノード名の初期化
　　 ofSetupOpenGL(1024,768,OF_WINDOW);			
    ofApp *app = new ofApp();
    ofRunApp(app);
}
```

##ofApp.cpp

```
void ofApp::setup(){
    chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
}
void ofApp::update(){
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << endl;
    msg.data = ss.str();

    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);
    ros::spinOnce();
}
```

https://github.com/nnn112358/Openframeworks_ROS/tree/master/myempty_ROS
[AutoHotKey]OnClipboardChange()関数でクリップボード監視


だいたい引用。

## OnClipboardChangeサブルーチンラベルの問題
AutoHotKeyには`OnClipboardChange`という組み込みラベルがあり、このラベルのサブルーチンに記述した処理が、**クリップボードが変更された時**に自動的に実行されます。
常駐スクリプトとして実行すれば、クリップボードを監視してなにかをしてくれるわけです。

- [クリップボード \- AutoHotkey Wiki](http://ahkwiki.net/Clipboard)

ただし、この「クリップボードが変更された時」というのに、**スクリプトの起動時**も含まれるのが問題でした。

スクリプトを起動した時（あるいはリロードした時）、あたかも同時になにかをコピーしたかのように反応するので、常駐スクリプトの編集中などはウザいことこの上ない感じでした。

## 問題を解決したOnClipboardChange()関数
しかし、現在の最新バージョンでは`OnClipboardChange()`関数が実装されており、これは**スクリプト起動時を除く**クリップボードの変更に反応してくれます。
上記の問題が解消されている以外、機能的には旧来のラベルと全く同じです。

- [AutoHotkey スレッド part24 \[無断転載禁止\]©2ch\.net](https://potato.2ch.net/test/read.cgi/software/1487149472/35-37)
- [OnClipboardChange](https://autohotkey.com/docs/commands/OnClipboardChange.htm)

そこで、元々ラベルで書いていた、クリップボードの変更を監視してコピーした文章をツールチップで表示するスクリプトを手直ししてみました。
元のスクリプトは以下のページを参考にしました。

- [コピーしたらツールチップを表示 | つぼログ。 | 横浜で翻訳業務を行うシーブレインスタッフによる技術情報ブログ](http://tsubolog.c-brains.jp/15/05/08-100000.php)

```ahk
; Includeして使っているので#Persistentなし
OnClipboardChange("ClipChanged")
Return

ClipChanged(Type) {
    if (Type = 1) { ;テキストの場合は内容を表示
        StringLen, length, Clipboard
        if (length>200) { ;長いテキストの場合は最初の200文字を表示
            ShortCB := SubStr(Clipboard, 1, 200)
            ToolTip テキストをコピーしました`n%ShortCB%
            RemoveToolTip(1500)
        }
        else { ;短いテキストの場合は内容を表示
            ToolTip テキストをコピーしました`n%Clipboard%
            RemoveToolTip(1500)
        }
    }
    else if (Type = 2) { ;テキスト以外の場合は適当に表示
        ToolTip 非テキストデータをコピーしました
        RemoveToolTip(1500)
    }
}
```

基本的にはラベルサブルーチンの内容を`OnClipboardChange()`の引数として指定した名前の関数に放り込めば問題ありませんが、クリップボードの**データ種別**を示す値の取り扱いが変わっています。
組み込み変数`A_EventInfo`は利用できず、代わりに関数のパラメータとして代入されます。この場合は`Type`です。
取りうる値は、「0：空」「1：テキストデータ」「2：非テキストデータ」で変わりありません。

### クリップボードの監視を停止する
特にホットストリングでスニペットのペースト処理をしてる場合などは、都度停止させないとツールチップが邪魔です。

- [AutoHotKeyで、TextExpander風にスニペットに他のスニペットを埋め込んだりしたい \- Qiita](https://qiita.com/catfist/items/8047598e5e0d105b5b59)

そこで、グローバル変数でフラグを管理してペーストする関数でフラグを切り替え、とかやっていたのですが、実は`OnClipboardChange()`関数自体に動作を停止するオプションがありました。

> AddRemove
> > One of the following values:
> > 1 (the default): Call the function after any previously > > registered functions.
> > -1: Call the function before any previously registered functions.
> > 0: Do not call the function.

というわけで、ペースト関数を以下のようにすれば誤動作は防げます。

```:ahk
PasteString(String)
{
	OnClipboardChange("ClipChanged",0)
	Backup := ClipboardAll
	Clipboard := String
	Sleep, 100 ; 削除が間に合わないので
	SendPlay, ^v
	Clipboard := Backup
	OnClipboardChange("ClipChanged",1)
}
```
AutoHotKeyのグローバル変数を、関数内で参照する


## AutoHotKeyスクリプトにおけるグローバル変数とローカル変数

[Variables and Expressions](https://autohotkey.com/docs/Variables.htm)

> With the exception of local variables in functions, all variables are global; that is, their contents may be read or altered by any part of the script. Except where noted on the functions page, variables do not need to be declared; they come into existence simply by using them (and each variable starts off empty/blank).

（Google翻訳）

> 関数のローカル変数を除いて、すべての変数はグローバルです。 つまり、その内容はスクリプトの任意の部分によって読み取られたり変更されたりする可能性があります。 関数ページに記載されている場合を除いて、変数は宣言する必要はありません。 それらを使用することによってそれらが存在するようになります（そして、各変数は空白/空白で始まります）。

これを読むと、「関数内でローカルに格納された変数は、関数外から参照できない」ということはもうそのまんまわかる。

AutoHotKeyスクリプトにおいて、「ローカル変数」というのは**関数ローカル**という意味でしかない。スレッドローカルとか、サブルーチンローカルとか、ラベルローカルとか、そんなもんはない。

関数以外で格納された全ての変数と、関数内で`global`として宣言された変数は、グローバル変数である。つまり、スクリプト内のどこからでも参照できるはずである。

では、「関数外でグローバルに格納された変数は、関数内から参照できるのか」。できそうに思える。

## 関数からグローバル変数を参照する
ところがぎっちょん。

以下のスクリプトでは、普通に`MsgBox`した時にローカル変数`LVar`が空なのは当然として、関数`TestFunc`から`MsgBox`した時、グローバル変数`GVar`は空になる。

```ahk
GVar = hoge ; グローバル変数GVarをつくる

MsgBox, , %A_ScriptName%, This is plain command`nGvar = %GVar%`nLVar = %LVar%
; LVarは空
TestFunc()
; GVarは空
Exit

TestFunc() {
    LVar = fuga ; ローカル変数LVarをつくる
    MsgBox, , %A_ScriptName%, This is function`nGvar = %GVar%`nLVar = %LVar%
}
```

実はもう一手間必要で、**関数内で改めてグローバル変数宣言を行う**ことで、参照ができるようになる。

```ahk
GVar = hoge ; グローバル変数GVarをつくる

MsgBox, , %A_ScriptName%, This is plain command`nGvar = %GVar%`nLVar = %LVar%
; LVarは空
TestFunc()
; GVar/LVarとも出力される
Exit

TestFunc() {
    global GVar ; GVarをこの関数内においてグローバル変数として宣言する
    LVar = fuga ; ローカル変数LVarをつくる
    MsgBox, , %A_ScriptName%, This is function`nGvar = %GVar%`nLVar = %LVar%
}
```

つまるところ、関数内においては、あらゆる変数がいったんローカル変数として参照されるわけだ。

## スーパーグローバル変数
日本語資料がロクになくて苦労したのだが、上記の問題は**スーパーグローバル変数**として宣言することで解決できる。

[Functions#Super-global variables](https://autohotkey.com/docs/Functions.htm#SuperGlobal)

> Super-global variables [v1.1.05+]: If a global declaration appears outside of any function, it takes effect for all functions by default. This avoids the need to redeclare the variable in each function.

やり方は簡単で、**関数外において、変数をグローバル変数として宣言すればよい**。
スーパーグローバル変数は、関数内での宣言がなくとも、あらゆる関数内で自動的にグローバル変数として参照される。

```ahk
global GVar ; GVarをスーパーグローバル変数として宣言
GVar = hoge ; グローバル変数GVarをつくる

/* こういう書き方でもいい
global GVar := "hoge" ; グローバル変数GVarをつくる
*/

MsgBox, , %A_ScriptName%, This is plain command`nGvar = %GVar%`nLVar = %LVar%
; LVarは空
TestFunc()
; GVar/LVarとも出力される
Exit

TestFunc() {
    LVar = fuga ; ローカル変数LVarをつくる
    MsgBox, , %A_ScriptName%, This is function`nGvar = %GVar%`nLVar = %LVar%
}
```

逆に言えば、関数内の処理だけで、スーパーグローバル変数を宣言することはできない。

なにやら[class](https://autohotkey.com/docs/Objects.htm#Custom_Classes)がどうこうとかも書いてあるのだが、さっぱり理解できないので諦めた。

## 引数渡し
また別の方法としては、グローバル変数を引数として渡してしまうというのもある。

```ahk
GVar = hoge ; グローバル変数GVarをつくる

TestFunc(GVar) ; GVarを引数として受け取り、ローカル変数ArgVに格納
; ArgV/LVar共に出力される
Exit

TestFunc(ArgV) {
    LVar = fuga ; ローカル変数LVarをつくる
    MsgBox, , %A_ScriptName%, This is function`nGvar = %ArgV%`nLVar = %LVar%
}
```
TensorFlow global_step を保持して学習再開

global_step を保持しないまま学習を再開、追加学習すると、
全体として何stepしたのかわからないのと、
model.ckpt-xxx (xxxはstep数) がまた0からになってしまうのが嫌だったので。

```py3
import os
from datetime import datetime
import tensorflow as tf

FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('checkpoint_dir', "./models/",
                           """Directory path of model checkpoint save.""")
tf.app.flags.DEFINE_string('checkpoint_name', "model.ckpt",
                           """Checkpoint name.""")
tf.app.flags.DEFINE_integer('max_steps', 1000,
                            """Number of batches to run.""")
def main(argv=None):
    global_step = tf.Variable(0, name='global_step')
    global_step_holder = tf.placeholder(tf.int32)
    global_step_op = global_step.assign(global_step_holder)

    saver = tf.train.Saver()

    with tf.Session() as sess:
        checkpoint = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
        if checkpoint:
            print(checkpoint.model_checkpoint_path)
            print("variables were restored.")
            saver = tf.train.Saver()
            saver.restore(sess, checkpoint.model_checkpoint_path)
        else:
            print("variables were initialized.")
            sess.run(tf.global_variables_initializer())

        checkpoint_path = os.path.join(FLAGS.checkpoint_dir, FLAGS.checkpoint_name);

        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)
        try:
            for step in range(global_step.eval() + 1, FLAGS.max_steps + 1):

                # do some train operation here

                if step % 10 == 0:
                    sess.run(global_step_op, feed_dict={global_step_holder: step})
                    print("%s: step %d)" % (datetime.now(), step))
                    saver.save(sess, checkpoint_path, global_step=step)
        finally:
            coord.request_stop()
            coord.join(threads)

if __name__ == '__main__':
    tf.app.run()
```

global_step を 保存できるようにしたら、

```py3
sess.run(global_step_op, feed_dict={global_step_holder: step})
```

として代入するオペレーションを実行してあげることでsaveした時に保持されます。
デザインパターン学習メモ：「Proxy」

## このパターンの目的
GoF本より引用する。

> あるオブジェクトへのアクセスを制御するために、そのオブジェクトの代理、または入れ物を提供する。(P.221)

「代理」を使ったほうがよいケースはいくつかある。たとえば、重い処理は必要になる時まで遅延させ、代理のオブジェクトが代わりに応答することでレンスポンスタイムが短くなる。

GoF本では、エディタにおける画像の読み込みの例が挙げられている。

エディタでは、その画像が本当に必要になるまで（その箇所が利用者に読まれるまでは）、画像ファイルの読み込み（ディスクへのIOが大きい）は遅延させてよい。つまり、ファイルをオープンした時に、すべての画像をディスクから読みだす必要はない。

その他の用途としては、実際のオブジェクトが処理を行う（メソッドを実行する）前後に、プロキシオブジェクトによる処理を実行することができるようになる。


## 構造
### Subject
プロキシオブジェクトと実オブジェクトが共に実装するインタフェース

### Proxy
プロキシオブジェクト。利用者はこのインスタンスを生成して利用する。
一部の処理（メソッド）を実オブジェクトに委譲する。その前後にプロキシオブジェクトは独自の処理を実行する可能性もある。

### Real Subject
実オブジェクト。利用者はプロキシオブジェクトを使う代わりに、こちらのクラスを使うこともできる。

## 実装例

簡単に書ける有効な例が思いつかなかった。

「１.Real Subjectは生成に時間がかかり、２．Proxy単体でもある程度の仕事ができる」という例を考えたが、何も思い浮かばない。




## 参考文献
 * エリック ガンマ、ラルフ ジョンソン、リチャード ヘルム、ジョン プリシディース（1999）『オブジェクト指向における再利用のためのデザインパターン　改訂版』本位田　真一、吉田　和樹 監訳、SBクリエイティブ
iTerm2 ー 同じディレクトリで新しいタブを開く

**Preference > Profiles > General > WorkingDirectory > Reuse previouse sessions's directory**

にチェックを入れる。

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/4d60d694-f459-6870-163c-ee41dfb0b5bb.png)

これで随分楽になりそうだ。

最終セッションと同じディレクトリでタブを開いてくれるようになる。

# 環境

- iTerm2 3.0.15








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Unityバージョンアップ時のプロジェクトのアップデート

# Unityをバージョンアップすると。。。

Unityをバージョンアップすると、旧プロジェクトをOpenしようとするとメッセージが表示される。

![バージョンアップ後に旧プロジェクトをOpenすると出てくるダイアログ.png](https://qiita-image-store.s3.amazonaws.com/0/179875/2f268bb3-4168-c7ff-251c-d517bdeffaa5.png)

近いバージョンでも、ちょっとでも作成時のバージョンと異なればメッセージが出てしまう。

Continueで開くと普通にプロジェクトは開ける。
そしてその新しいバージョンでプロジェクトを保存するとどうなるか。

新しいバージョンで保存したので、2回目以降はこのメッセージが出なくなると思ったのだが、
結論としてはこのメッセージが出てしまった。

# ReImport

「This may require re-import」と書いてあるため、ReImportすればいいのかとこれも試してみた。

Unityメニューの「Assets」->「ReImport」を選択。

![reimport.png](https://qiita-image-store.s3.amazonaws.com/0/179875/4238aa01-6bd9-2f29-1173-2c60f53c0866.png)

これで保存し、再起動。
結果、変わらず。。。

# プロジェクトを変更して保存

最初に試したプロジェクトの保存は、何も変更を加えない状態での保存だった。
そこで、適当に中身を編集した上で保存してみた。
（パラメータの数値をいじる等）

結果、これでプロジェクトのバージョンが、バージョンアップしたUnityと同じになった。
その後、Open時のメッセージは出なくなった。

Unityの立ち上げ時のプロジェクト選択画面にそのプロジェクトのUnityバージョンが表示されている。
ここが更新されていればOK。

![projects3.png](https://qiita-image-store.s3.amazonaws.com/0/179875/d05dedfb-9c9c-5126-80a6-dce6f3444a6f.png)

# 結論

Unityのバージョンとプロジェクトのバージョンはちょっとでもズレるとメッセージが出る。
（だからといって動かないわけではない。バージョンアップによる変化点が影響するかどうかは、
バージョン間の変化点と使用している機能やコード次第かと。当然ですが）

実際、マイナーバージョンアップでそこまで致命的な問題が発生するとは考えにくいが、
バージョン不一致が気になる場合はこのような形でバージョンを揃えておくとよい。
（新バージョンで何かしらの開発をすれば自ずと対応されるかとは思いますが。。。）

今回は内部的なバージョンの紐付け直しについてのみ確認したが、
その他、バージョンアップ時に伴うTodoやトラブルシュートなど発生したら追記していきたい。
set_error_handlerは局所的にも使える

# [`set_error_handler`] って何？

この辺読んでね。

- [PHP: set_error_handler - Manual](http://php.net/manual/ja/function.set-error-handler.php)
- [set_error_handler と ErrorException を組み合わせると幸せになるかも - Qiita](http://qiita.com/suin/items/14c455691a0391ee265c)
- [お前は PHP 7 における Fatal Error / Catchable Fatal Error / Error / ErrorException / Exception の違いを言えるか？ - Qiita](http://qiita.com/mpyw/items/c69da9589e72ceac470c)

# [`set_error_handler`] にまつわる杞憂

## ありがちな心配？

- ライブラリ側で勝手にこれ使うと，元のアプリケーション側で設定されてるハンドラを吹き飛ばしてしまうんじゃ？
- [`restore_error_handler`] を呼んでも，結局エラーハンドラが無かった状態に戻るだけでは？

```php:exif_*ってデータ次第でエラー発生するしエラーハンドラ使いたいけどライブラリ関数側で使うとなぁ…もう@演算子でいいや…
function read_image_metadata(string $filename)
{
    if (false === $type = @exif_imagetype($filename)) {
        throw new \RuntimeException(error_get_last()['message']);
    }
    if ($type !== IMAGETYPE_JPEG) {
        return [];
    }
    if (false === $data = @exif_read_data($filename)) {
        throw new \RuntimeException(error_get_last()['message']);
    }
    return $data;
}
```

## そんなことはない！

[`set_error_handler`]はスタッカブルであるため，リストアするとちゃんと**直前に設定されていたエラーハンドラ**に戻してくれる。

```php:finallyで自動的にリストアさせる
function read_image_metadata(string $filename)
{
    set_error_handler(function($severity, $message) {
        throw new \RuntimeException($message);
    });
    try {
        $type = exif_imagetype($filename);
        if ($type !== IMAGETYPE_JPEG) {
            return [];
        }
        return exif_read_data($filename);
    } finally {
        restore_error_handler();
    }
}
```

若干関数呼び出しのオーバーヘッドがあるが，書きやすくすることも可能だ。

```php:関数で共通化する
function handle_error(callable $function, ...$args)
{
    set_error_handler(function($severity, $message) {
        throw new \RuntimeException($message);
    });
    try {
        return $function(...$args);
    } finally {
        restore_error_handler();
    }
}

function read_image_metadata(string $filename)
{
    return handle_error(function () use ($filename) {
        $type = exif_imagetype($filename);
        if ($type !== IMAGETYPE_JPEG) {
            return [];
        }
        return exif_read_data($filename);
    });
}
```

[`set_error_handler`]: http://www.php.net/manual/ja/function.set-error-handler.php
[`restore_error_handler`]: http://php.net/manual/ja/function.restore-error-handler.php
Kotlin で簡単なプログラムを書いてみる

[JavaプログラマのためのKotlin入門](http://qiita.com/koher/items/bcc58c01c6ff2ece658f)を読みながら、[Kotlinお試しコーナー](
https://try.kotlinlang.org)で。
50以下の素数を求める。

```kotlin
class PrimeCalc(val maxN : Int) {
    fun isPrime(n : Int): Boolean {
     	if (n < 2) {
            return false
        } else if (n == 2) {
            return true
        } else if (n % 2 == 0) {
            return false
        } else {
            var i = 3
            while (i * i <= n) {
                if (n % i == 0) {
                    return false
                }
                i += 2
            }
            return true
        }
    }
    
    fun run(): Unit {
        for (i in 2..maxN) {
            if (isPrime(i)) {
                println(i)
            }
        }
    }
}

fun main(args: Array<String>) {
    val calc = PrimeCalc(50)
    calc.run()
}
```

Java よりはるかにすっきり書ける。
Scala と比べたらどうなんだろう？
Scala の代替物となりうるのだろうか？
three.jsで簡易残像表示

(R84利用)

Processingでよくやる手抜きモーションブラー的なやつがthree.jsで若干つまづいた＋意外と情報がなかったのでメモ。まず呼び方がわからない。

こういうやつ。

![スクリーンショット 2017-05-17 20.14.45.png](https://qiita-image-store.s3.amazonaws.com/0/45247/720ce6b5-2e24-fe13-bc8a-b1902936d447.png)

この描画量でTHREE.Line30本で済むのでエコ。


# Processingの場合どうやっていたのか

```c
// メインループ
void draw(){
  // 通常特定の色でクリアするところを
  // background(0);

  // 半透明のrectでちょっとずつフェードアウト
  noStroke();
  fill(0, 20);
  rect(0, 0, width, height);

  // なんらかの描画処理
  // ...
}
```

# 同じことをしようとしてthree.jsでつまづいた点

- 普通に書くときっちりクリアされてしまう
- 背景も回ってしまう
- renderer.autoClear = false;ではないっぽい
- 軌跡表示まではできたのに半透明処理がおかしくなる

---

ということで色々検索したり検索したりしながら最終的に動いたコードの中から必須な箇所をピックアップ。


# Three.jsコード

## レンダラー設定

THREE.WebGLRendererで`preserveDrawingBuffer`を有効にする。

```js
var renderer = new THREE.WebGLRenderer({
  preserveDrawingBuffer: true //これが重要
});
renderer.autoClearColor = false; //  これも必須
// renderer.autoClear = false; //これは不要
```
`autoClear`をfalseにするのではなく`autoClearColor`を`false`にする
この辺を間違えると`preserveDrawingBuffer: true`の状態だと背景オブジェクトに重なった部分が一切描画されないという状態になり困る。

## 描画を少しずつ消していくため半透明のplaneオブジェクトを追加

描画したいオブジェクトと同じシーンを使うとカメラを回した時に同じように回ってしてしまうので、planeオブジェクトのみを扱うシーンとカメラを追加する。この場合のカメラは`THREE.OrthographicCamera`を使うと便利(`WIDTH`, `HEIGHT`は別途定義したcanvasサイズ定数）

```js
var scene_bg = new THREE.Scene();
var camera_bg = new THREE.OrthographicCamera(0, WIDTH, HEIGHT, 0, 0, 1000);
var bg_geometry = new THREE.PlaneGeometry(WIDTH, HEIGHT, 10, 10);
var bg_material = new THREE.MeshBasicMaterial({
  color: 0x000000,
  transparent: true,
  opacity: .04,
});
var bg = new THREE.Mesh(bg_geometry, bg_material);

//位置調整して追加
bg.position.x = WIDTH/2;
bg.position.y = HEIGHT/2;
scene_bg.add(bg);
```

`transparent: true`がないと半透明にならないので忘れないようにして、`opacity`の値で減衰速度を調整。

## 残像表示するメインのオブジェクトを追加

描画するオブジェクトは適当なものを適当に追加して動かす。動かさないと何も起こらない。
またマテリアルによってはライト追加するまで出来ているのか判断しづらいので一旦wireframe状態で行うとわかりやすい。

```js
var box = new THREE.BoxGeometry(2, 2, 2);
var mat = new THREE.MeshBasicMaterial({
  color: 0xffffff,
  wireframe: true    // wireframeである必要はないが効果が確認しやすい
});
var mesh = new THREE.Mesh(box, mat);
scene.add(mesh);
```

他Line系のTHREEオブジェクトやモデリングデータをwireframe表示したものもそれっぽくなりやすい。

## レンダーループ(requestAnimationFrame内部)

```js
// boxgeometryを回す。
mesh.rotation.x+=.01;
mesh.rotation.y+=.02;

// レンダー
renderer.render( scene_bg, camera_bg );
renderer.render( scene, camera );
```

背景>メインの順でレンダリングする。

カリングなどの全面・背面の描画周りには特に触れる必要がなかった。
renderPassなど使うときのような`renderer.autoClear = false;`も不要。
あとは適当にラインを置いて加算合成しつつ回したものが最初に貼った画像になります。
 

# 描画結果

![スクリーンショット 2017-05-20 3.32.58.png](https://qiita-image-store.s3.amazonaws.com/0/45247/bcd6e8d8-ff7d-0867-fd00-e004d78305a7.png)

最小構成コード（js)
https://gist.github.com/nanonum/99fa67c6bef13a8d60fc55bd82e4c883

# メモ

processingのだいぶ古い本で当たり前のように書いてあった気がするテクニックのため、検索ワードが完全に間違っているだけでこれをやるためのクラスが普通に用意されている可能性も捨てきれていない。