OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで実装する簡単なHTTPクライアント

#概要
Pythonの練習がてら作った簡単なHTTPクライアント

#環境
Python 3.4.3

#使い方
コマンドがpython3になってる人は適宜読み替えてください

```bash
$python http1.0.py 'ipアドレス' '返ってきたhtmlを保存するファイル名'
```

#補足
ヘッダーの読み飛ばしを記述するのが面倒だったので、とりあえず全部読み込んであとから改行が2連続の部分を前から検索してスライスで切り落としました。
例外はとりあえず全部キャッチするスタイルでやってます。


#ソースコード

```http1.0.py
import socket
import sys
import traceback

def main():
    #Set max buffer size
    max_size = 8192

    argv = sys.argv
    argc = len(argv)

    #Check commandline parameter
    if(argc != 3):
        sys.stderr.write('Usage: python http1.0.py [ADDRESS] [FILE]\nor\n')
        sys.stderr.write('Usage: python3 http1.0.py [ADDRESS] [FILE]\n')
        exit()

    address = (argv[1], 80)
    filename = argv[2]

    try:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #Create socket
        client.connect(address)    #Connect
        client.sendall(b'GET / HTTP/1.0\r\n\r\n')    #Send GET command
        data = client.recv(max_size).decode('utf-8')    #Receive data and decode
        client.close()  #Close

        #Cut header
        index = data.find('\r\n\r\n')
        data = data[index:]

        #Write HTML file
        fout = open(filename, 'w')
        fout.write(data)
        fout.close()

    except:
        sys.stderr.write(traceback.format_exc())
        exit()


if __name__ == '__main__':
	main()

```
(自分メモ)GNS3 ospf設定 ルータ間

# GNS3 ospf設定 ルータ間

■Aルータ

conf t
interface fastEthernet 0/0
ip address 110.2.3.2 255.255.255.0
no shutdown
router ospf 1
router-id 110.20.1.1
network 110.2.3.0 255.255.255.0 area 0

上記入力後、show runで設定内容を確認する。

■Bルータ

conf t
interface fastEthernet 0/0
ip address 110.2.3.1 255.255.255.0
no shutdown
router ospf 1
network 110.2.3.0 255.255.255.0 area 0

上記入力後、show runで設定内容を確認する。

■OSPF確認方法
show ip ospf neighbor 
か
show ip route

結果が出ます。
■R1
R1#show ip ospf neighbor 

Neighbor ID     Pri   State           Dead Time   Address         Interface
110.2.3.1         1   FULL/BDR        00:00:39    110.2.3.1       FastEthernet0/0

■R2
R2#show ip ospf neighbor 

Neighbor ID     Pri   State           Dead Time   Address         Interface
110.20.1.1        1   FULL/DR         00:00:35    110.2.3.2       FastEthernet0/0
pythonで日付を変換したり計算したり



■文字列から日付
```python
date = datetime.datetime.strptime('2017-02-02', '%Y-%m-%d')
```
■日付から文字列
```python
date.strftime('%Y-%m-%d')
```
下記のように、特定の日付を指定することも可能。
「timedelta」で日付の加減算ができるが、「days=1」のように日単位でしか計算できないので、下記を応用すれば色々計算できる。
（野良パッケージ使えばもっと早いけど）
```python
date.strftime('%Y-%m-%01')
```
【读书笔记】《C# in Depth》～2

你们知道我为何喜欢Python，Ruby这些动态语言么？因为他们去代码之糟粕，仅取其精华。
繁琐的形式被生成器，Lambda表达式，列表推导式等特性所替代。

回到C#，C#1呢可以看作是Java语言的升级版，他们的相似之处十分明显，但是C#还包含一些额外的特性：属性，委托，事件，foreach循环，using语句，显示方法重载，操作符重载，自定义类型等。
当我第一次使用C#1时，就明显比Java要更进一步。:rainbow:

别墨迹了，废话少说点吧，直接上Hello World的电子商务版本：

C#1版本的代码：

```csharp:Product.cs
using System.Collections;
public class Product
{
  string name;
  public string Name {get{return name;}}
  
  decimal price;
  public decimal Price {get{return price;}}
  
  public Product(string name, decimal price)
  {
    this.name = name;
    this.price = price;
  }
  
  public static ArrayList GetSampleProducts()
  {
    ArrayList list = new ArrayList();
    list.Add(new Product("West Side Story",9.99m));
    list.Add(new Product("Assassins",14.99m));
    list.Add(new Product("Frogs",13.99m));
    list.Add(new Product("Sweeney Todd",10.99m));
    return list;
  }

  public override string ToString()
  {
    return string.Format("{0}:{1}", name, price);
  }
}
```

C#2 C#3 我就略去了哈
直接看C#4的进化后的代码吧：

```csharp:Product.cs
using System.Collections;
public class Product
{
  readonly string name;
  public string Name {get{return name;}}
  
  readonly decimal price;
  public decimal Price {get{return price;}}
  
  public Product(string name, decimal price)
  {
    this.name = name;
    this.price = price;
  }
  
  public static ArrayList GetSampleProducts()
  {
    return new List<Product>{
       new Product(name:"West Side Story", price: 9.99m),
       new Product(name:"Assassins", price: 14.99m),
       new Product(name:"Frogs", price: 13.99m),
       new Product(name:"Sweeney Todd", price: 10.99m),
    };
  }

  public override string ToString()
  {
    return string.Format("{0}:{1}", name, price);
  }
}
```

C#2加入了泛型
C#4允许我们在调用构造函数时指定实参的名称
SonarQubeをdocker上で動かし、ローカルファイルを静的解析する For Mac




##dockerコンテナ作成

```bash
docker pull sonarqube:latest

#今回は起動テストまでなのでオプション --rm 付けました
docker run -d  --rm --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube
```


###コンソールにアクセス
http://localhost:9000/
ログインアカウントとパスワードは admin / admin


##プロジェクトを作成する
###Administaration >　Project > Management 押下
![スクリーンショット 2017-04-19 13.42.03.png](https://qiita-image-store.s3.amazonaws.com/0/169851/fa94206a-ca66-1770-d8f9-82406fac8699.png "スクリーンショット 2017-04-19 13.42.03.png")




###Create Project 押下
![スクリーンショット 2017-04-19 11.46.30.png](https://qiita-image-store.s3.amazonaws.com/0/169851/65550aa6-6dd3-a9d5-8afd-66c76e1b5120.png "スクリーンショット 2017-04-19 11.46.30.png")


###プロジェクトの設定
今回はサンプルなので下記で設定
Name : test
Key  : test
![スクリーンショット 2017-04-19 11.47.47.png](https://qiita-image-store.s3.amazonaws.com/0/169851/79644b19-c619-007c-3f06-06b5021a9dab.png "スクリーンショット 2017-04-19 11.47.47.png")




##sonarscanerのインストール
クライアントのファイルを解析するため、ローカルPCにsonarscanerのインストールを行う。

下記にアクセス
https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner

Mac OS X 64 bit　リンクからzipファイルをダウンロードし、解凍する


properties の設定
/path/to/解凍ディレクトリ/conf/sonar-scanner.properties

```
sonar.projectName=test
sonar.projectKey=test:test
sonar.sources=/path/to/ローカルの解析対象ディレクトリ
sonar.exclusions=除外対象
```


##解析実行

```bash
/path/to/解凍ディレクトリ/bin/sonar-scanner
```
あるGameObjectから他のGameObject内の変数を読もうとしてハマった話

#はじめに
タイトルに書いたようにドハマりしました・・・。
気づけばそりゃそうだろと思うようなことなのですが・・(´・ω・`)

#ハマった点
オブジェクト(OBJ_A)とオブジェクト(OBJ_B)があるとします。また、OBJ_AとOBJ_Bはどちらもprefab化しています。(便宜上、OBJ_AのprefabをOBJ_A[pre]のように表現します。)
OBJ_AとOBJ_Bにはそれぞれ以下の内容のスクリプト(A.cs、B.cs)がアタッチされています。

```C#:A.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class A : MonoBehaviour {

	public GameObject bObj;
	private B b;

	// Use this for initialization
	void Start () {
		b = bObj.GetComponent<B> ();
	}
	
	// Update is called once per frame
	void Update () {
		Debug.Log ("A:" + b.num);
	}
}

```


```C#:B.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class B : MonoBehaviour {

	public int num = 0;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		num++;
		Debug.Log ("B:" + num);
	}
}

```

見てわかるように、updateされるたびにBスクリプト内のnumがインクリメントされ、numの値をAとBのスクリプト内でコンソールに出力しています。
bObjにOBJ_Bを入れるために、OBJ_AをInspectorに表示させると以下のようになります。

![スクリーンショット 2017-04-18 17.47.34.png](https://qiita-image-store.s3.amazonaws.com/0/150412/b18526da-64c1-eaf6-ff6e-e58d1ca9bf34.png)

今からここにOBJ_Bを入れるのですが、私は考えなしに(いつものように)OBJ_B[pre]の方をいれて以下のような出力になりました。

![スクリーンショット 2017-04-18 17.51.33.png](https://qiita-image-store.s3.amazonaws.com/0/150412/d1b2b78c-51e5-0344-de20-cbe125a5e3ae.png)

そしてこの出力を見て「！？」となってしまいました。

#原因
OBJ_B[pre]を入れたということが原因です。
OBJ_B[pre]の内部を見に行ったところでUpdate関数でインクリメントされているnumはそこにはいません。```num = 0```が待っているだけです。Update関数が実行されるのはゲーム内で有効なオブジェクトである必要があるからです。

#解決法
もう分かるかと思いますが、HierarchyにあるOBJ_Bの方を入れる必要があったわけです。
以下がその時の出力結果です。

![スクリーンショット 2017-04-18 18.33.03.png](https://qiita-image-store.s3.amazonaws.com/0/150412/7b2ac2b2-c604-f7b1-3bdc-5284c848df49.png)

#おわり
何言ってんだよ当たり前だろ。って言われるような内容ですが、ハマっていた当時は原因不明で「？？」って感じでした。Instantiateに使うオブジェクトとして考えなしにとりあえずprefabを設定していたツケがきたんですね(´・ω・`)
説明や語句の使用で間違っている箇所があれば指摘をお願いします。。
applet起動時の警告ダイアログで「次回から表示しない」のチェックが効かない

