OmniAICreator/Qiita-1.07M huggingface dataset:
minitestの5.10.2でtestが動作しないときに試すこと

(2017/05/17追記あり)
[Ruby on Rails Tutorial](https://railstutorial.jp/chapters/static_pages?version=5.0#cha-static_pages)のテストが動作しなかったので備忘録代わりに。

上記Tutorialにおいて、Railsのバージョンは5.0.0.1で固定されている。
そして、簡単なコントローラーをgenerateしてテストを実行しようとすると下記エラーが発生する。

```sh
$ rails test
Running via Spring preloader in process 2460
Run options: --seed 30883

# Running:

..

Finished in 0.811104s, 2.4658 runs/s, 2.4658 assertions/s.
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-5.0.0.1/lib/rails/test_unit/minitest_plugin.rb:9:in `aggregated_results': wrong number of arguments (given 1, expected 0) (ArgumentError)
        from /usr/local/rvm/gems/ruby-2.3.0/gems/minitest-5.10.2/lib/minitest.rb:597:in `report'
        from /usr/local/rvm/gems/ruby-2.3.0/gems/minitest-reporters-1.1.9/lib/minitest/minitest_reporter_plugin.rb:26:in `each'
        from /usr/local/rvm/gems/ruby-2.3.0/gems/minitest-reporters-1.1.9/lib/minitest/minitest_reporter_plugin.rb:26:in `report'
        from /usr/local/rvm/gems/ruby-2.3.0/gems/minitest-5.10.2/lib/minitest.rb:687:in `each'
・
・
・
```

どうもgemのminitestが5.10.2(2017/5/9リリース)にアップデートされたことで発生した様子。
参考：[StackOverflow](http://stackoverflow.com/questions/43886586/minitest-plugin-rb9-getting-wrong-number-of-arguments)

Rails側でminitestに合わせた対応が進んでいる。
暫定対応としては、gemfileに以下の記述を追加し、5.10.1のminitestをインストールすることで解決ができる。

```
gem 'minitest', '~> 5.10', '!= 5.10.2'
```

(2017/5/17追記)
2017/5/12にリリースされた[Rails5.0.3とRails5.1.1で対応された](http://weblog.rubyonrails.org/2017/5/12/Rails-5-0-3-and-5-1-1-have-been-released/)そうです。
macOSでnginxを使ってみる

# Install

下記のように```brew```を用いてインストールできます。

```
$ brew install nginx
```

## 確認

下記のようなディレクトリが作成されます。

```
/usr/local/bin/nginx
/usr/local/Cellar/nginx
/usr/local/etc/nginx
/usr/local/opt/nginx
/usr/local/var/homebrew/linked/nginx
/usr/local/var/log/nginx

```

静的資源のドキュメントルートは、下記のように設定されているみたいなので
絶対パスは```/usr/local/var/www```になります。

```
$  ls -l /usr/local/Cellar/nginx/1.10.2_1/
lrwxr-xr-x  1 XXX  XXX      16 11 10 17:31 html -> ../../../var/www
```

なので、初期設定```http://localhost:8080```でアクセスした場合はこのファイルがブラウザに表示されます。

```
/usr/local/var/www/index.html 
```

## 設定ファイル

設定ファイルは下記で、これを編集していくのがメインとなりそうです。

```
/usr/local/etc/nginx/nginx.conf
```

今日は自分が配置した、静的資源を表示するところまでに留めておきます。

※今後URLのパスによって、裏でアプリを動かしたりするところまでが目標なので、すべてが理解できたところで再度記事を書こうと思います。


# 超初級チュートリアル

## nginx.conf


```
http {
    
    #省略

    server {
        listen       80;
        server_name  kws9-test.com;

        location / {
            root   html;   
            index  index.html index.htm;
        }
}
```

最低限の修正箇所を記載してますが、それぞれ下記のような感じです

* listen → ポート番号
* server_name → サーバ名（ブラウザに打ち込むURL）
* location → サーバ名に続くパスを指定
* root → ルートディレクトリを指定

※ルートディレクトリは先ほど説明したデフォルトを使用(html -> /usr/local/var/www)

## 静的資源の作成

```
$ cd /usr/local/Cellar/nginx/1.10.2_1/html/
$ vi index.html
```

## hosts設定

```
127.0.0.1    kws9-test.com
```

## nginx起動

下記コマンドで起動(sudo は指定したポートが1024番以降は不要)

```
#起動
$ sudo nginx

#停止
$ sudo nginx -s stop

#再起動
$ sudo nginx -s reload
```

※PATHに/usr/local/binを事前に追加しておいてください

```
$ export PATH=$PATH:/usr/local/bin
```

これらの設定で、```server_name  kws9-test.com```にアクセスすると

`/usr/local/Cellar/nginx/1.10.2_1/html/index.html`が表示されるようになります。
Bootstrap Star Rating 使ってみる

# 前書き

お試し検証用アプリでRating表示機能を設けており、もともと1刻みで登録できるようにしていたのですが、0.5刻みで表示できるようになプラグインを使って、見た目いい感じにしてみようと思い

**Bootstrap Star Rating** を試しに使ってみることにしました。



# 必要なもの


https://github.com/kartik-v/bootstrap-star-rating/zipball/master

上記からダウンロードができる下記2ファイルと

* star-rating.css
* star-rating.js

`bootstrap.min.css` と　`jquery.min.js`　です

はまった点としてローカルに配置する場合

`bootstrap.min.css`だけではだめでして、下記のようなツリー構造にしないと★が表示されません。

```
+ css
    - bootstrap.min.css
+ fonts
    - glyphicons-halflings-regular.woff2
```

無難にBootStrapをローカルで使うときは、ディレクトリごと使えば思わぬ不具合に遭遇せずに済みそうです。

## form 修正


htmlの中で、ratingをつけたい箇所に下記のように追加


```html
<input id="grade" name="grade"  class="rating rating-loading" data-min="0" data-max="5" data-step="0.5" data-size="xs">
```

色々なサンプルや使い方も下記の公式サイトに詳しく載ってます。

http://plugins.krajee.com/star-rating:title

## js 修正

更新時ダイアログを開く際に、既存のrating情報を持たせた状態で開けるようにしたかったのですが、

既存のデータ付与方法では、上手くいきませんでした。

```javascript
var targetHotel = JSON.parse($('#'+ this.id).attr('data-hotel'));
$.each(targetHotel, function(i,v){
    $('#updateHotel').find('#'+i).val(v);
})
```

どうやら、val()を用いた変更はできないらしく

調べていたら方法を見つけたので、修正しました。

```javascript
var targetHotel = JSON.parse($('#'+ this.id).attr('data-hotel'));
$.each(targetHotel, function(i,v){
    if (i == 'grade'){
        $('#updateHotel').find('#grade').rating('update', v);
    }else{
        $('#updateHotel').find('#'+i).val(v);
    }
})	
```

`.rating('update', 'updateしたい値')`のような方法で、値を更新できるそうです。

## 見た目

![20161006181211.png](https://qiita-image-store.s3.amazonaws.com/0/109149/356c4eed-33e4-ccff-e7c9-0d68ddfe1ad7.png)
　

これで、既存ratingの表示と更新が可能になりました。
SpringBoot Elasticsearch 接続

# 前書き

SpringBootとElasticsearchの接続まではできたのでメモ書き。　

# 準備

MySQLからElasticsearchにembulkを使ってデータを投入。

## embulkダウンロード

```
curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar"
chmod +x ~/.embulk/bin/embulk
echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```

## プラグインのinstall

```
embulk gem install embulk-input-mysql embulk-output-elasticsearch 
```

## config作成

```
in:
  type: mysql
  user: user
  password: pass
  database: sample_db
  table: hotel
  host: localhost
  select : "id,name,address,country_code,city_code,grade,facility"
  where : "delete_flag=0"
out:
  type: elasticsearch
  index: hotel_auto_complete
  index_type: hotel_auto_complete
  nodes:
  - {host: localhost, port: 9300}

```

## データ投入

```
# 投入データの確認
embulk preview config.yml

# 投入
embulk run config.yml 
```

　

# SpringBootで使ったもの

## 設定ファイル

接続用に下記を`application.yml`に追記

```
spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: localhost:9300
```


## Repository

```java
public interface AutoCompleteRepository extends ElasticsearchRepository<AutoComplete, Long> {
	
	//@Query("{\"query\": {\"prefix\": {\"address\": \"?0\"}}}")
	public List<AutoComplete> findByNameLike(String query, Pageable pageable);

}
```

## Entity

```java
@Document(indexName = "hotel_auto_complete", type = "hotel_auto_complete")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class AutoComplete {

	@Id
    private Long id;

    private String name;

    private String address;

    private String countryCode;
    
    private String cityCode;

    private Integer grade;

    private String facility;
    
    private String imagePath;
}
```

## Service

```java
@Service
@Transactional
public class AutoCompleteService {
	
	

    @Autowired
    private AutoCompleteRepository autoCompleteRepository;

    /**
     * 
     * @return
     */
    public HotelAutoCompleteResponseBody autoComplete(AutoCompleteRequest request) {
    	
    	Pageable topTen = new PageRequest(0, 10);
    	
    	List<String> resultList = autoCompleteRepository.findByNameLike(request.getQuery(), topTen).stream()
    			.map(x -> new String(x.getName())).collect(MoreCollectors.toImmutableList());
    	
    	return new HotelAutoCompleteResponseBody(resultList);
    	
    	
    	
    }
}
```

# 感想

Springに備わっているメソッドを、いくつか試しに使ったのですが

* ```findByNameLike```
    * Like文のような使い方ができますが空白スペースが入ると検索結果0になる。
* ```findByNameContaining```
    * "ABC DEF"みたいな文字列だと"ABC"まで入れないと返却がない。
* ```@Query```
    * 引数を使った素敵なQueryが書けず。
* ElasticsearchのSuggester
    * Springでの使い方が記述されたサイトが少なく断念

このレベルの使い方だと、DB直接クエリ投げたほうがいいので上手く活用できる方法を模索します..
ほどよく手を抜きつつ複数サイトの安全性を確かめる


## サイトのセキュリティ診断

McAfeeのセキュリティ診断サイト
http://www.siteadvisor.com/sites/

◆いざ、セキュリティチェック

```bash
cat survey_target_urls.csv | xargs -I URL sh -c '{ wget http://www.siteadvisor.com/sites/URL; sleep 15; }'
```
※url数が多い場合は、tmuxやscreenなどでバックグランドで実行するのがおすすめです。

### cat

調査対象のurlが1つずつ渡せれば、ファイル形式等は何でも良いです。
調査対象のサイトが多くないのであれば、echoで出力してしまっても良いです。
例) `echo 'http://hoge/,http://hogehoge/,http://hogehogehoge/'`

### xargs 

xargsをかませることで、url１つ1つを実行していきます。

### wget

今回は調査結果のhtmlファイルをローカルに取得します。

### sleep

DoS攻撃に間違われないように、一定時間置いてコンテンツを取得するというマナーを守ります。


## 判定パターン

1: This link is safe. We tested it and didn't find any significant security issues.
2: This link isn't rated. Either we don't have enough information, or we haven't tested it yet. Proceed with caution.
3: This link might be dangerous. We tested it and found security risks. Beware.
4: We have no data for the page you requested. You can check another site using the look up box below.

## 判定パターン別の集計

◆全体リンク数
`cat survey_target_urls.csv | wc`
(行数 = リンク数)

◆1: Safeの数
`grep -l 'This link is safe' * | wc`

◆2: Not Ratedの数
`grep -l "This link isn't rated" * | wc`

◆3: Might be dangerousの数
`grep -l 'This link might be dangerous' * | wc`

◆4: No dataの数
`grep -l 'We have no data' * | wc`


## その他セキュリティ診断サイト
- Norton Safe Web https://safeweb.norton.com/
　`https://safeweb.norton.com/report/show?url={URL}`
　※60秒おきにコンテンツ取得を試みても、一定時間回すとリミット超過でロボット扱いされてしまいエラーとなってしまった。

- Google Safe Browsing 
  `http://www.google.com/safebrowsing/diagnostic?site={URL}`
　※特定のフォームは用意されておらず、
プロキシ環境下でVisual studio codeにExtensionが入らない問題を解決する

---

**2017/8/18追記**

Ver1.15.1でプロキシ認証の方法が変わり、直ったみたいです。よかった・・・
https://code.visualstudio.com/updates/v1_15#_proxy-server-authentication

---

[認証付きのプロキシ環境下でVisual studio codeの画面からExtensionがインストールできない問題](https://github.com/Microsoft/vscode/issues/23164)

去年の4月ぐらいにも[同様の問題](
http://qiita.com/cha2maru/items/427ea605e9518c347bb8
)があったようなのですが、最近また再発したので、解決策をメモ


## 環境

Windows 10

## コマンドラインからインストールする

githubのIssueにも解決策が書かれていたのですが、以下のコマンドを実行して、コマンドラインでエクステンションをインストールすると、proxy環境下でもExtensionをインストールできます。完全な解決策ではないですが、とりあえずはこれでしのげるかなと

```
> code --install-extension <author>.<extension>
```

`<author>.<extension>`の部分は、Visual studio codeのExtension画面を開いたときに、タイトルの横に表示されている文字列です

![2017-05-17_00h00_25.png](https://qiita-image-store.s3.amazonaws.com/0/93999/661d372d-dfc9-0251-31e9-159f3bf90347.png)


~~同じ操作でアップデートもできるので、バッチファイルを作っておけば、便利かもしれません。~~

**2017/6/19追記** 一回 `code --uninstall-extension <author>.<extension> ` してから、インストールしなおさないと、アップデート（この場合は再インストール？）できませんでした。
Laravel Mix の npm コマンドが Heroku 上で実行出来ない時に


Heroku のビルド時に `npm run production`するとコケる。

中に入って `npm run production` しても普通に実行できるのに…

エラーログには以下のような記録が

````
couldn't write 83961 items to stdout: Resource temporarily unavailable
````

こういうときには、 `--progress`オプションを外すと良い。

https://github.com/webpack/webpack/issues/1553#issuecomment-159648679

> i had the same issue, try to remove the --progress flag from webpack command, its worked for me.
looks like heroku stop and failed the build if its prints too many logs.

とのこと。
Go/Gopher.jsで最速の2Dの行列演算の設計

nanovgoはあのままのアーキテクチャだとダメそうで、スクラップ・アンド・ビルドしたいなぁと思ったりするので、とりあえず手を付けられそうなところからボトムアップで部品を作っています。

で、本題の行列演算。

nanovgoでは3x2の行列を使っています。2D変換の座標値のアフィン変換であれば3x2でOK。アニメーションとか興味ある人なら当然Adobe Flashはみんな使ったことあるはずで、今更書く必要もないんですが、[Flashも同じ行列](http://help.adobe.com/en_US/as2/reference/flashlite/WSB241BA5E-9675-4b87-A3B1-CC97893EE65E.html)を使ってます。行と列は転置されていますが、まあ一緒。

Goで作るからにはふつうのネイティブ環境と、Gopher.jsの両方に対応したいのが人情というもの。で、ネイティブ環境だと精度は32ビットもあれば十分。もしかしたら16ビット固定小数点数でもいいかもしれないけどGoが非対応。で、Gopher.jsの場合はパフォーマンスTipsとしてintとfloat64以外は使ってくれるな、とREADMEに確か書かれていました。なので、ネイティブ環境とブラウザ環境で最速を狙うにはビルドタグで切り替える必要があります。じゃあ、どういうコードを書けばいいのかな、というを実験しました。

ちなみに、nanovgoはブラウザ対応はバーテックスバッファーのコピー以外には特別に手当はしてなくて、どっちもfloat32を使っていました。

コードは[ここ](https://gist.github.com/shibukawa/b9acb32765a87a63c24816b8c89e6907)にあります。

# 単純実装

まずはつぎのようなコードを作ってみました。メモリのヒープからのアロケートは遅いけど、スタックは別に遅くないし、要素数も少ないのでカジュアルにコピーでいいだろう、ということで全コピーのimmutableっぽい感じの実装にしました。次のコードは32ビットだけど、float64のも作ってベンチしました。

```go
type Mat32 [6]float32

func (t Mat32) Multiply(s Mat32) Mat32 {
	t0 := t[0]*s[0] + t[1]*s[2]
	t2 := t[2]*s[0] + t[3]*s[2]
	t4 := t[4]*s[0] + t[5]*s[2] + s[4]
	t[1] = t[0]*s[1] + t[1]*s[3]
	t[3] = t[2]*s[1] + t[3]*s[3]
	t[5] = t[4]*s[1] + t[5]*s[3] + s[5]
	t[0] = t0
	t[2] = t2
	t[4] = t4
	return t
}
```

ベンチを取った結果です。

| 行列の実装  | darwin/amd64 | gopher.js |
|:-:|:-:|:-:|
| [6]float32  | 14 ns/op  | 2060 ns/op |
| [6]float64  | 18 ns/op  | 1900 ns/op |

うーむ。確かにfloat64の方がgopher.jsの方が速いが・・・そもそもすごく遅い。ネイティブコードと150倍ぐらい遅い。

# インラインで演算する実装

じゃあ、コピーじゃなくてインラインでやってみた方がいいのかな・・・と思って試してみた結果が以下の通り。

```go
func (t *Mat32) Multiply(s *Mat32) {
	t0 := t[0]*s[0] + t[1]*s[2]
	t2 := t[2]*s[0] + t[3]*s[2]
	t4 := t[4]*s[0] + t[5]*s[2] + s[4]
	t[1] = t[0]*s[1] + t[1]*s[3]
	t[3] = t[2]*s[1] + t[3]*s[3]
	t[5] = t[4]*s[1] + t[5]*s[3] + s[5]
	t[0] = t0
	t[2] = t2
	t[4] = t4
}
```

| 行列の実装  | darwin/amd64 | gopher.js |
|:-:|:-:|:-:|
| [6]float32  | 110 ns/op  | 1700 ns/op |
| [6]float64  | 99 ns/op  | 1560 ns/op |

差は縮まりましたが・・・

# 結果を踏まえた実装方針

当初の予定どおり、ネイティブは32ビット、JSは64ビットの方が良さそうですが、それにプラスして、ネイティブの方はコピーを積極的に、JSの方はインラインで・・・という実装の仕分けをした方が良さそうです。

それにしてもこれだけJS実装の速度に差があると、計算結果のキャッシュは不可欠ですね。nanovgoは毎フレームキャッシュせずに毎回計算していたので、そこの構造にも手を入れる必要があります。

WebAssemblyとJavaScriptの違いとしてはfloat32の有無があるので、そのうちGoがWebAssemblyに対応してくれるようなことがあったら、また測定しなおしでしょうけど、とりあえずはこの方針でいきたいと思います。
明示的Intent（値をやり取りする場合）

Activity間で、計算結果や入力値など何らかの値をやり取りしたい場合がある。
そのような場合は、Intentを使って値のやり取りができる。

#Intentとは
Activityから他のActivityを呼び出したい場合、「android.content.Intent」というクラスを使う。
Intentクラスは、以下2点を格納する入れ物のようなものである。
1.呼び出しActivityを決める情報
2.呼び出しActivityに渡したい情報

#Intentを用いたActivityの呼び出し
Intentに必要な情報を設定し、startActivityメソッドに引数として渡すと、指定されたActivityが呼び出される。

次のコードでは、ボタンをクリックしたときにIntentに呼び出したいActivityである
SubActivityのクラスを設定し、startActivityメソッドでActivityを呼び出している。

```java
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //setOnClickListenerのコンストラクタ内でthisを指定すると
                //setOnClickListenerのインスタンスをさしてしまうので、
                //MainActivity.thisとする。
                Intent intent = new Intent(MainActivity.this,SubActivity.class);

                startActivity(intent);

```

#Activity間での値のやり取り
Activity間で値をやり取りするには、呼び出し元ActivityでIntentに値を設定し、
呼び出し先ActivityでIntentから値を取得すればいい。
Intentに値を設定するにはputExtraメソッド、Intentから値を取得するにはgetStringExtraメソッドを使う。

次のコードは、呼び出し元Activityのコードで、
ボタンがクリックされた時に、Intentに呼び出し先Activityと渡したい値を設定している。
この例では、キーと文字列の組をIntentに設定している。

```java
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText editText =(EditText)findViewById(R.id.editText);
                String textString = editText.getText().toString();

                Intent intent = new Intent(MainActivity.this,SubActivity.class);
                intent.putExtra(KEY,textString);

                startActivityForResult(intent,SUB_ACTIVITY_REQUEST);
```
次のコードは、呼び出し先Activityのコードで、
呼び出し元で設定されたキーに対応する文字列を取得し、画面に表示する。


```java
        Intent intent = getIntent();
        String str = intent.getStringExtra(MainActivity.KEY);

        editText.setText(str);
        TextView textView = (TextView)findViewById(R.id.subTextView);
        textView.setText("こんにちは！"+str+"さん");

```

#Githubリンク
リポジトリ：https://github.com/tagfa/MyExplicitIntentActivity02
paiza POH logic_summoner ロジックサマナー #コード詠唱


召喚に使ったアイテムと称号の対応表を作るのは面倒だったので中止で

ファイル名が11〜なのはmoshijoを9、hundred_thousandを10として扱っているからです(hundred_thousandの記事は週末に出します)

## 召喚の書

- 優遇されている言語にpaizaのこだわりを(略)

### 召喚の書：竜 [Ruby]

- ゲーム開始時に自動入力される

### 召喚の書：翼 [PHP]

```rb:11a1.rb
#!/usr/bin/ruby
n=gets.to_i;s=gets.chomp
a=[]
(1..n).each{|i|a.send(s[i-1]==?L ? :unshift : :push,i)}
puts a*' '
```

### 召喚の書：獣 [C]

- さすがに(思考停止)

```sh:11a2.sh
#!/bin/sh
dd
```

### 召喚の書：妖 [Java]

```rb:11a3.rb
#!/usr/bin/ruby
puts gets.chomp==gets.chomp ? :OK : :NG
```

## 生け贄

### 白い祈りの角笛

```rb:11b1.rb
#!/usr/bin/ruby
puts ('b'+gets.chomp).chars.chunk{|e|e}.map.with_index{|(k,v),i|v.size-(i==0?1:0)}*' '
```

### 夜との契約

- 不明な数字が2個だけなので斜めの判定は不要です

```rb:11b2.rb
#!/usr/bin/ruby
N=gets.to_i
T=N*(N*N+1)/2
def f(a)
	[a,a.transpose].all?{|b|b.all?{|e|e.reduce(:+)==T}}
end
a=$<.map{|e|e.split.map(&:to_i)}
q=[];g=[]
N.times{|i|N.times{|j|
	if a[i][j]==0
		q<<[i,j]
	else
		g<<a[i][j]
	end
}}
g=[*1..N*N]-g
q.permutation{|x,y|
	a[x[0]][x[1]]=g[0]
	a[y[0]][y[1]]=g[1]
	f(a) and puts a.map{|e|e*' '}
}
```

## 宝具

### 色変えメイク

```rb:11c1.rb
#!/usr/bin/ruby
puts `dd`.count(?A)*100
```

### 惚れ薬

```rb:11c2.rb
#!/usr/bin/ruby
n,m,a,b,*c=`dd`.split.map(&:to_i)
c.each{|e|
	m+=e
	if e<0
		if m<0
			p -1
			break
		end
		if m<=a
			m+=b
		end
	end
}
p m
```

### 王冠

```rb:11c3.rb
#!/usr/bin/ruby
x=gets.count(?1)-gets.to_i
puts x>0?:No:-x
```

## スパイス

### javaの木

```rb:11d1.rb
#!/usr/bin/ruby
a,b,c,d=`dd`.split.map(&:to_i)
p a*d>c*b ? b : d
```

### rubyの原石

- paiza(.io)で実行する際は、言語をBashにして、2行目を`awk ''`で囲って下さい

```awk:11d2.awk
#!/usr/bin/awk -f
$0=$1*$2
```

### pythonリング

```awk:11d3.awk
#!/usr/bin/awk -f
$0=$1+50>100?100:$1+50
```

### 歯車typeC

```rb:11d4.rb
#!/usr/bin/ruby
h=Hash.new{|h,k|h[k]=''.dup} # Ruby3
gets.to_i.times{a,b=gets.split;h[a.to_i]<<b}
puts h.sort.map{|e|e*' '}
```

### JSの羽

- マラソンマッチ問題には割と言えることだけど、無を出力すれば正解扱いになる問題が多いよね。
- 締め切り後にちゃんとした解答を公開するかは未定。

```php:11d5.php
0
```

### 天球儀

- paiza問題なので公開できません
vSphere メモリ解説

### はじめに

* 本ページはvSphereにおけるメモリ種類について触れます。
    * 表示されているメモリ量は何を指すのかまとめます。
    * [こちら](https://blogs.vmware.com/jp-cim/2014/04/vcenter_memory.html)の解説を補います。

### VMにおけるメモリの考え方

* メモリ情報ページを見る前に意識したいメモリの違いについてです。
    * 下の方がメモリ量は小さい。

|概要|英語表記|意味|
|:-----------|:-----|:------------------|
|予約メモリ|Configured Memory|VM作成時に指定する最大メモリ量。例えば2GB(2048MB)など。このメモリ量がすべて利用されると実利用となるため、メモリーオーバーコミットの計算で使用される。|
|消費メモリ|Consumed Memory|VMがESXiホストのメモリを(バッキング,マッピング)使用している量。一度使用すると、なかなか解放されない。vMotionにより利用メモリ以外が解放される場合がある。ESXiホストにおけるメモリ使用率の計算に使われる。|
|利用メモリ|Active Memory|頻繁に使用しているVMのメモリ量。一定期間の統計値で算出される。VMにおけるメモリ使用率％表示のケージに使われる|
 
### 仮想マシンのハードウェア

* VMのサマリーをみたときの名称です。

|名称|概要|
|:-----------|:------------|
|メモリ|予約メモリ|
|予約メモリ使用率|利用メモリ|
|メモリ オーバーヘッド||

### ESXiホストのハードウェア

* ESXiホストのサマリーをみたときの名称です。

|名称|概要|
|:-----------|:------------|
|容量|||
|使用済み/メモリ使用量|消費メモリの合計値||
|空き容量|||

### ゲストメモリ

* 仮想マシンからゲストOSをみたときの名称です。

|名称|英語表記|概要|
|:-----------|:-----|:-----|:-------|
|有効|Active|利用メモリ|
|プライベート|Private|消費メモリ||
|共有|Shared|
|スワップ済み|Swapped|
|圧縮済み|Compressed|
|バルーン済み|Ballooned|
|未アクセス|Unaccessed|ゲストOSから参照されないメモリ|

### ホストメモリ

* 仮想マシンについてESXiホストからみたときの名称です。

|名称|英語表記|概要|
|:-----------|:----|:------------|
|消費|Consumed|消費メモリ+オーバーヘッドの消費||
|オーバーヘッドの消費|Overhead Consumption|仮想マシンをパワーオンするために必要なオーバーヘッドメモリ|
|制限|Limit||
|構成済み|Configured|予約メモリ||
|割り当て最低限度|Worst Case Allocation|重度なオーバーコミットが発生した場合のメモリ確保量|
|オーバーヘッド予約|Overhead Reservation|仮想化オーバーヘッド用に予約されているメモリの量|

### DRSにおけるメモリ

* [こちらのページ](https://blogs.vmware.com/vsphere/2016/05/load-balancing-vsphere-clusters-with-drs.html)では、活動していないメモリ(Idle Memory)という表現がある。
    * 消費メモリ(Consumed Memory)から利用メモリ(Active Memory)を減算した値に相当。
    * DRSでは、利用メモリ(Active Memory)と活動していないメモリ(Idle Memory)の25%の合算値にてメモリにおけるホスト負荷を算出。
VBScript Outlookのタスク（仕事）にファイルを登録する

```vbnet:MakeOutlookTaskformFile.vbs
Const olJournalItem = 4
Const olTaskItem = 3
Const olFolderJournal = 7
Const StoreName = "Mail@Address" 'Change Your mailAddres
Const olSave = 0
Const olDiscard = 1
Const JpnOlJounrnalTypeNameOfEmail = "電子メールメッセージ"
Const JpnOlJounrnalTypeNameOfDocument = "ドキュメント"
Const JpnOlTaskTypeNameOfDocument = "仕事"
Const olTaskNotStarted = 0
Const olTaskInProgress = 1
Dim oApp: Set oApp = CreateObject("Outlook.Application")
Dim NS: Set NS = oApp.GetNamespace("MAPI")
Dim oJfol
Dim objArgs, I, strFile, strFolder
Dim objFile, objFolder, objPath, strScr
Dim strBase, strExt, strParent, strPath, strZip, RetVal
Dim objShell: Set objShell = CreateObject("WScript.Shell")
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim myJItm 'As Outlook.JournalItem
Dim myMItm 'As Outlook.MailItem
Dim blnExist 'As Boolean
Dim oRoot, olStore
Set olStore = oApp.Session.Stores.Item(StoreName)
Set oRoot = oApp.Session.Stores.Item(StoreName).GetRootFolder
Set oJfol = oRoot.folders(JpnOlTaskTypeNameOfDocument)
Set objArgs = Wscript.Arguments

I=0
Set objFile = FSO.GetFile(CStr(objArgs(I)))
strParent = FSO.GetParentFolderName(objFile)
Set objPath = FSO.GetFolder(strParent)
strBase = FSO.GetBaseName(CStr(objArgs(I)))
strExt = FSO.GetExtensionName(CStr(objArgs(I)))
strPath = strParent & "\"
blnExist = False
If blnExist = False Then
msgbox objfile.path
Set myJItm = oApp.CreateItem(olTaskItem)

With myJItm
.Display
.Subject = "<" & "file:///" & replace(objFile.Path,"\","/",1,-1) & ">"
.Body = "CurrentFilePath:= " & strParent & vbCrLf & _
"FileName:= " & objFile.Name & vbCrLf & _
"FolderLink:= " & " <" & "file:///" & replace(strParent,"\","/",1,-1) & ">" & vbCrLf & _
"FileLink:=" & " <" & "file:///" & replace(objFile.Path,"\","/",1,-1) & ">" & vbCrLf & _
"CreationTime:= " & Cdate(FSO.GetFile(CStr(objArgs(I))).DateCreated) & vbCrLf & _
"LastWriteTime:= " & Cdate(FSO.GetFile(CStr(objArgs(I))).DateLastModified)

If LCase(strExt) = "msg" Then
Set myMItm= myJtm
.Body = myJItm.Body & VbCrLf & Left(myMItm.Body, 1000)
.ContactNames = myMItm.SenderName
End If

.Categories = .Categories
.Status = olTaskInProgress
.StartDate = Date() '今日が開始時点
.End = DateAdd("d",30,Date()) ’期限は1か月後
.Save
.Close 1
Wscript.Sleep 1000
End With
Else
End If

Set objShell = Nothing
Set FSO = Nothing
Set NS = Nothing
Set oApp = Nothing
Wscript.Quit
```

##ファイルをドラッグアンドドロップでタスクに登録する
しかもファイルリンクを作成して、タスクからファイルを開けるようにしています。
標準ではタスクの期間を1か月にしています。
StoreName = "Mail@Address" に自分のメールアドレスをいれてください。

##ファイル形式の制限
オフィスの主なファイル、PDFにしています。

##詳しいオブジェクトの解説
というほどでもありませんが、
[OUTLOOK VBA オブジェクトまとめ](http://qiita.com/Q11Q/items/ac14d96c00e707de5d13)
があります。
jQuery UI でオートコンプリート

# 準備

## jQuery UI

http://jqueryui.com/download/:title

上記URLより　Theme ⇒ [UI lightness] を選択してダウンロードしました。

その中の下記2ファイルを利用

* jquery-ui.js
* jquery-ui.css


## オートコンプリート用のAPI

SpringBootを使って、下記のようなAPIを追加

リクエスト：「検索文字列・検索対象」

レスポンス：「検索結果のリスト」


## Python/Jinja2

Pythonを経由して、データのValidationや加工を行えるようにする。
※　検証用にこのような構成にしています。

# 内容

## API仕様

```target``` には検索条件を、```query``` には入力中の文字が入る想定です。

たとえば、下記のようなリクエスト「Hotel name」が「R」から始まるホテル名といったリクエストを投げると

```javascript
{
  "header": {
    "countryCode": "US",
    "currencyCode": "USD",
    "languageCode": "en",
  },
  "body": {
    "query": "R",
    "target": "name"
  }
}
```

こんな感じで、ホテル名のリストが返却されます。

```javascript
{
  "status": 200,
  "header": {
    "languageCode": "en",
    "countryCode": "US",
    "currencyCode": "USD",
    "userAgent": "string",
    "userIp": "string"
  },
  "body": {
    "results": [
      "Royal Park Hotel",
      "Richmond Hotel Higashi Osaka",
      "Ryokan Mikawaya",
      "RIHGA Royal Hotel Osaka",
      "Refre Forum",
      "Richmond Hotel Nagoya Nayabashi",
      "Richmond Hotel Premier Asakusa International"
    ]
  }
}
```

単純にServiceクラスでターゲットを判断して、下記のクエリを実行してます。

```java
@Query("select name from Hotel h where h.name like :name% and h.deleteFlag=0")
public List<String> findHotelName(@Param("name") String name, Pageable pageable);

@Query("select distinct cityCode from Hotel h where h.cityCode like :cityCode% and h.deleteFlag=0")
public List<String> findCityCode(@Param("cityCode") String cityCode, Pageable pageable);
```
Pageable は 最大10件表示にするために引数に```new PageRequest(0, 10);```を渡してます。

## Python

PythonでAPIのレスポンスを加工して、最終的に下記のようにホテル名リストがレスポンスとして返るようにする。

```javascript
{ 
    "results": [
        "Royal Park Hotel",
        "Richmond Hotel Higashi Osaka",
        "Ryokan Mikawaya",
        "RIHGA Royal Hotel Osaka",
        "Refre Forum",
        "Richmond Hotel Nagoya Nayabashi",
        "Richmond Hotel Premier Asakusa International"
    ]
}
```
## Jinja2
```html+jinja
 <input type="text" class="form-control" id="query" name="query" value="{{data.query}}">
```

上記inputタグでオートコンプリートを実現する。

## jQuery UI

```js
$("#query").autocomplete({
    source: function(req, resp){
        $.ajax({
            url: "/hotel/auto_complete",
            type: "POST",
            cache: false,
            dataType: "json",
            data: {
                query: req.term, 
                target : $('#searchBy').val()
            },
            success: function(response){
                resp(response.result);
            },
            error: function(xhr, ts, err){
                resp(['']);
            }
        });

    }
});
```

```req.term``` はユーザが入力した文字です。

```$('#searchBy').val()``` は、検索方法のselectBoxのvalueを取得してます。

```response.result``` は、最終的にPythonから返却されるホテル名のリストです。

そのリストを```autocomplete``` の ```source: ``` に渡すと動きます。

ライブラリを使うと本当に簡単に機能追加できてしまいます。

# 確認

![20160929183928.png](https://qiita-image-store.s3.amazonaws.com/0/109149/6e58505c-b29d-b1f5-a1b7-c78bbb678943.png)


時間差もなくすぐに表示されました。
Windows 10 Pro の PowerShell で自己署名証明書(SHA-2)を作成する

Windows 10 Pro 以外で動くかどうかは知らない備忘録

```powershell:New-SelfCert.ps1 
# localhost 向け
$dns = "localhost"
# なんとなく有効期間100年
$after = (Get-Date).AddYears(100)

# 「個人」に証明書を作成
$my = "cert:\CurrentUser\My"
$cert = New-SelfSignedCertificate -DnsName $dns -CertStoreLocation $my -NotAfter $after

# cer を確保
$root = "cert:\CurrentUser\Root"
$cerfile  = "localhost.cer"
Export-Certificate -Cert $cert -FilePath $cerfile

# [信頼されたルート証明機関]に cer を登録 (直接は作れなかった)
Import-Certificate -FilePath $cerfile -CertStoreLocation $root

# pfx を確保
$pfxfile  = "localhost.pfx"
$password = "password"
$sspwd = ConvertTo-SecureString -String $password -Force -AsPlainText 
Export-PfxCertificate -Cert $cert -FilePath $pfxfile -Password $sspwd

# 最初に作成した 「個人」の証明書を削除
Remove-Item -Path ($cert.PSPath)
```
SpringBootでエラーハンドリング

# 内容

[前回](http://qiita.com/kws9/items/3a9308e8e0821fcb64e6)の、INSERT用Serviceクラスでは同じIDでリクエストを行うと、そのIDのUPDATE処理となってしまうため、既に存在するIDでリクエストがきた場合はエラーを返すように修正

## Exceptionクラス

RuntimeException を継承して、独自Exceptionクラスを生成

```java
public class DuplicateException extends RuntimeException {

	private String type;
	private Long id; 
	
}
```
## Repositoryクラス

論理削除(delete_flag=1)のレコードはSELECT時の対象外としているため、論理削除されたレコードも抽出できるようにクエリを追加

```java
    @Query(value="SELECT * FROM hotel WHERE id = :id ", nativeQuery=true)
    Hotel findHotelById(@Param("id") Long id);
```

## Serviceクラス

既にホテルIDが存在した場合は、先ほど作成したExceptionを投げるように修正

```java
    public HotelInsertResponseBody insertHotels(Hotel hotel) {
        // transform entity information as response as need
    	Hotel check = hotelRepository.findHotelById(hotel.getId());
    	if(check != null){
    		throw new DuplicateException("hotel" ,hotel.getId());
    	}
    	hotel.setRegisterDatetime(new Timestamp(System.currentTimeMillis()));
    	hotel.setRegisterPerson(Utils.API_NAME);
        Hotel res = hotelRepository.save(hotel);
        HotelInfo hotelInfo = new HotelInfo(res.getId(), res.getName(), res.getLatitude(), res.getLongitude());
        return new HotelInsertResponseBody(hotelInfo);
    }
```

## Exception Handlerクラス

`@ExceptionHandler`で、ハンドリングしたいクラスを指定します。
さらにハンドリングした際にエラーの詳細情報を作成し、エラーレスポンスとして返すようにします。


```java
    @ExceptionHandler(DuplicateException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleException(DuplicateException e) {
        log.error("Request parameter validation failed", e);
        
        String type = e.getType();
        Long id = e.getId();
        HotelError error = HotelError.DUPLICATE_ID_ERROR;
        String detailMessage = type + " id=" + id + " is already exist.";
        return createErrorResponse(
        		HttpStatus.BAD_REQUEST, 
        		error, detailMessage,
        		ErrorInfo.Type.VALIDATION );      
    }

```

## 確認

### 既存レコード　(id = 105)

```
*************************** 1. row ***************************
               id: 105
             name: HIJ Hotel
         latitude: NULL
        longitude: NULL
          address: NULL
     country_code: NULL
        city_code: NULL
            grade: NULL
         facility: NULL
       image_path: NULL
register_datetime: 2016-09-12 16:21:23
  register_person: test
  update_datetime: NULL
    update_person: NULL
      delete_flag: 1
  delete_datetime: 2016-09-12 17:15:20
    delete_person: test

```

### リクエスト

既存レコード　(id = 105)のINSERTリクエストを投げます。

```
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
  "header": {
    "countryCode": "US",
    "currencyCode": "USD",
    "languageCode": "en",
    "uid": "string",
    "userAgent": "string",
    "userIp": "string"
  },
  "body": {
    "id": 105,
    "name": "HIJ HOTEL"
  }
}' 'http://localhost:8080/hotel/insert'
```

### レスポンス

設定したエラーレスポンスが返ってくることが確認できました。

```
{
  "status": 400,
  "error": {
    "code": "HTLERR100",
    "message": "Duplicate id error",
    "type": "VALIDATION",
    "detailMessage": "hotel id=105 is already exist.",
    "invalidParameters": null
  }
}
```
胸に刻みたいExpressアンチパターン


業務でExpressを触り始めてから1年ほど経ったので、私が思う「これはヤバい」をまとめておきたいと思います。
アンチパターンなので各見出しはやっちゃいけないことです。
みなさん真似しないように。ドミナントとの約束だ。

# 「サーバサイドもクライアントサイドもJavaScriptとか超楽じゃん」という考えでNode.jsに手を出す。

そもそも論として、Expressの中でのアンチパターンというか、プラットフォームを選ぶときに **こんな考えでNode.jsを使おうとするのはヤバい** というものです。

Node.jsに手を出した人の約9割(主観)がこういう思いから始め、そしてそのほとんどが「あ、これやっぱ別物だわ」となります。
まあ確かにjsなので文法は同じなんですけどね。
どちらもnpmからライブラリを引っ張ってこれるんですけどね。
結局サーバサイドとクライアントサイドを同じノリでできるわけがないんですよ。

Node.jsがダメというわけではありませんが、クライアントサイドのJavaScriptとは分けて考えるべきです。
[Meteor](https://www.meteor.com)なんかはサーバサイドとクライアントサイドの境界がだいぶ曖昧になっているようですが、真面目に触ったことないのでよくわかりません。

# 「WebフレームワークってことはRailsとかLaravelみたいなものでしょ?」と過剰な期待を抱いちゃう

**そこまで手厚くありません。わりと突き放してきます。**

あとExpressは別にMVCのフレームワークじゃありません。MVCっぽくも使えるというだけで。
「いやいやご冗談を」と思った方はとりあえずexpress-generatorで雛形を作ってみましょう。
**Modelなんてどこにもありませんよ。**

Expressはひたすらミドルウェアを積み重ねて行くもの。


# Routerの中に処理を全てぶち込む

**やめて...やめてクレメンス...**

巷に溢れるチュートリアル程度の規模なら大丈夫なんですけどね、ちょっと処理が複雑になったら一気に破綻します。
あとRouterは単体テストしづらいです。[supertest](https://github.com/visionmedia/supertest)とか使えば無理ではないんですけど、いずれにせよ処理が複雑になってきたら別のモジュールに切り出したいところです。
古代ローマ人も「分割して統治せよ」と言っています。

# レスポンスを返したあとreturnしない

**いつから「ここで処理が終わる」と錯覚していた?**

`res.send()`とかした後も実は処理が続いてます。
一つのリクエストに対して複数のレスポンスが返ってくる、みたいなことは起きないようですが、レスポンス以外のコードは普通に実行されます。

```js:routes/users.js
const express = require('express');
const router = express.Router();

/* GET users listing. */
router.get('/', (req, res, next) => {
  res.send('respond with a resource');
  console.log("Whats!?"); // レスポンス返した後に何かしてみる
});

module.exports = router;
```

試しにexpress-generatorで生成されるルーティングに適当な処理を追加しましょう。

![スクリーンショット 2017-05-16 22.58.50.png](https://qiita-image-store.s3.amazonaws.com/0/116434/da288de4-7c52-00dc-4bbd-071e9a3356fc.png "スクリーンショット 2017-05-16 22.58.50.png")

この場合ただの`console.log`なので無害ですけど、DBにアクセスしに行く処理とかがあったら恐ろしいですね。
基本的にWebアプリにおいてレスポンス返した後に何か処理を行う必要はないかと思いますので、事故を防ぐ為にもreturnしといたほうが無難かと思います。


```js:routes/users.js
const express = require('express');
const router = express.Router();

/* GET users listing. */
router.get('/', (req, res, next) => {
  return res.send('respond with a resource'); // ここでreturnしておく
  console.log("Whats!?");
});

module.exports = router;
```

![スクリーンショット 2017-05-16 23.05.29.png](https://qiita-image-store.s3.amazonaws.com/0/116434/f33205a0-867c-5d29-4545-52d255f094e3.png "スクリーンショット 2017-05-16 23.05.29.png")

こうしておけば、レスポンスを返した後に意図せず変なことをしてしまうことは防げます。

# 本番環境でデフォルトのnpm startしちゃう

**それは縛りプレイです**

デフォルトの`npm start`の中身は`node bin/www`なので、普通にNode.jsを実行するだけです。
そしてNode.jsはシングルスレッドで動きます。

**つまりCPUを一つしか使えません。**
めっちゃハイスペックなマルチコアのCPUを積んだサーバを用意しても、デフォルトの`npm start`を使った時点で無意味になります。
「おー、Node.jsのサーバはCPU使用率があまり大きくならないなぁ」と安心していたら、実はCPUの性能を発揮できてなかっただけだったなんてこともあります。
ていうかありました。

* [Node.jsのClusterをセットアップして、処理を並列化・高速化する](http://postd.cc/setting-up-a-node-js-cluster/)
* [Node.js v7.10.0 Documentation](https://nodejs.org/api/cluster.html)

このあたりを参考にしてクラスター化しましょう。
いろいろなフォーマットの日付をDateオブジェクトに変換する

セキュリティ新着情報をつぶやくTwitterボットを作っていて困るのが、日付のフォーマットがバラバラなこと。最初は個々にちまちまgsubしてましたが、どうやらDate.parseを使うと簡単にできるようで・・。

# フォーマットの例
対象サイトでの日付は以下のような感じ。

|サイト名|日付のフォーマット|
|:-----------------|:------------------|
| [警察庁サイバー犯罪対策](https://www.npa.go.jp/cyber/)|H29.5.16|
| [警察庁 @police](https://www.npa.go.jp/cyberpolice/)|2017年05月16日|
| [内閣サイバーセキュリティセンター(NISC)](https://www.nisc.go.jp/)|2017.5.16|
| [高度情報通信ネットワーク社会推進戦略本部（ＩＴ総合戦略本部）](http://www.kantei.go.jp/jp/singi/it2/)|H29.5.16|
| [総務省 国民のための情報セキュリティサイト](http://www.soumu.go.jp/main_sosiki/joho_tsusin/security/topics.html)|2017/05/16|
| [経済産業省 情報セキュリティ政策](http://www.meti.go.jp/policy/netsecurity/)|2017年05月16日|
| [CRYPTREC](http://www.cryptrec.go.jp/topics.html)|2017/5/16|
| [日本スマートフォンセキュリティ協会(JSSEC)](https://www.jssec.org/news)|2017.5.16|
| [フィッシング対策協議会](https://www.antiphishing.jp/news/info/)|2017/05/16|
| [重要生活機器連携セキュリティ協議会(CCDS)](https://www.ccds.or.jp/)|2017.05.16|
| [日本情報経済社会推進協会（JIPDEC）](https://www.jipdec.or.jp/topics/news/index.html)|2017年05月16日|

# 対応したいフォーマット

出てきたフォーマットは以下。

- YYYY年MM月DD日
- HYY.MM.DD
- YYYY.MM.DD
- YYYY/MM/DD

今後対象サイトを増やすと以下のようなものも出てきそう。

- 全角数字での表記
- 平成YY年MM月DD日
- YY.MM.DD
- YY/MM/DD

ということで、

- H29.5.1
- 2017.5.2
- 17.5.3
- 2017/05/04
- 17/05/05
- 2017年5月6日
- 平成29年5月7日
- 平成２９年５月８日

をDateオブジェクトに変換する。

# 全角数字を半角数字に変換する
数字のみなら以下のようなtr!で簡単にできるそうで。

```Ruby
s.tr!("０-９", "0-9")
```

# 区切り文字を処理する
「.」と「/」はそのままでparseできるため、年・月・日のみ以下のように変換する。

- 年|月 => .
- 日 => 削除

# 和暦を処理する
DateクラスはJIS X 0301形式の和暦を解釈できるそうなので、「平成」を「H」に変換する。

# コードと結果
以上の処理をしてDate.parseに渡す。

コードは以下の通り[^1]。

```rb
require 'date'
samples = ["H29.5.1", "2017.5.2", "17.5.3", "2017/05/04", "17/05/05", "2017年5月6日", "平成29年5月7日", "平成２９年５月８日"]

samples.each{|sample|
	sample.tr!("０-９", "0-9")
	sample.gsub!(/年|月|日|平成/, "年" => ".", "月" => ".", "日" => "", "平成" => "H")
	p Date.parse(sample).to_s
}
```

[^1]: 最後の日付が半角数字になっていますが、コード上は全角数字です。

実行結果は以下。

```
$ ruby test.rb 
"2017-05-01"
"2017-05-02"
"2017-05-03"
"2017-05-04"
"2017-05-05"
"2017-05-06"
"2017-05-07"
"2017-05-08"
```

# 参考
- [Ruby 2.4.0 リファレンスマニュアル Dateクラス](https://docs.ruby-lang.org/ja/latest/class/Date.html)
- [全角数字を半角数字に変換するお手軽な方法](http://qiita.com/yugo-yamamoto/items/5a7a99ce84e26397e9df)
- [和暦と西暦を変換する - Ruby Tips!](http://rubytips86.hatenablog.com/entry/2014/03/26/084851)
- [政府機関等のセキュリティ関連の新着情報をつぶやくTwitterボットを公開しました - トリコロールな猫/セキュリティ](http://security.nekotricolor.com/entry/bot-for-tweeting-whats-new-related-security-on-government-sites)
SwiftでSwiftyUserDefaultsに色々なデータを入れる。

## はじめに
大したことではないのですが、よく忘れるのでメモ。

## Archiver
```swift
class Archiver: NSObject {
    // 指定のデータをアーカイブします。
    static func encrypt(rootObject: Any) -> Data {
        return NSKeyedArchiver.archivedData(withRootObject: rootObject)
    }
    
    // アーカイブデータを解凍して返します。
    static func decrypt<T>(data:Data) -> T? {
        return NSKeyedUnarchiver.unarchiveObject(with: data) as? T
    }
}
```

## SwiftyUserDefaultsにデータを入れる。
色々なデータを入れたいので以下のようなアクセッサを作る。

```swift
    static var createdAt:Hoge? {
        get {
            if let data = Defaults[.createdAt:Date] {
                return Archiver.decrypt(data: data)
            }
            return nil
        }
        set {
            if let newValue = newValue {
                Defaults[.createdAt:Date] = Archiver.encrypt(rootObject: newValue)
            } else {
                Defaults[.createdAt:Date] = nil
            }
        }
    }
```

これを使えば独自クラス(NSCoding実装済みクラス)でもSwiftyUserDefaultsに入れることができる。
Googleクラウドサービスを利用して時間指定メール送信システムを作る（その６）

***
＜[前へ](http://qiita.com/matsuhandy/items/396fb23cf5f270ea1726)＞　＜[次へ](https://qiita.com/matsuhandy/items/a481260a9fd9bc1254fc)＞
　時間指定メール送信用のインターフェースをフォームで作ります。
***
#1. Google Formでメール送信インターフェースを作成

![画像2.png](https://qiita-image-store.s3.amazonaws.com/0/146927/2f6cfb09-a62a-7d1f-496d-a926050d2320.png)

* メール送信できたので，次はフォームを利用して，時間指定メール送信用ユーザーインターフェース（UI）を作成する。ソフトウェア構成図の①をできるようにする。

1. to, subject, body, date, timeは必須，cc, bccは必須でない。
1. メールアドレスはメールアドレスのフォーマットしか受け付けないように設定する。
1. replyTo, nameについては，GAS中で決めうちするのでフォームでは入力不要。
1. 参考手順を以下に示す。

---
![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/6f2cd350-cfc1-bba7-8d20-d9f14ff468f2.png)

---
![画像2.png](https://qiita-image-store.s3.amazonaws.com/0/146927/e19a0e59-43da-2888-f277-47d8cb73430d.png)

---
![画像3.png](https://qiita-image-store.s3.amazonaws.com/0/146927/3d745a2c-5f32-d6a4-dad7-b2016a28f726.png)

---
![画像4.png](https://qiita-image-store.s3.amazonaws.com/0/146927/fe94c23c-c13c-7cd1-9f51-eae576fc2f9c.png)

---
![画像5.png](https://qiita-image-store.s3.amazonaws.com/0/146927/62ce9131-132c-b57e-6399-88c19d65f69b.png)

---
![画像6.png](https://qiita-image-store.s3.amazonaws.com/0/146927/0568cb4e-7385-d028-64fb-26e5dda2cff6.png)

---
![画像7.png](https://qiita-image-store.s3.amazonaws.com/0/146927/8307e9c0-44ef-8031-b272-e5ef595192cc.png)





---
![フォームの新規作成.png](https://qiita-image-store.s3.amazonaws.com/0/146927/528d3454-2128-b1a4-0cc9-69a9c3704b14.png)

---
![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/214d343d-fe31-7420-c1cf-a29e9ab5d0dc.png)

---
* 次のように設定すれば，メールアドレスの書式しか受け付けなくなる。ccAdr, bccAdrも同様にするが，必須にはしない。

---

![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/2e7f48c1-bb79-fe63-22ef-87819e5a6c38.png)

---
![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/492f875d-6211-a482-f433-42505b6716a1.png)

---
* プレビューをすると，完成形を見ることができる。

![画像11.png](https://qiita-image-store.s3.amazonaws.com/0/146927/c4e60ce1-d8bf-d5c4-16b1-2dafd46d11bb.png)

---
* URLを取得する。

![画像12.png](https://qiita-image-store.s3.amazonaws.com/0/146927/a649c319-eae8-4e0a-1b55-0ae8327633cc.png)

---
![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/7ebddbec-154e-2d30-c6e5-b963a4a2edcf.png)

---
![画像2.png](https://qiita-image-store.s3.amazonaws.com/0/146927/82b46574-4fe1-b264-79ba-5efcda3f390a.png)

---
* コピーしたURLは，時間指定メール送信システムにアクセスするURLなので，テキストエディタ等を使い，保存しておく。

---
![画像1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/04b15383-fbae-5723-3fdc-af76d3363d8e.png)

***
　次は，入力した内容の確認メールを入力した人に送信するGASプログラムです。ソフトウェア構成図の②と③を実現します。
＜[前へ](http://qiita.com/matsuhandy/items/396fb23cf5f270ea1726)＞　＜[次へ](https://qiita.com/matsuhandy/items/a481260a9fd9bc1254fc)＞
***
NetworkXのlayoutのdefを12個抜粋してみた

(参考)NetworkXのlayoutのdef
https://networkx.github.io/documentation/development/_modules/networkx/drawing/layout.html

```
def random_layout(G,dim=2):
def circular_layout(G, dim=2, scale=1):
def shell_layout(G,nlist=None,dim=2,scale=1):
def fruchterman_reingold_layout(G,dim=2,k=None,
                                pos=None,
                                fixed=None,
                                iterations=50,
                                weight='weight',
                                scale=1.0):
def _fruchterman_reingold(A, dim=2, k=None, pos=None, fixed=None,
                          iterations=50):
def _sparse_fruchterman_reingold(A, dim=2, k=None, pos=None, fixed=None,
                                 iterations=50):
def spectral_layout(G, dim=2, weight='weight', scale=1):
def _spectral(A, dim=2):
def _sparse_spectral(A,dim=2):
def _rescale_layout(pos,scale=1):
def setup_module(module):
def flatten(l):
```
(参考)バネ指向モデルというアルゴリズムで各ノードを見易いように配置
pos = spring_layout(G)
http://antibayesian.hateblo.jp/entry/20110828/1314491180
重ねて・ArchLinux インストール覚書

[ArchLinux インストール覚書](http://qiita.com/katz_engineer/items/f032a24cb273c4eb6669)より始めたArchLinuxプロジェクト。[も一つ・ArchLinux インストール覚書](http://qiita.com/katz_engineer/items/cc4786a8c586637eb17c)と[なお・ArchLinux インストール覚書](http://qiita.com/katz_engineer/items/8408fe4ddbd9111a5d08)でFreeNAS上のiSCSIストレージを接続しましたが、ファイルシステムをext4にしていました。これをbtrfsに変更します。

# データ用ストレージもbtrfsで

データ領域もbtrfsである方が望ましい。その根拠は[システム開発の際に用意すべき環境で触れたリハーサル環境](http://qiita.com/katz_engineer/items/4a0161459133cf2ec11d#リハーサル環境)にあります。

本番のデータをリハーサル環境に持ってくる為に最も手軽な手段。これを考えると、スナップショットが非常に便利です。仕事ならとにかく個人の趣味で立てたサーバなら、本番環境と同じマシン上にリハーサル環境を作る事も出来ますし。その場合、スナップショットを撮れば一瞬で本番データのコピーが完了します。それをマウントすれば展開する手間もかかりません。

ところがスナップショットを撮れるファイルシステムって意外と少ない。btrfsかLVMかzfsか、くらいしか選択肢が無さそうです。個人的にはzfs on Linuxに憧れるんですけど、まぁ、動かすまでちょっと面倒臭そうなのでやめときます。…と言う理由でメインのストレージもbtrfsにしましたし。btrfsかLVMかとなれば、今更LVMを選択する理由もありません。というわけでbtrfs一択。

# /iscsi を btrfs にする

## フォーマット

まだ何もデータが無いので、何も考えずに ```mkfs.btrfs``` します。ext4からの移行の実験も考えたのですが、後々何かあるとイヤなので、やめる事にしました。

```
# ls /iscsi
lost+found  test1
# mkfs.btrfs -f -L btrfs_iscsi /dev/sdc
btrfs-progs v4.10.2
See http://btrfs.wiki.kernel.org for more information.

ERROR: /dev/sdc is mounted
# umount /iscsi
# mkfs.btrfs -f -L btrfs_iscsi /dev/sdc
btrfs-progs v4.10.2
See http://btrfs.wiki.kernel.org for more information.

Detected a SSD, turning off metadata duplication.  Mkfs with -m dup if you want to force metadata duplication.
Performing full device TRIM /dev/sdc (2.00TiB) ...
Label:              btrfs_iscsi
UUID:               〈省略〉
Node size:          16384
Sector size:        4096
Filesystem size:    2.00TiB
Block group profiles:
  Data:             single            8.00MiB
  Metadata:         single            8.00MiB
  System:           single            4.00MiB
SSD detected:       yes
Incompat features:  extref, skinny-metadata
Number of devices:  1
Devices:
   ID        SIZE  PATH
    1     2.00TiB  /dev/sdc

# mount /dev/sdc /iscsi
# btrfs subvolume create /iscsi/@
Create subvolume '/iscsi/@'
# btrfs subvolume list -p /iscsi
ID 257 gen 8 parent 5 top level 5 path @
```

## /etc/fstab

ついでに、fstabでちょっと気になっていた部分も修正しました。

```
# mv /etc/fstab /etc/fstab.org
# cp /etc/fstab.org /etc/fstab
# vi /etc/fstab
# diff -sU0 /etc/fstab.org /etc/fstab
--- /etc/fstab.org      2017-04-18 23:48:11.294161494 +0900
+++ /etc/fstab  2017-05-16 21:49:36.390976057 +0900
@@ -6,2 +6,2 @@
--UUID=〈省略〉 /               btrfs           rw,relatime,space_cache,subvolid=258,subvol=/@,subvol=@ 0 0
--UUID=〈省略〉 /iscsi  ext4    _netdev,noatime,data=journal,barrier=0,nobh,errors=remount-ro   0 2
++UUID=〈省略〉 /       btrfs   rw,relatime,space_cache,subvol=@        0 0
++UUID=〈省略〉 /iscsi  btrfs   _netdev,rw,relatime,space_cache,subvol=@        0 0
# rm /etc/fstab.org
```

## リブートして確認

```
# reboot
```

ログインの後、軽く確認。

```
# mount | grep iscsi
/dev/sdc on /iscsi type btrfs (rw,relatime,ssd,space_cache,subvolid=257,subvol=/@,_netdev)
# echo hoge >/iscsi/test.txt
# ls /iscsi
test.txt
# umount /iscsi
# ls -a /iscsi
.  ..
```

やった:thumbsup:
pluckの功罪（不要なDBアクセスを避けるために）

Railsにある`.pluck`メソッドを使っていたところ、本来必要ないN+1クエリを発生させてしまいました。

# `pluck`メソッドとは
ご存じの方も多いかもしれませんが、`.pluck`メソッドは`ActiveRecord::Relation`（`where`などをかけていった結果のクラス）にあって、リレーションの条件で特定のカラムを取ってくる、というものです。

ぱっと聞けば、ふつうに`.map(&:column)`とするのとそんなに変わらないようにも思えます。

## メリット
この`.pluck`のメリットは、「モデルの生成をせず、直接特定の列だけを取ってくるSQLを投げる」ということです。余計な列の取得やActiveRecordオブジェクトの生成をすっ飛ばして、値だけを取ってくることができます。

## デメリット
ところが、この「ActiveRecordオブジェクトを介さない」 ということは、時としてデメリットに早変わりしてしまいます。というのも、モデル取得時にEager Loadをかけていた場合も、そちらには**目もくれず**、改めてSQLを投げてしまうのです。リレーションで複数オブジェクトを取得しているときに、各オブジェクトの`has_many`に対して`pluck`してしまえば、あっという間にN+1クエリの発生です。

# なんとかしてみる
`pluck`ではeager loadを無視してしまう、`map`では不要な場合にも全列取得・ActiveRecord生成をしてしまう、と都合の合わない両者ですが、`loaded?`でロード状況を見れば、自動で都合の良いほうに切り替えることも可能です。

```ruby
rel = SomeModel.some_scope(:arg)
rel.loaded? ? rel.map(&:column) : rel.pluck(:column)
```

`.mapluck`とでも名前を付けて、`ActiveRecord::Relation`に入れておいても便利かな、とちらっと思いました。

# 関連記事
* [pluckよりもmapのほうが高速なケース](http://qiita.com/metheglin/items/18064851a8f00dab67f8)
* [pluckが常に最速とは限らない](http://qiita.com/fireowl11/items/3eb33017f935e38442a1)
* [ViewでのpluckメソッドはN+1を引き起こす可能性があるので気をつける](http://qiita.com/tkm_kj/items/66b166a5b93afec6f8ad)
pkg-configのインストール方法

#1 pkg-configとは?


#2 環境
VMware Workstation 14 Player上の仮想マシンを使いました。
仮想マシンは、「最小限のインストール」->「開発ツール」を選択して作成しました。

```
[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

[root@server ~]# uname -r
3.10.0-957.el7.x86_64
```


#3 インストール方法
rpmパッケージをインストールする方法とソースをコンパイルする方法があるようです。
[ホームページ](https://www.freedesktop.org/wiki/Software/pkg-config/)をみると、gitでも提供されているようです。
ここでは、rpmパッケージのインストール、ソースのコンパイルを試してみました。
ソースからコンパイルしたpkg-configの方が版数が新しかったです(2019/5/18現在)。

##3.1 rpmパッケージをインストールする方法
baseリポジトリに入っているので、あらためてインストールする必要はないと思いますが、
インストールする場合は、以下のように実行すれば、pkgconfigパッケージを
インストールすることができます。

```console:インストール
[root@server ~]# yum install pkgconfig
```

```console:版数確認
[root@server ~]# pkg-config --version
0.27.1
```


##3.2 ソースからコンパイルする方法

```console:ファイルのダウンロード
[root@server ~]# wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.tar.gz
[root@server ~]# ls -l pkg-config-0.29.tar.gz
-rw-r--r--. 1 root root 1973875  9月 27  2015 pkg-config-0.29.tar.gz
```

```console:ファイルの解凍
[root@server ~]# tar xvf pkg-config-0.29.tar.gz
[root@server ~]# cd pkg-config-0.29
[root@server pkg-config-0.29]#
```

configureを実行する。私の環境では、--with-internal-glibオプションを付ける必要がありました。

```console:configure実行
[root@server pkg-config-0.29]# ./configure --with-internal-glib
```

```console:ファイルの確認
[root@server pkg-config-0.29]# ls -F
AUTHORS    Makefile.am   aclocal.m4     config.h.in     configure*    libtool*   parse.h                pkg.m4
COPYING    Makefile.in   check/         config.log      configure.ac  ltmain.sh  pkg-config-guide.html  pkg.m4.in
ChangeLog  NEWS          compile*       config.lt*      depcomp*      main.c     pkg-config.1           rpmvercmp.c
INSTALL    README        config.guess*  config.status*  glib/         missing*   pkg.c                  rpmvercmp.h
Makefile   README.win32  config.h       config.sub*     install-sh*   parse.c    pkg.h                  stamp-h1
```

```console:コンパイル
[root@server pkg-config-0.29]# make
```

```console:インストール
[root@server pkg-config-0.29]# make install
```

```console:版数確認
[root@server pkg-config-0.29]# /usr/local/bin/pkg-config --version
0.29
```


#Z 参考情報
[pkg-configに対応する](http://ultraist.hatenablog.com/entry/20070624/pkgconfig)
[pkg-config のインストール](http://www.bnote.net/linux/pkg_config.shtml)
clickイベント　基本メモV2

```js
$(function(){
navi();

function navi(){

	let click_hon = $(".hongkong_acco");
	let click_tait = $(".taiwan_acco");
	let navianime = {
		change_hon : $(".header .menu-contents .hongkong_acco .navi-title"),
		change_tai : $(".header .menu-contents .taiwan_acco .navi-title"),
		tai_acco:$("ul.taiwan_active"),
		hon_acco:$("ul.hongkong_active"),
		play_hon : function(){
			if(this.hon_acco.css("display") == "none"){
				this.change_hon.addClass("js_open");
				this.hon_acco.stop().slideDown(500, "easeOutCirc");
			} else {
				this.change_hon.removeClass("js_open");
				this.hon_acco.stop().slideUp();
			}
		},
		play_tai : function(){
			if(this.tai_acco.css("display") == "none"){
				this.change_tai.addClass("js_open");
				this.tai_acco.stop().slideDown(500, "easeOutCirc");
			} else {
				this.change_tai.removeClass("js_open");
				this.tai_acco.stop().slideUp();
			}
		},
	}
	click_hon.click(function(){
	  navianime.play_hon();
	});
	click_tait.click(function(){
	  navianime.play_tai();
	});
};


});
```
Scratchで体験するゲームプログラミングのための物理シミュレーション2 (中高生向け)

# URL

https://goo.gl/OVdsnu

---

# 今日の目標

- ジャンプ・落下の運動をリアルに再現してみよう
- ゲームプログラミングでの利用例: ["ペンギンの冒険"](https://scratch.mit.edu/projects/156975201/#player)

![スクリーンショット 2017-05-16 22.21.05.png](https://qiita-image-store.s3.amazonaws.com/0/155441/d9359676-03ad-df16-d99e-045c2964cea0.png)

---

# やってみよう(1)

- 自分の好きなキャラクターを選ぶ。
- キャラクターの大きさなどを調整。
- キャラクターが上方向に動くだけのプログラムを作ってみよう。

---

# やってみよう(2)

- キャラクターが上方向に加速しながら動くプログラムを作ってみよう。
- ヒント: 「速さ」を表す変数を用意する。

---

# やってみよう(3)

- 上のプログラムを改良して、キャラクターがジャンプし、落下してくるプログラムを作ってみよう。
- ヒント: 
  - 「速さ」を表す変数を、はじめは0より大きな値にして、一定のスピードで小さくしていく。
  - 「速さ」のはじめの値や、小さくするスピードは、自分で試して調整してみよう。

---

# やってみよう(4)

- 上のプログラムを改良して、落下してきたキャラクターがちょうどいい位置で止まるプログラムにしてみよう。

---

# やってみよう(5)

- キーボード上のキーを押すことで、キャラクターをジャンプさせるように、プログラムを改良してみよう。
- ヒント:
  - キーが押されたときに、「速さ」の値を増やすようにする。
  - 「速さ」の値をどれくらい増やせばいいかは、自分で試して調整しよう。
  - プログラムを上手く作らないと、「ちょうどいい位置」で止まった後、ジャンプできなくなってしまう。どうすればいいか考えてみよう。
- [プログラム例](https://scratch.mit.edu/projects/161432099/)

---

# チャレンジ(1)

- 上のプログラムを改良して、"ペンギンの冒険"のようなゲームを作りたい。
- 画面右側のランダムな位置に風船が次々と出現し、左側に向けて流れてくるプログラムを書いてみよう。
- 風船が画面左端についたら、消えるようにしておこう。
- [プログラム例](https://scratch.mit.edu/projects/161435492/)

---

# チャレンジ(2)

- 画面左上に「残りの時間」と「点数」という二つの変数を表示させよう。
- 「残りの時間」は1秒ごとに少なくなるようにし、「点数」はキャラクターが風船に触れたら1増やす。
- 「残り時間」が0になったら、ゲームが終了する。
- キャラクターが風船に触れたら、風船が消えるようにしておこう(消える前に簡単なアニメーションがあると分かりやすい)。

---

# チャレンジ(3)

- キャラクターが上下だけでなく、キーボード操作で左右にも動けるようにしてみよう。
- 風船がただ左方向に動くのではなく、ランダムに上下に揺れるようにしてみよう。
- ジャンプしたときと、風船が割れたときに、効果音をつけてみよう。