###前提・実現したいこと
applet起動時の警告ダイアログで「次回から表示しない」のチェックボックスが表示されるが、チェックを入れて実行しても、次回表示時に同じ警告ダイアログが表示されてしまいます。
チェックを入れて実行時に次回から警告ダイアログが表示されないようにしたいと考えております。

なお、警告ダイアログ自体を表示しない方法でも良いのですが、これまで調査したところ、現在最新のJDK(1.8.0_121)ではできないと認識しております。
もし、ダイアログ自体を表示しない方法をご存知でしたら、そちらもご教示いただけると幸いです。

何卒宜しくお願いいたします。

###発生している問題・エラーメッセージ
現在構築のjnlpによるappletを起動すると添付画像の警告ダイアログが表示されます。

![jnlp警告ダイアログ.png](https://qiita-image-store.s3.amazonaws.com/0/176766/d584d381-f28c-3276-4704-deb948cc7312.png)


このダイアログ赤枠の「上記の発行者と場所からのアプリケーションについては、次回から表示しない(D)」
のチェックボックスにチェックを入れ、「実行」ボタンで正常に起動するのですが、再度同じappletを起動しても同じダイアログが毎回表示され困っております。

このダイアログ表示とするため以下の作業は正しくできている認識です。
 ・信頼できる認証局の有効な証明書発行
 ・ファイルマニフェストの属性権限明記


###試したこと
以下などを試しましたが、警告ダイアログの非表示並びに、チェックボックスが有効に機能することはありませんでした。

■Javaコントロール・パネルでの試行
 ●「セキュリティ」タブ
  ・「例外サイト・リスト」に該当ＵＲＬ追加

 ●「詳細」タブ
  ・「混合コード（サンドボックス内実行vs.信頼済）セキュリティ検証」を「有効-警告を表示せずに、保護をかけて実行する」にチェック
  ・「署名付きコード証明書実行チェックを実行」を
    「チェックしない」


###補足情報(言語/FW/ツール等のバージョンなど)
・Java 1.8.0_121（サーバ・クライアント共に）
・acm4chee-2.18.1
・JBoss4.2.3GA
・weasis
lumenでログのローテーションをする

#lumenでログのローテーションをする

ログの出力はMonologを使っているので、下記のようにすると、
日付ごとにlogが出力されるようになり、ログファイル作成時に古いログファイルが削除されるようになります。

```bootstrap/app.php

//こいつを追加
$app->configureMonologUsing(function (Monolog\Logger $monoLog) {

    $handlers[] = (
    new \Monolog\Handler\RotatingFileHandler(storage_path("logs/lumen.log"), 10) # ← 2番目の引数に残したいファイルの数
    )->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true));

    $monoLog->setHandlers($handlers);

    return $monoLog;
});


```

例えば下記のようなログファイルがすでに作成されていて

```
lumen-2017-04-10.log
lumen-2017-04-13.log
lumen-2017-04-16.log
```

`new RotatingFileHandler(storage_path("logs/lumen.log"), 2)`とした場合は

```
lumen-2017-04-16.log
lumen-2017-04-18.log
```

みたいな感じになる
FirebaseのBigQueryを使ってみた

Firebaseが登場したので、Google Analyticsから Firebase Analyticsに移行しました。

使い勝手が結構変わりますが、有料プランに入って心置きなく使い倒せるのはFirebaseの方です。
Analyticsの方に入れたデータは勝手にどんどんBigQuery内に溜め込まれており、クエリを発行して欲しいデータを集めることができるようになります。

# 始め方

Firebaseコンソールから対象のプロジェクトを開き、「Analytics」→「イベント」から画面の下部に行くと
「BigQueryで生のデータを参照」というボタンがあるのでクリック

こんな感じの画面になります

![スクリーンショット 2017-04-18 18.05.22.png](https://qiita-image-store.s3.amazonaws.com/0/98954/b29124f0-57ca-8794-304b-4718996ecf57.png)


はじめはちんぷんかんぷだと思います。（データベースを知らない人はまずそちらの勉強からしないとこの記事は読んでもわからないでしょう…）


## 見方

画面右下エリアの「Table Details」というところに注目。
すぐ横にテーブル名が選択できるようになっています。
app_events_YYYYMMDD という名前になっているものが、Analyticsイベントで送信したデータが丸っと入っています。ユーザ情報や位置情報、イベント内容など大変多くの情報が入っているので、欲しいものやユーザ紐付けなどは大概できるようになっているはずです。

### スキーム

「Scheme」は、テーブルのスキームが書いてあります。と言ってこれだけじゃよくわからないので、こちらのドキュメントがわかりやすいです
https://support.google.com/firebase/answer/7029846?hl=ja

大まかに言うと、ユーザ情報の入った「user_dim」と、イベント情報が入った「event_dim」に分かれています。
データ形式について、「String」「Integer」「Float」は問題ないと思います。
「Record」というのは、まあハッシュというか構造体のようなもの。内部にさらにStringやInteger,Floatなどの構造を持っています。
例えば user_dim.device_info というカラムはRecord型ですが、その中に device_category や、mobile_brand_name といったString型のカラムが存在しています。

SQLのSELECT節に指定するのは、String,Integer,Floatのようなプリミティブな型にする必要があります。逆にRecord型を指定したり、「*」で指定することはできません。
クエリ実行時に「プリミティブな型を指定しなさい」というようなエラーが英語ででます。

### プレビュー

「Preview」ボタンを押すと、テーブル内のレコードがいくつか表示されます。


## クエリを書く

右上のエリアにクエリを記述します。
難しいことはないですが、知っておくと便利なことをいくつかだけ

### SELECT節

まず、先述のように、SELECT節に「*」が使えません。
また、検索結果が膨大になる時は、実行前に警告が出ます。クラウド死しないよう気をつけましょう。


### FROM節

テーブル名にハイフンが含まれる場合、[]（角カッコ）で囲みます。
テーブル名はバケット名やプロジェクト名を含んでおり、ハイフンが入ってると思うので、角カッコ必須と思っていいでしょう。

テーブルが日付ごとに分かれていますので、複数の日時から検索したい時は、FROM節に以下のように記述します

```
  TABLE_DATE_RANGE([backet-name:project_name.app_events_], TIMESTAMP('2017-03-29'), TIMESTAMP('2017-04-18'))

```
こうすると、
backet-name:project_name.app_events_20170318 から
backet-name:project_name.app_events_20170418　までのテーブルから検索してくれます。
くれぐれもクラウド死注意。

### WHERE節

たいていのことはできます（大雑把）。
念のため、RealtimeDatabaseはNoSQLなのであんまり大したWHERE指定ができませんが、BigQueryはそんなことないのでご安心を

とにかくLIMIT句は必ずつけておくのがいいんじゃないかな。

あとはドキュメントにたくさん日本語で書いてあります。
https://cloud.google.com/bigquery/query-reference#from


# その他

user_dim.user_idは、アプリからAnalyticsを投げる前に指定したものです。

```
    [FIRAnalytics setUserID:userId];
```

このuserIdは、Firebase Authenticationで発行されたIDと同じものを指定しておくのがマストでしょう。
https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.html#setUserId(java.lang.String)


その他参考
http://qiita.com/taji-taji/items/760e242828dd58238dac
http://tiro105.hateblo.jp/entry/2016/12/23/234113
MySQL 5.7でmysqldが起動しない件

MySQL5.5から5.7に以降した時、playbookがコケてmysqlが立ち上がらなくなったので調査しました。


```
oppai@test:~$ sudo service mysql start
.................................................................................................................................................................................... * MySQL Community Server 5.7.18 did not start. Please check logs for more details.
oppai@test:~$ sudo mysqld_safe
2017-04-18T09:08:20.732801Z mysqld_safe Logging to '/var/log/mysql.err'.
2017-04-18T09:08:20.748330Z mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
2017-04-18T09:08:20.905812Z mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
oppai@test:~$
```

straceで見てるとmysql.errの書き込みで怒られてるのを発見。

```
open("/var/log/mysql.err", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EACCES (Permission denied)
open("/var/log/mysql.err", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EACCES (Permission denied)
open("/var/log/mysql.err", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EACCES (Permission denied)
```

でも、権限はあってそう、なぜ?

```
oppai@test:~$ ll /var/log/mysql.err
-rw-r----- 1 mysql mysql 1590 Apr 18 09:03 /var/log/mysql.err
```


MySQL５.7のドキュメントにちゃんと書いてました。どうやら、MySQL5.7から書込み可能なディレクトリにerrorログを入れないといけないようです。apt等で入れたときのデフォルトでは `log-error=/var/log/mysql.err`　になってますが、 `log-error=/var/log/mysql/mysql.err` にすればOKでした。


> https://dev.mysql.com/doc/refman/5.7/en/error-log.html
> It is common for Yum or APT package installations to configure an error log location under /var/log with an entry like log-error=/var/log/mysqld.log in a server configuration file. Removing the file name from the entry causes the default log file to be used, which is written to the data directory.
【读书笔记】《C# in Depth》～1

世界上有两类钢琴家。
1）弹钢琴并不是他们喜欢，而是父母强迫其上钢琴课，被逼的。
2）另一种是他们喜欢音乐，想创作音乐，没有被强迫，反而陶醉其中，时常忘记什么时候要停下来。

C# MVP的大神-Jon Skeet很明显是第二种钢琴家。:zap:

C# 是一种极为实用和快速发展的语言，通过添加查询能力，更丰富性的类型推断，精简的匿名函数语法等等，一种全新风格的编程语言已经出现在我的们的面前。与此同时，它代表的仍是一种静态类型的，面向组件的开发方式，C#取得成功的立足之本没有改变。
:heart_eyes:

我期待我能够看完这本书后能“谱写”出优秀的乐章。争取近几年内参与一次C#的系统设计，核心部分的开发。:fist:
php-timecopで時間を仮想的に変化させる


## 環境
- Docker
- Amazon Linux
- PHP 5.6.x

## インストール
```bash
$ git clone https://github.com/hnw/php-timecop.git
$ cd php-timecop
$ phpize
$ ./configure
$ make
$ make install
```

`gcc`とか`php56-devel`が入ってなかったので、`phpize`でつまづきました。

## php.iniに追記
`php -i | grep php.ini`でphp.iniの場所を調べて下記を追記。

```
extension=timecop.so
```

## 試してみる
```php
<?php
date_default_timezone_set("Asia/Tokyo");
echo date("Y-m-d H:i:s")."\n";

echo "\ntimecop_freeze\n";
timecop_freeze(new DateTime("2017-03-31 10:00:00"));
echo date('Y-m-d H:i:s'). "\n";
```

実行結果

```
2017-04-18 17:31:55

timecop_freeze
2017-03-31 10:00:00
```

## 使えそうな関数
|関数名|機能|
|:--|:--|
| timecop_freeze |PHPの現在時刻を変更する（時刻不変）|
| timecop_travel |PHPの現在時刻を変更する（時間は変わっていく）|
| timecop_return |PHPの現在時刻を元に戻す|

## 参考
- https://github.com/hnw/php-timecop
- http://d.hatena.ne.jp/ts_asano/20130316/1363430516
なんかしてるっぽい出力をするスクリプト

仕事に疲れてぼーっとしたいけどサボってるって思われたくないときに、作業中かな？と思われるようなスクリプトを書きました。
必要なときにカスタマイズなどして使ってください。

すでにお使いのものがありましたら教えてください。

追記：[なんかインストールしてるっぽいスクリプト](http://qiita.com/yushimizu/items/5cbc1b9c940cc4a9f054)も作りました。

Linux版

```bash:ProcessSomething.sh
#!/bin/bash
i=0
while :
do
    i=`expr $i + 1`
    echo "Now Processing... line :${i}"
    sleepTime=`expr $RANDOM % 3`
    sleep "${sleepTime}s"
done
```

Windows版

```powershell:ProcessSomething.ps1
$i = 0
while($True){
    $i++
    Write-Host "Now Processing... "$i"行目まで処理しました。"
    Start-Sleep -m (Get-Random 1000)
}
```
メモ：iOSのプロビジョニングプロファイル

資料を片付けていたら、初代 iPad が出て間もない頃に、作ったこんな資料が出てきました。証明書とかプロビジョニングプロファイルとか実機にインストールする為にどうすれば良いかの模式図と、どこがどうつながっているのかを、人に説明するために、イラレでがんば作ったものです。元データは喪失してしまった可能性が高いですが、印刷してあったものを見つけてスキャンしたので、記録としてシェアしておきます。

<img width="612" alt="IMG.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/b90b4a29-2669-9373-d01f-95e729821f9f.png">
YAML.load を YAML.safe_load に書き換えると Psych::BadAlias エラーが発生する

# 問題

[RSpec のコードで Rubocop の "Block has too many lines." という警告を無視したい](http://qiita.com/QUANON/items/65a420e35af455aad74c) に引き続き、Rubocop のバージョン更新でひっかかったこと 2 つ目です。

Rubocop を実行すると Security/YAMLLoad という cop に怒られました :cop_tone1:

```
Prefer using YAML.safe_load over YAML.load.
```

YAML.load にはセキュリティ上の問題があるため、YAML.safe_load に書き換えろという内容です ([参考 PR](https://github.com/bbatsov/rubocop/pull/3821)) 。

Rubocop の自動修正で [YAML.load](https://ruby-doc.org/stdlib-2.4.0/libdoc/psych/rdoc/Psych.html#method-c-load) を [YAML.safe_load](https://ruby-doc.org/stdlib-2.4.0/libdoc/psych/rdoc/Psych.html#method-c-safe_load) に修正したのですが、修正したコードを実行すると次のエラーが発生しました。

```ruby
file = Rails.root.join('config/database.yml').read

YAML.safe_load(file)
#=> Psych::BadAlias: Unknown alias: default
```

これは Rails の `config/database.yml` を読み込むコードなのですが、YAML ファイル内で `&default` という名前の [エイリアス](http://magazine.rubyist.net/?0009-YAML#l10) を使っているのが原因のようです。ただ、エイリアス自体は YAML の機能ですし、YAML ファイルの文法も間違っていません。

# 解決策

```ruby
YAML.safe_load(file, [], [], true)
#=> Hash object
```

のように、エイリアス機能を利用するには YAML.safe_load の第 4 引数に `true` を渡す必要がありました。詳しくは [YAML.safe_load のドキュメント](https://ruby-doc.org/stdlib-2.4.0/libdoc/psych/rdoc/Psych.html#method-c-safe_load) を参照してください。
Linuxコマンドで空きポートを探す

適当な空きポートをlistenしたい場面があったのですが、「空きポート 探す」みたいなキーワードで検索しても「あるポートが空いているかどうか（そのポート番号についてファイアウォールでブロックされていないかどうか）を調べる」や「あるポートを誰かがlistenしているかどうかを調べる」という例はすぐに見つかっても、「誰も使っていないポートをランダムに1つ抽出する」という例はパッと出てきませんでした。なので書き留めておきます。

* `/proc/sys/net/ipv4/ip_local_port_range`でエフェメラルポートの開始番号と終了番号が得られる。
*  `shuf -i [start]-[end] -n 1`で与えられた範囲の数字の中から1つをランダムに選べる。
*  `netstat -a -n | egrep ':[port] .+LISTEN'`に成功した場合は誰かがそのポートをlistenしていて、失敗した場合は誰もそのポートをlistenしていない（ポートが空いている）。

という所から、空いているポートをランダムに1つ選ぶシェルスクリプトはこんな感じに書けました。

~~~bash:find_free_port.sh
#!/bin/bash
available_port_range="$(cat /proc/sys/net/ipv4/ip_local_port_range | cut -f 1,2 --output-delimiter='-')"
while true
do
  port="$(shuf -i $available_port_range -n 1)"
  netstat -a -n |
    egrep ":$port .+LISTEN" 1>/dev/null 2>&1 ||
    break
done
echo $port
~~~

`nc`で一時的なサーバーを立てるとかそういう場面で使えるんじゃないでしょうか。
Macで英数字を全角で入力しちゃった時に、わざわざ消さなくて良いのに！


Macのスペースキーの両サイドの「英数キー」と「かなキー」、便利だよね！
初めてMacに触れたときはものすごい衝撃だった

「トグルじゃあない！！！もう二度と半角が入れたいのに全角で書き始めなくて済む！！！」

と思ったのを思い出す

けど、まぁ間違える事はあるよね


そんな時に**全角で入力した物をdelete連打で消して、英数に切り替えてから入力し直す**
とする人をとてもよく見るんだけど、**それわざわざ消さなくても良いんだよ！**

**全角でも、変換が確定する前なら「英数キー」を2連打するとカッチリと半角英数に変換されるよ！**

## 例
面倒なのでアニメーションは作ってないけど、すぐ試せるからやってみて

ターミナルで`git`って打ったつもりが全角だったー！
<img width="355" alt="スクリーンショット 2017-04-18 15.38.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/29d1ff9b-3377-9592-5062-7733be486f90.png">

けど、落ち着いて「英数キー」「英数キー」を押せば問題無し！
<img width="355" alt="スクリーンショット 2017-04-18 15.38.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/567d8ea2-7a15-a569-871c-d9fd8855ba5d.png">



勢いでスペースまで押してしまっていても...
<img width="355" alt="スクリーンショット 2017-04-18 15.38.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/1ecfc672-0e60-7514-bb39-ae4bac8d2017.png">

大丈夫！
<img width="355" alt="スクリーンショット 2017-04-18 15.38.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/567d8ea2-7a15-a569-871c-d9fd8855ba5d.png">



エンターキーを押してしまっても...
<img width="355" alt="スクリーンショット 2017-04-18 15.40.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/b2109f05-9580-db05-3d38-2de134e78969.png">

カーソルがそこにあればまだ大丈夫！
<img width="355" alt="スクリーンショット 2017-04-18 15.40.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/6da74ca5-7ff4-3a5c-c3dc-af8f68eaffa0.png">



Issue番号も...
<img width="355" alt="スクリーンショット 2017-04-18 15.40.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/9cbf39cc-61ab-dbfa-7722-3e9cfd5faf1e.png">

大丈夫！
<img width="355" alt="スクリーンショット 2017-04-18 15.40.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/53384365-c4e2-19b4-c97f-510025c6fee0.png">



コード書いちゃっても...
<img width="355" alt="スクリーンショット 2017-04-18 15.40.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/6f5cd303-2edd-5764-95ec-fcaf8421503d.png">

問題無し！
<img width="355" alt="スクリーンショット 2017-04-18 15.40.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/113398/452db76f-c366-91f5-b20e-9e0627bbea15.png">

そろそろしつこいかなw


何で知ったか忘れたけど、これとても便利！
あと、これ思ってる以上に気持ちが良いので、オススメ！
Gruntで結合したJSファイルに自動でタイムスタンプを付けてキャッシュを防止

## 結合したスクリプトファイルがブラウザキャッシュされる？
Gruntで複数のJavaScriptファイルを結合して、scripts.js とかにすることがよくある。
その場合、ファイルを更新してもブラウザキャッシュを読みに行ってしまうことがある。
ブラウザキャッシュを消せば良いが、ユーザーに毎回ブラウザキャッシュを消させるのは酷すぎる。

## 「grunt-cache-breaker」プラグインを使えば良い
そんな時に、scriptタグのsrc属性で読み込むURLにクエリパラメータで

`scripts.js?ts=34534534534` 

のように文字列（例えばタイムスタンプ）をつけ、URLを変えるとブラウザが再度読みに行ってくれる。

この文字列は、バージョンアップのタイミングで更新しなくてはならないが、
それを自動更新してくれるのが、「grunt-cache-breaker」プラグイン。

# インストール

https://github.com/shakyShane/grunt-cache-breaker　参照

# もっとも簡単な使い方
Gruntfile.jsに以下の記述を追加
`  grunt.loadNpmTasks('grunt-cache-breaker');`

grunt.initConfigの配列に以下を追加
ここでは、 files.src で指定した index.html の中の 
scripts/scripts.js　および　scripts/vendor.js にタイムスタンプを付与している。

```js:Gruntfile.js
    cachebreaker: {
      dev: {
          options: {
              match: ['scripts/scripts.js', 'scripts/vendor.js'],
          },
          files: {
              src: ['<%= yeoman.dist %>/index.html']
          }
      }
    }
```

実行したいタスクに、cachebreaker を追加する。
例えば、build タスクに追加するなら

```js:Gruntfile.js
  grunt.registerTask('build', [
    '…省略',
    'cachebreaker' // ←追加
  ]);
```

以上の設定を追加して、

```bash
grunt build
```

すれば index.html 内のscriptタグが以下のように置き換えられる。

```html
<script src="scripts/vendor.js?rel=1492500899044"></script>
<script src="scripts/scripts.js?rel=1492500899043"></script>
```
jq で エポックミリ秒を変換したい

ｊｑ 便利だよね。何でも jq 使っちゃいます。
エポックミリ秒を jq だけで可視化出来たら素敵だなと思って調べました。

ですが、 jq では日付のパースを ISO8601 準拠のエポック秒までしか出来ません。
仕方ないので、1000 で割りましょう。

```shell-session
$ echo '1492377216630' | jq '(./1000|todate)' 
"2017-04-16T21:13:36Z"
```

1000割る時にあ、文字列だぞって怒られたら `number` に変換しましょう。

```shell-session
$ echo '1492377216630' | jq '(.|tonumber|./1000|todate)'
```

UTC → JST変換したい時の機能がないので、 計算する

```shell-session
$ echo '1492377216630' | jq '(.|tonumber|./1000|.+32400|todate)'
"2017-04-17T06:13:36Z"
```



jq 最高
mastodonはインフラエンジニアの見せ所

わたしもインフラエンジニアのはしくれとして立ててみました。
~~https://mstdn.high-low.ml/~~
5/29追記： AWS料金がかさむため、↑のインスタンスは閉鎖しました。
代わりに [https://co-mastdn.ga/ - 文具丼](https://co-mastdn.ga/)こちらを建てています。

2007年くらいにはTwitter APIやFacebook Developersに登録したりしていろいろなアプリを作ったりURLを公開して実験したものですが、ここ最近のSNSはハードルが高くなっていて、インフラのコード化や監視の充実にいそしんでいました。
満を持して登場したmastodonはそんなインフラ屋に光明を射すプロダクト＆サービスなんじゃないかと胸が熱くなる数日間でした。

やってみるといろいろと漏れていた知識もあったり、開発環境そろえるのもどうだったっけと思い出しながらでしたが、なんとかローンチできました。
まだまだメディアファイルのs3逃がしとかredisやsidekiqあたりのチューニングなど課題は見えてますが、ゆるく運用するなら勝てそうだという気持ちになり立ち上げに奮闘しました。

# 必要な知識

- クラウド(aws,GCP,Azure,さくらクラウド,etc) or VPSサービス（ConoHa,GMOクラウド,さくらVPS,etc） or PaaS(heroku,heteml,etc) or 自宅サーバ
- OSはUbuntu、またはそのあたりのLinux
- nginx
- メール認証（SES、GCP、SendGrid、Mailgun、SparkPost）
- Docker（必須ではない）
- Ruby on Rails
- ~~Haml~~
    - 必要じゃなかった（admin機能で全部対応可能）
- SSL（letsencrypt、AWSのELB）
- PostgreSQL（1コマンドしか打たないので知識としては必須ではない）
- SNSリテラシー
- 99%の根性

# インスタンスを建てる際に参考にした記事

[CentOS7でmastodonを建てる](http://qiita.com/motiakoron/items/1e5b0679f7283bfee70b)
[さくらのVPSで自分の Mastodon サーバを最速でつくる方法](http://qiita.com/hekki/items/c3f42c31632105389c79)
[CentOS 7 で ぱおーん](http://qiita.com/kozawappoi/items/a68f88bd64c87ee801d2)
[全力AWSでMastodonサーバー立てました chitose.moe](http://qiita.com/kawax/items/5307b58e549dd9cc3928)
[お一人様のMastodon](http://qiita.com/sawanoboly/items/c7d6b913fd5455fb0f36)

# ほかの連合とのつながり方
- アルファマストドニストなユーザにフォローを送りまくる
- 大手マストドンで宣伝しまくる
- https://instances.mastodon.xyz/ に登録する
- [日本 Mastodon インスタンス一覧](http://qiita.com/noraworld/items/ea853c6897326feda51f)に追加する

# 所感
- 連合は組むがユーザは増やしたくない
Redhat7に、システム共通のrbenv環境を作る

毎度おんなじことやっているので、手順を残しておきます。

ローカル環境でrbenvのインストールの方法と違い、どのユーザでログインしても、システム上のrbenvが使える状況を作ります。

# gitのインストール
```shell-session

$ sudo yum install git
```

# rbenvのインストール
```shell-session

$ git clone git://github.com/sstephenson/rbenv.git /usr/local/src/rbenv
$ sudo echo 'export RBENV_ROOT="/usr/local/src/rbenv"' >> /etc/profile.d/rbenv.sh
$ sudo echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile.d/rbenv.sh
$ sudo echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh
$ source /etc/profile.d/rbenv.sh
```

```shell-session

$ sudo git clone git://github.com/sstephenson/ruby-build.git /usr/local/src/rbenv/plugins/ruby-build
```

```shell-session

$ sudo yum install bzip2
$ sudo rbenv install 2.4.1

Last 10 log lines:
checking for ruby... false
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ruby-build.20170418104359.2588/ruby-2.4.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
```

今日も怒られてます。

```shell-session

$ sudo yum install gcc
$ sudo rbenv install 2.4.1
Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.
```

なんどでも、なんどでも

```shell-session

$ sudo yum insall openssl-devel
Downloading ruby-2.4.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2
Installing ruby-2.4.1...

BUILD FAILED (Red Hat Enterprise Linux Server 7.3 using ruby-build 20170405-2-g3b15693)

Inspect or clean up the working tree at /tmp/ruby-build.20170418105034.16372
Results logged to /tmp/ruby-build.20170418105034.16372.log

Last 10 log lines:
installing rdoc:              /usr/local/src/rbenv/versions/2.4.1/share/ri/2.4.0/system
installing capi-docs:         /usr/local/src/rbenv/versions/2.4.1/share/doc/ruby
The Ruby readline extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y readline-devel` to fetch missing dependencies.

Configure options used:
--prefix=/usr/local/src/rbenv/versions/2.4.1
LDFLAGS=-L/usr/local/src/rbenv/versions/2.4.1/lib
CPPFLAGS=-I/usr/local/src/rbenv/versions/2.4.1/include
```
もういっちょ！　

```shell-session

$ sudo yum install -y readline-devel

$ sudo rbenv install 2.4.1
```

成功！

# bundlerのインストール
```shell-session

# rbenv shell 2.4.1
# rbenv exec gem install bundler
```
今後、　rbenvでインストールしたrubyのバージョンごとに、上記のbundlerをインストールしておいてあげるとよいです。
RSpec のコードで Rubocop の "Block has too many lines." という警告を無視したい

# 概要

ある晴れた日のとある Rails プロジェクトでのできごと。[Rubocop](https://github.com/bbatsov/rubocop) のバージョンが少し古かったので、現在の最新版である `0.48.1` に更新しました。そして、rubocop コマンドを実行すると、[RSpec](https://github.com/rspec/rspec) のコードの多くで `Metrics/BlockLength: Block has too many lines.` という警告が表示されました。

```
$ bin/rubocop --display-cop-names

spec/models/user_spec.rb:1:1: C: Metrics/BlockLength: Block has too many lines. [35/25]
describe User, type: :model do ...
```

とはいえ、RSpec は専用の [DSL](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%9B%BA%E6%9C%89%E8%A8%80%E8%AA%9E) で記述する性質上、どうしても 1 つのブロックあたりの行数が増えてしまいます。そのため、行数を 25 行以下に書き換えるのは現実的ではありません。とはいえ、RSpec のコードで他の規約違反を無視したくはないので、Rubocop の監視対象から外すことはしたくありません。では、RSpec のコードだけ `Metrics/BlockLength` を無視するにはどうすればいいでしょうか。

# 方法

RSpec のコードで無視したい cop の名前が `Metrics/BlockLength` だったので、以下の記述を `.rubocop.yml` に追加しました。

```.rubocop.yml
Metrics/BlockLength:
  Exclude:
    - 'spec/**/*'
```

# 参考

* [<i class="fa fa-fw fa-github"></i> bbatsov/rubocop > Configuration > Including/Excluding files](https://github.com/bbatsov/rubocop/blob/master/manual/configuration.md#includingexcluding-files)
* [<i class="fa fa-fw fa-stack-overflow"></i> Rubocop 25 line block size and RSpec tests](http://stackoverflow.com/questions/40934345/rubocop-25-line-block-size-and-rspec-tests)
CentOS7をルータにしてXBOX-ONEをつないでみたメモ

某校の研究室にて、ネットで外部につなぐ時にブラウザによる認証が必要なのですが、機材として購入されていたXBOX-ONEが認証に阻まれネットに繋げずただの箱になっていました。そこで、近くにあったCentOSサーバ(NIC２枚差し)を間に挟んでネットにつながるようにしてみました。

絶対次やろうとしても忘れている自信があるのでメモを残しておきます。うろ覚えの部分もあるので、間違ってる部分もあるかも……

#NIC構成
外側 enp6s0 DHCP(クラスB)
内側 enp11s0 192.168.11.1/24

外側が学内ネットワークでDHCPでIPが割り振られます。ブラウザ認証を終えると無制限でネット接続ができます。
内側がXBOX用のネットワークです。内側に対するDHCPは、以前外側のネットワークに漏らして本来のDHCPサーバの邪魔をしてみんなIPが拾えなくなるという(ゝω・)ﾃﾍﾍﾟﾛな事件を起こしたことがあり、今回も自信がないので固定IPでやることにしました。

#ゾーン構成
外側 external
`firewall-cmd --permanent --zone=external --change-interface=enp6s0`

内側 trusted
`firewall-cmd --permanent --zone=trusted --change-interface=enp11s0`

#マスカレード設定
外側
`firewall-cmd --permanent --zone=external --add-masquerade`

内側
`firewall-cmd --permanent --zone=trusted --add-masquerade`

#ポート解放
外側(学校のFWがあるので学内は信用する。ルータの設定とは関係ない、研究室用)
`firewall-cmd --permanent --zone=external --add-port=0-65535/tcp`

#ipv4のforward設定
`echo 1 >/proc/sys/net/ipv4/ip_forward`

#転送許可フィルタ
`firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -o enp6s0 -j MASQUERADE`
`firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i enp11s0 -o enp6s0 -j ACCEPT`
`firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i enp6s0 -o enp11s0 -m state --state RELATED,ESTABLISHED -j ACCEPT`

---
これだけ設定してfirewallをreloadしたら、サーバの方の設定は終了。とりあえず認証を通しておきます。
`curl -d uid=<ユーザーID> -d pwd=<パスワード> http://認証cgiのアドレス`

後はつなぐ側。

#XBOX-ONEの設定
IP 192.168.11.2
MASK 255.255.255.0
DNS 8.8.8.8 / 8.8.4.4
GATEWAY 192.168.11.1

無事サインインができ、Edgeも動きましたo(≧▽≦)┌θ
MacのSlackアプリでアカウントを消されたチームを削除する


## tl;dr

- 設定ファイルを直接書き換えましょう

## 概要

MacのSlackアプリで、ログインしているチームを削除（ログアウト）したい場合、以下の2つの方法があります

- チームメニューの一番下の`Sign out of XXX`を選ぶ

![スクリーンショット 2017-04-18 16.02.24.png](https://qiita-image-store.s3.amazonaws.com/0/29459/5f92bac3-565c-555b-ba7b-b51dbfc06328.png "スクリーンショット 2017-04-18 16.02.24.png")

- チームアイコン右クリックから`Remove XXX`を選ぶ

![スクリーンショット 2017-04-18 16.03.10.png](https://qiita-image-store.s3.amazonaws.com/0/29459/8ea79468-0f92-0bbb-6a94-d452fa48fba5.png "スクリーンショット 2017-04-18 16.03.10.png")

しかし、後者の方はどうもバグ的な挙動でアプリを再起動するとチームが復活します。
なので、前者の方法を行えばいいのですが、チームからアカウントが削除されると前者のサインアウトメニューは出せなくなってしまいます。

## 対処方法

直接設定ファイルを書き換えるしか方法がなかったので、それを行います。
作業を始める前にSlackアプリを終了しておいてください。
**また、ファイルを編集する前にかならずバックアップを取っておいてください。**

Slackのアプリのデータは以下のフォルダに保管されています。

```
~/Library/Containers/com.tinyspeck.slackmacgap/Data/Library/Application Support/Slack/
```

その中の、`storage`フォルダ内に以下のような構成でログインしているチーム情報が保管されています。

- slack-appTeams: ログインしているチームのID、起動時に選択されるチームのID
- slack-teams: ログイン情報以外のデータ（自身のアカウントのID、テーマ、URL、アイコンなど）

この2ファイルから該当チームのデータを削除することで、ログインチーム一覧に表示されなくなります。

### チームIDの検索とslack-teamsからの削除

はじめに、`slack-teams`のファイルからチームデータの削除とチームIDのメモを行います。
このファイルはjsonで、以下のようなフォーマットで情報が保管されています。

```json
{
  "[TEAM-ID1]":{
    チームの情報
  },
  "[TEAM-ID2]":{
    チームの情報
  },
  "[TEAM-ID3]":{
    チームの情報
  }
  .
  .
}
```

チーム情報の中に`xxx.slack.com`という文字であったり、チーム名が記載されているので、検索し、チームIDをメモします。
チームIDは、各チーム情報のKeyとなっている他、`team_id`の値としても保管されています。`id`は個人のアカウントのIDなので注意です。
IDをメモしたら、このファイル内から該当チームの項目をごそっと削除します。
上の例の中からTEAM-ID2のものを削除するなら、

```diff
{
  "[TEAM-ID1]":{
    チームの情報
  },
-  "[TEAM-ID2]":{
-    チームの情報
-  },
  "[TEAM-ID3]":{
    チームの情報
  }
  .
  .
}
```

この部分を削除してください。

### slack-appTeamsからの削除

次に、`slack-appTeams`からもチームのIDを消します。
こちらのファイルの構造は以下のようになっています。

```json
{
  "selectedTeamId": "[TEAM-ID1]",
  "teamByIndex": [
  	"[TEAM-ID1]",
  	"[TEAM-ID2]",
  	"[TEAM-ID3]",
  	.
  	.
  ]
}
```

この中から、`teamByIndex`のリストの中にある該当チームの項を削除してください。
また、仮に`selectedTeamId`の方にも書かれていた場合は、他の適当なチームのIDに書き換えておいてください。

-

完了後、Slackを起動すると対象のチームが一覧から消えているはずです。
servo simple RPi

```servo_simple.py
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
servo_pin = 3
GPIO.setup(3, GPIO.OUT)
servo = GPIO.PWM(3, 50)

servo.start(0)

servo.ChangeDutyCycle(2.0)
time.sleep(2.0)
servo.ChangeDutyCycle(12.0)
time.sleep(2.0)
servo.ChangeDutyCycle(2.0)
time.sleep(1.0)
servo.ChangeDutyCycle(12.0)
time.sleep(2.0)

servo.stop()

GPIO.cleanup()
```

参考: http://rpi.science.uoit.ca/lab/servo/
PWMのコマンドの意味は

>
In the above case we have instantiated the PWM module for the pin number 12 with a frequency of 50Hz. That frequency was selected because the servo motor expect a pulse every 20ms (period), that means 50 pulses per second or Hertz. 

だそうです.
9スライスをPythonでしてみる

##9スライスとは
図形を拡大・縮小するときに、角のスタイルが設定されたものは歪曲して表示されてしまいます。9スライスでは、図形を9つの領域に分けることで元の形を保ったまま拡大・縮小ができます。
![9sliceDisc.png](https://qiita-image-store.s3.amazonaws.com/0/134076/6ec8e955-fed8-ef5f-c5f6-5fca0f080641.png)

##事前準備
9スライスに対応した画像を生成します。Romannurikさんが公開している[Android Asset Studio](https://romannurik.github.io/AndroidAssetStudio/)を利用します。トップ画面から Simple nine-patch generator を選択し、下のような感じで画像をつくります。

![スクリーンショット 2017-04-18 14.51.32.png](https://qiita-image-store.s3.amazonaws.com/0/134076/35992224-acd6-1f54-33b8-51040d07fe5e.png)



##必要なライブラリのインストール
pillowとnine-patchを導入します


```
pip install pillow
pip install ninepatch
```

##コード
上記で生成した9スライス画像を引数にしてNinepatchオブジェクトを生成します。render()メソッドで縦横のサイズを指定して画像を拡大します。


```python:nineSliceTest.py
from ninepatch import Ninepatch
from PIL import Image
bubble = Ninepatch("bubble.9.png")
scaledBubble = bubble.render(600,200)
scaledBubble.show()
```
元画像
![bubbleForBlog.png](https://qiita-image-store.s3.amazonaws.com/0/134076/8c4b58dd-59f0-258d-0126-41822680067a.png)


結果画像
![result.png](https://qiita-image-store.s3.amazonaws.com/0/134076/b5617f38-a2e8-b0e3-da19-a127e28bd9ad.png)
Rancher から GitLab Container Registry を使う

Rancher から GitLab Container Registry を使います。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/ffa7d1f2-bb19-957e-27af-08b6641a5340.png)

# 1. Container Registry を Rancher から登録する

## 1-1. 登録画面を表示

「インフラストラクチャー」から、「レジストリ」をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/323527e1-348b-eadb-aa5b-cfc9012e7174.png)

## 1-2. アカウントを登録
1. 「Custome」をクリック
2. 「アドレス」にRegistryのFQDNを入力
3. 「ユーザー名」にPullするレジストリーのユーザー名を入力
4. 「パスワード」に3のユーザーのパスワードを入力
5. 「作成をクリック」

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/d0810ee0-b081-d6f1-5092-b5845bd99ddb.png)

# 2. 使い方
通常のコンテナーデプロイと同じようにデプロイできます。

## 2-1. スタック追加
Rancherでは、「スタック」-->「ユーザー」とクリックして、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/02ab47af-125f-914c-3ac0-2661a81d13eb.png)

「スタックを追加」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/99b7e2c2-5844-d5e4-d50f-8e9be3256a01.png)

## 2-2. サービス追加
下記のように空のスタックができたら、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/9f69d5dc-bcbd-6b43-e82e-eadf4fca1573.png)

「サービスを追加」をクリックして、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/dc2647d1-76f7-e871-af49-19de8f2debd2.png)

「イメージを選択」のところに 1で登録したイメージのタグを入力します。

以上でデプロイできます。
俺のプレゼン用ショートカット

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E4%BF%BA%E3%81%AE%E3%83%97%E3%83%AC%E3%82%BC%E3%83%B3%E7%94%A8%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/)をご覧ください😀

プレゼンする際によく使用するMacのショートカット集です。
末尾に修飾キーの読み方も載せてます。

## ディスプレイ周り
### ミラーリング

`⌘` + `F1`

### Dock非表示

`⌥` + `⌘` + `d`

### アプリ切り替え

`⌘` + `tab`

### アプリ内ウィンドウ切り替え

`⌘` + `F1(+fn)`


## ブラウザ周り（Chrome）

### フルスクリーン

`⌃` + `⌘` + `f`

### ブックマークバーを隠す

`⇧` + `⌘` + `b`

## 備考：修飾キーの意味

- `⌘` : command
- `⌥` : option (alt)
- `⇧` : shift
- `⌃` : control
Python PyTorch install tips 

# このエラーにピンときたらPyTorch Forumsへ．．．

> import torchvision.transforms as transforms
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/hogehoge/anaconda3/envs/py36/lib/python3.6/site-packages/torchvision-0.1.8-py3.6.egg/torchvision/__init__.py", line 2, in <module>
  File "/home/hogehoge/anaconda3/envs/py36/lib/python3.6/site-packages/torchvision-0.1.8-py3.6.egg/torchvision/datasets/__init__.py", line 1, in <module>
  File "/home/hogehoge/anaconda3/envs/py36/lib/python3.6/site-packages/torchvision-0.1.8-py3.6.egg/torchvision/datasets/lsun.py", line 2, in <module>
  File "/home/hogehoge/anaconda3/envs/py36/lib/python3.6/site-packages/PIL/Image.py", line 56, in <module>
    from . import _imaging as core
ImportError: /home/hogehoge/anaconda3/envs/py36/lib/python3.6/site-packages/PIL/_imaging.cpython-36m-x86_64-linux-gnu.so: undefined symbol: PySlice_Unpack

とまあ，このエラーで長いこと苦しめられました．
私の環境は　
python 3.6 
conda install pytorch torchvision -c soumith
で作成．

解決法はpython 3.5 に変えること．以上

```bash
$ conda create -n py35 python=3.5
$ conda activate py35
(py35)$ conda install pytorch torchvision -c soumith
```

で，とりあえずうまく行きます．以上
Rails && MySQL >= 5.7 でERROR 1055 (42000)となる原因と対処3Way

# ActiveRecordで集計系Scopeを組んでいるときに、エラーに遭遇
```
ERROR 1055 - Expression #5 of SELEC list is not in GROUP BY clause and contains nonaggregated column '***' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
```

`sql_mode=only_full_group_by` とな

## SQLモードを調べる
```
mysql> select @@SESSION.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@SESSION.sql_mode                                                                                                                        |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
```
* ちなみにSQLモードとは、SQL実行時のルールのようなものです。
上にある `STRICT_TRANS_TABLES`はINSERT/UPDATE時の型チェックを厳しくして実行を中止したりします。

`ONLY_FULL_GROUP_BY`は、GROUP BYで集計するとき、SELECT句やORDER BY句で指定されるカラムがGROUP BY句に含まれていなければならないというルール。

**どうやら、MySQL5.7から”ONLY_FULL_GROUP_BY”は、デフォルトの設定となった模様**
> MySQL 5.7.5 and up implements detection of functional dependence. If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default),
> -- [MySQL5.7 Reference](https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html)

MySQLの場合、これ迄は同様の書き方でもエラーは出なかった。

## 設定変更で対応
ていうかそもそもORDER BY句自体が必要ないんですよね、集計関数だから。
どうやらModel側で default_scopeに `->{ order(id: :desc) }` が入る（プロジェクト設定の）ため、これを外せる（モデルなの）なら外せば良い。

できないのであれば、my.cnfの`ONLY_FULL_GROUP_BY`を外すという選択肢もありますが、
他のRDBMSでは元々SQLとしてエラーになる書き方であるからして、ここは残しておくべきかと思います。

## コード書き換えで対応
よって個別の対応策としては、Modelのscope側に

```rb
scope :active_count_by_category, lambda {|category|
  active
  .where(:category_id, category.id)
  .group(:category_id)
  .reorder(nil)
  .count(:id)
}
```
のように `.reorder(nil)`を差し込むことで対応する。
CentOS6にGit1.8をコンパイルインストールする方法

# 必要なライブラリを入れておく
sudo yum install make curl-devel gcc openssl-devel expat-devel  cpan
sudo yum install gettext  asciidoc xmlto

# ソースコードをgithubから取得
wget "https://github.com/git/git/tarball/v1.8.0-rc3" -O git.tar.gz
tar xvfz git.tar.gz
cd git-git-22ed067/

# インストール
# この例では/usr/loca/bin/にインストールされます
make prefix=/usr/local all doc
sudo make  prefix=/usr/local install install-doc install-html
Dockerのビルド時にプライベートリポジトリをpip install

##要件
Docker ビルド時に,
github, BitBucket 等のプライベートリポジトリのライブラリを pip install したい

##条件
プライベートリポジトリにアクセスするための鍵は $HOME/.ssh 以下にある

##案1
ローカルで wheel 作成して Dockerfile でコピー

```pip wheel djando```
(django はプライベートじゃないけども)

### 良い点
 - 鍵問題と Docker を切り離せる
 - イメージをビルドし直す際に wheel を使いまわせる

### 問題点
 - ライブラリのビルドをローカル環境で行うためコンテナ内の実行環境と合わない可能性がある

例1: Django を wheel で取得した場合
-> Django-1.8.1-py2.py3-none-any.whl
python2-3 互換性があり, OS 非依存(any) こちらの場合なら問題ないが, 

例2: MysqlClient を wheel で取得した場合
-> mysqlclient-1.3.10-cp27-cp27m-macosx_10_10_intel.whl
CPython2.7で、macosx10.10 用ビルド と実行環境が制限される.
Docker Container は linux カーネル上で動作するため動作に支障が出る可能性がある.

linux 上で取得と wheel 化を行えばよさそうだが, 手間がかかりすぎて本末転倒.

## 案2
イメージに鍵を埋め込む.
O'REILLY の Docker 本で「やるな」とある. セキュリティ的によろしくなさすぎるので却下.

## 案2-2
イメージに永続的に鍵が残らなければいいので, 鍵をコピーして pip install 後に鍵を削除すればいいのでは. で, 書いてみたのが

```Dockerfile.
COPY id_rsa /root/.ssh/
COPY id_rsa.pub /root/.ssh/
RUN chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub && \
    echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config
RUN pip install -r requirements.txt
RUN rm /root/.ssh/*
```
こんな感じ.
鍵ファイルのアクセス権限は 600 でないといけない (.ssh は 700).
また, HostKeyChecking は無効にしておかないとビルドではエラーになる.
pip install が終了したら認証情報はイメージから全て削除する.

### これでインストールできるけども
鍵ファイルは通常ローカルの $HOME/.ssh 以下にあり, Docker ビルドは Dockerfile のあるディレクトリとトップディレクトリとしてその内部にあるファイルしかアクセスできない.
そのため, 鍵ファイルをコピーして Dockerビルドでアクセスできる領域に持ってくる必要がある.
こちらも永続的置いておくのはあまりイケてないので, 一時的にコピーしてビルド後に削除するようなビルドスクリプトを書くのがいいと思う.
Docker のコマンドで完結しないが仕方のないこと...

## 案3 
プライベートリポジトリのライブラリだけ頑張って Docker の実行環境に合うように wheel 化して残りは普通にビルド内でインターネットから pip install する.

プライベートリポジトリ内ライブラリの数によるが, これでいい気がしてきた.
でも wheel のバージョン管理も必要になるのか...

##まとめ
個人開発環境として配布するなら 案2-2, 本番運用するなら案3 かなぁ...(しない)
Bashの変数展開

mongod の起動スクリプトに以下の記述があった。

```/etc/init.d/mongod
mongod=${MONGOD-/usr/bin/mongod}
```

空欄か未定義だと - 以降が展開される？
正式な仕様を探したら `man bash` の "Parameter Expansion" に以下の記載があった。

>       Omitting the colon results in a test  only  for  a  parameter  that  is
>       unset.

":" コロンが省略された場合、未定義の場合のみ ${parameter:-word} と同じ挙動になるようだ。
PlantUMLをAtomで使う in Windows7

大雑把な手順。詳細は下に。
1. Chocolateyをインストールする
2. Graphvizをインストールする
3. Atomにプラグインをインストールして設定
4. PlantUMLを使う

# 実行時の環境
Windows7 SP1 64bit
Atom 1.15.0

# Chocolateyをインストールする
[公式サイトのインストール手順](https://chocolatey.org/install)を見ればわかるけど、コマンドプロンプトでインストールできる。
管理者モードでコマンドプロンプトを立ち上げ、下記のコマンド(2017/04/18現在)を実行

```
@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
```

# Graphvizをインストールする
コマンドプロンプトで下記のコマンドを実行

```
choco install graphviz
```

JDKをインストールしてないなら下記のコマンドもついでに実行

```
choco install jdk
```

# Atomにプラグインをインストールして設定
下記の2つをインストール

```
language-plantuml
plantuml-viewer
```

インストール後、`plantuml-viwer`の設定を行う。
設定する項目は下記の2つ。
この設定前にプレビューを開いてたら、再度プレビューを開き直さないと設定が反映されないので注意。

|設定項目|設定内容|
|:--|:--|
|Charset|UTF-8|
|Graphviz Dot Executable|C:\Program Files (x86)\Graphviz2.38\bin\dot.exe|

# PlantUMLを使う
拡張子が.pumlや.puのファイルを開いてる時に`Ctrl + Alt + P`を押すとプレビューが出るので楽ちん。
どうやって書くかは下記のサイトなんかを参考に。

[AtomとPlantUMLでクラス図を書く方法](http://gabekore.org/atom-plantuml-class-diagram)
[PlantUML - シーケンス図](http://yohshiy.blog.fc2.com/blog-entry-153.html)
[Atom+PlantUMLで見た目もいい感じのシーケンス図を作成する](http://qiita.com/k_nakayama/items/77ca73753ebd049a66de)

# 参考
[Atom にPlantUML を導入](http://cartman0.hatenablog.com/entry/2016/02/24/144806)
[AtomとPlantUMLで爆速UMLモデリング](http://qiita.com/nakahashi/items/3d88655f055ca6a2617c)
脱jQueryのためにしたこと

この記事は加筆して「[脱jQueryのためにしたこと \- ICS MEDIA](https://ics.media/entry/17451)」に引っ越しました。

[![](https://ics.media/wp-content/uploads/2018/03/170418_beautifl_jquery_eyecatch2.png)](https://ics.media/entry/17451)

**64000PV、480いいねとフロントエンド界隈でご好評いただいた内容**です。ぜひご覧ください。

※Google検索で辿り着いた方にリンク切れとなっては申し訳ないので、元の記事を残しています。ご了承ください。
[android] TextToSpeechのleak対策

TextToSpeechをgoogleのサンプル通りに実装するとleakCanaryが頻繁にleakを検出するので、
色々試して、やっとleakが検出されなくなったのでメモ

## 方法
- onDestroy()でshutdown()
- ContextはActivityではなくApplicationContextを渡す。
- SoftReferenceを使用する。


## onDestroy()でshutdown()
これは普通にgoogleのサンプルでもやっている。
当然やらないとTextToSpeechがContextを保持したままなのでメモリリークする。

```
@Override
    protected void onDestroy() {
        if (textToSpeech != null) {
            textToSpeech.get().setOnUtteranceProgressListener(null);
            textToSpeech.get().shutdown();
        }
        textToSpeech = null;
    }
```

しかし、これだけではOutOfMemoryはほぼ起こらないですが、leakは度々検出されます。

## ContextはActivityではなくApplicationContextを渡す。

```
textToSpeechManager = new TextToSpeechManager(getApplicationContext(), this);
```
これでほぼOutOfMemoryで落ちることはないのですが、それでもまだleakは検出されます。

## SoftReferenceを使用する。

```
    private SoftReference<TextToSpeech> textToSpeech;

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textToSpeech = new SoftReference<TextToSpeech>(new TextToSpeech(getApplicationContext(), this));

    }

    private void init(Context context) {
    }

@Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            if (textToSpeech.get().isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
                textToSpeech.get().setLanguage(locale);
            } else {
                Log.e("TTS", "Not support locale.");
            }
        }
    }
```
こんな感じで実装するとleakが検出されなくなりました。


## 参考
最終的に行き着いた答えがstack overflowにありました。
[How to release the static var of TextToSpeech in order to avoid leak?](http://stackoverflow.com/questions/23073577/how-to-release-the-static-var-of-texttospeech-in-order-to-avoid-leak)
何も知らない人のための機械学習

#機械学習とは
**機械学習**とは、**コンピュータにヒトのような学習能力を獲得させるための技術の総称**のことです。
大量のデータ（**ビッグデータ**）から有用な知識を見つけ出す**データマイニング**のために利用されます。


#3つの機械学習
機械学習は、扱うデータによって**「教師あり学習」「教師なし学習」「強化学習」**の3つに分類されます。
### 教師あり学習
　**教師あり学習**では、**生徒（コンピュータ）が先生（人間）に答えを教えてもらいながら学習**します。
　コンピュータには、あらかじめ正解・不正解がわかっているデータを渡します。この対をいくつも学習することで、教わっていないデータにも正解・不正解を予想することができます。このような、**未知の問題にも正しく回答する力**を**汎化能力**といい、学習がどの程度成功しているかの大切な指標になります。
　身近なところでは、手書き文字認識（書かれた文字が何の文字かを判別する問題）、画像認識（何の画像かを判別する問題）などの**分類問題**や、株価予測などの**回帰問題**、Webページのランキングなどの**順序予測問題**に使われています。
### 教師なし学習
**教師なし学習**では、**生徒は一人で黙々と勉強**します。コンピュータに渡すデータは、とりあえず着目するもの全部です。コンピュータはそれを俯瞰し、全体の傾向を学習していきます。何か答えがはっきりした問題を解くのではなく、例えば全体から外れた部分を知らせてくれるような問題に使われます。
　身近なところでは、クレジットカードの不正検知などの**異常検知**、録画したテレビ番組のハイライト抽出などの**変化検知**に使われています。
### 強化学習
強化学習は、教師ありと教師なしの中間に相当します。**褒めて伸ばす型教育**です。教師は答えそのものは教えませんが、生徒の予測した答えがどのくらい適切だったかを評価します。これを元に、生徒は評価ができるだけ高くなるように学習をしていきます。**PCDAサイクルを超高速で回しまくる**イメージです。
身近なところでは、囲碁の人工知能や、マーケティング戦略の最適化などに応用されています。
sysdig をインストールして使ってみる

Docker(Rancher)環境は、これまでの運用監視の常識が通用しません。
これまでは、OSがありそれを監視していれば問題はありませんでした。

しかし、Dockerコンテナーには OS的なものはありますが厳密にはOSが動いているわけではないので、監視も違う考え方が必要です。

Prometheus などがコンテナー管理ツールとして出てきていますが、コンソールから使える sysdig の紹介です。

＃これまでよく使われてきたvmstatコマンドとか top(htop)コマンドとか、みたいなものと思えば良いです。

# 1. sysdig のサイト

Sysdigのページ
Container Troubleshooting and Linux Visibility | Sysdig
http://www.sysdig.org/

ncurses の csysdig の説明動画があるので見てみましょう。
https://www.youtube.com/watch?time_continue=4&v=UJ4wVrbP-Q8

マウスでポチポチ操作できそうです。便利ですね。

# 2. sysdig のインストール

RPMやdebパッケージもあるようですが、今ふうにはコンテナーで動かすのがオススメのようです。

```lang:docker-host/bash
$ sudo docker pull sysdig/sysdig
```
まず、コンテナーをPullします。

# 3. csysdig の起動
以下のコマンドでsysdigのイメージが起動します。

```lang:docker-host/bash
$ sudo docker run -i -t --name sysdig --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro sysdig/sysdig
```

2回目以降は、--name は必要ありません。以下のコマンドで起動して下さい。

```lang:docker-host/bash
$ sudo docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro sysdig/sysdig
```
コンソールに入ったら(以下のコマンドはコンテナー内で起動します)

```lang:docker-container/bash
root@480427897ec8:/# csysdig
```

以下の様な画面になると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/fb875846-734e-21aa-e9de-272699f824a6.png)

一番下のFunctionの列で「Help」をクリックすると使い方、
「Views」をクリックするとその他の項目を見ることができます。

# 4 sysdig の起動

同様にコマンドラインでも起動できます。

```lang:docker-container/bash
root@480427897ec8:/# sysdig
```
しかし、オプションなしで起動すると、ログがザーザーながれますのでご注意ください。
Google Apps ScriptからMastodonにトゥートしてみた

## はじめに
マストドン流行っていますね。
流行に身を任せて、mstdn.jpとpawoonのアカウントを作成しました。
せっかくなので、Google Apps Scriptで定期ポストできるようにしようと思いました。
そこで、Google Apps Scriptから、マストドンに投稿する方法を示します。

## 事前準備
[Twitter の投稿を IFTTT で Mastodon へ転送する。]
(http://qiita.com/yukimochi/items/f80a50a4486d0cb770dc)
上記の記事を参考に、Mastdonのアクセストークンを取得しておきます。

取得したアクセストークンは、GASのメニューから「ファイル」→「プロジェクトのプロパティ」→「スクリプトのプロパティ」を選択して、プロパティに設定しておきます。
![mstdn_sample1.png](https://qiita-image-store.s3.amazonaws.com/0/100312/92bf7a7e-0372-223e-009f-3215b205e24d.png)

## サンプルコード 

```javascript
//mastodonに投稿する
function postUpdateToots(message,token,url){
  var url = url
  var options =
   {
     "method"  : "post",
     "payload" : "status=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}
     
   };
   UrlFetchApp.fetch(url,options);
}

//mstdnjpとpawooの両方のアカウントに同じメッセージを投稿する
function postMstdn(){
  var mstdnjp_token = ScriptProperties.getProperty("mstdnjpToken");
  var pawoo_token = ScriptProperties.getProperty("pawooToken");
  var mstdnjp_url = "https://mstdn.jp/api/v1/statuses";
  var pawoo_url = "https://pawoo.net/api/v1/statuses";
  var message = "投稿テスト"

  postUpdateToots(message,mstdnjp_token,mstdnjp_url);
  postUpdateToots(message,pawoo_token,pawoo_url);
}
```
## まとめ
これらを応用すれば、簡単なmastdon botをサーバーレスで作ることができます。
ボクは、過去のブログ記事などをスケジュールで、ランダムに投稿するように使っています。

## 参考URL
- [Twitter の投稿を IFTTT で Mastodon へ転送する。]
(http://qiita.com/yukimochi/items/f80a50a4486d0cb770dc)
- https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#apps