OmniAICreator/Qiita-1.07M huggingface dataset:
JDK9のマイグレーションガイドを読む_001

少し気になる部分があるので読んでみたい。
[原文_JDK9マイグレーションガイド](https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-7744EF96-5899-4FB2-B34E-86D49B2E89B6)

The purpose of this guide is to help you identify potential issues and give you suggestions on how to proceed as you migrate your existing Java application to JDK 9.

この文章は、Java言語が8→9にバージョンアップすることにより、仕様変更で挙動が変わった箇所を記載します。同作業を実施する際に役立ててください。

Every new Java SE release introduces some binary, source, and behavioral incompatibilities with previous releases. The modularization of the Java SE Platform brings many benefits, but also many changes. Code that uses only official Java SE Platform APIs and supported JDK-specific APIs should continue to work without change. Code that uses JDK-internal APIs should continue to run but should be migrated to use external APIs.

Java言語はバージョンの下位互換性を保証していますが、いくつかの機能で非互換となっているものがあります。たとえば9ではモジュール化という機能を追加しましたが、非常に多くのソースコードを修正しています。互換性の考え方としては、JREのランタイムに内包されるAPI、JDKのうちサポートを明言しているAPIのみを利用するコードはJava9と、下位バージョンで差異がないはずです。主に修正が必要なのはサードパーティのライブラリ、サポート対象外のAPIです。
### New Version-String Scheme
JDK 9 provides a new simplified version-string format. If your code relies on the version-string format to distinguish major, minor, security, and patch update releases, then you may need to update it.

Java言語ではバージョン文字列の形が新しくなっています。もしプログラムから言語のバージョン文字列の形からメジャーバージョン値、マイナーバージョン値、セキュリティパッチバージョン値をを取得して分岐する処理などは修正が必要になります。

The format of the new version-string is:
新しいバージョンのフォーマットは以下です

```
$MAJOR.$MINOR.$SECURITY.$PATCH
```

For example, under the old scheme, the Java 9u5 security release would have the version string 1.9.0_5-b20.

例を挙げると、下位バージョンの文字列は↑のような形でした。

Under the new scheme, the short version of the same release is 9.0.1, and the long version is 9.0.1+20.

新しいバージョンの文字列は↑のような形となります。

This change affects java -version and related system properties, such as java.runtime.version, java.vm.version, java.specification.version, and java.vm.specification.version.

この変更は、上記のコマンドやAPIの出力内容に影響あります。

A simple Java API to parse, validate, and compare version strings has been added. See java.lang.Runtime.Version.

毎度バージョン更新時に問題が出ないよう、より単純な形でバージョンを取得できるJava APIを作成しました。

See Version String Format in Java Platform, Standard Edition Installation Guide, and JEP 223: New Version-String Scheme.

詳細はドキュメントに記載しているので、そちらを参照してください。
[JEP 223: New Version-String Scheme](http://openjdk.java.net/jeps/223)


今日はここまで。後日追記します。
GradleでJUnit Testをフィルタ実行する方法

## `--tests`オプション

以下のようにして対象のテストクラス(`HogeTest`)を指定できる

```
./gradlew test --tests com.example.HogeTest
```

メソッドまで指定することも可能

```
./gradlew test --tests com.example.HogeTest.fooMethodTest
```

ワイルドカード(`*`)を利用して複数のテストを指定することもできる

```
./gradlew test --tests com.example.\*Test
```

このオプションは「実行するテスト」は指定できるが、「実行しないテスト」を指定することはできない。
`-Dtest.single` というオプションもあるが、`--tests`で代替可能。


## `include`/`exclude`関数

テスト対象に包含/除外するテストを指定できる

```groovy
test {
    include 'com/example/HogeTest.class'
    exclude '**/*Foo*'
}
```

`--tests`とは異なり、`.class`ファイルへのパスを指定する。

## Test Grouping

`build.gradle`に記述することで、特定のカテゴリに属するテストを包含/除外することができる

```groovy
test {
    useJUnit {
        includeCategories 'com.example.CategoryA'
        excludeCategories 'com.example.CategoryB', 'com.example.CategoryC'
    }
}
```

カテゴリはInterfaceとして作成し、`@Category`アノテーションを通じて指定する

```kotlin
interface MyCategory

@Category(MyCategory::class)
class HogeTest {
    // some tests...
}
```

ちなみにこれを使うと、`@RunWith(JUnitRunner::class)`を指定したテストが認識されなくなった（謎）。

## おまけ：Androidでの設定

Androidでは`build.gradle`の以下のブロックに設定を記述する

```groovy
android {
    unitTests.all {
        // here
    }
}
```

## 参考

- https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_test 
- https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html
- https://github.com/junit-team/junit4/wiki/Categories
Unity.iOS.DeviceGenerationとその2017年秋のアップデートについて

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ゆるぼ<br>Unityの列挙型　iOS.DeviceGenerationに対して新しいモデルが追加されるタイミング<br><br>いつもはマイナーリリースで追加されるんです？それともメンテナンスリリースやパッチリリースでも追加されます？<a href="https://t.co/lls25a9rEU">https://t.co/lls25a9rEU</a></p>&mdash; むろほし (@RyotaMurohoshi) <a href="https://twitter.com/RyotaMurohoshi/status/907891199872135168?ref_src=twsrc%5Etfw">2017年9月13日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

　Unity 5から、[UnityEngine.iOS.Device](https://docs.unity3d.com/500/Documentation/ScriptReference/iOS.Device.html)というクラスが加わりました。このクラスには、次のような情報をつかさどるstaticなプロパティが定義されています。

* advertisingIdentifier・・・広告ID
* advertisingTrackingEnabled・・・広告IDのトラッキング可否
* systemVersion・・・iOSのバージョン
* vendorIdentifier・・・ベンダーID
* generation・・・Device種別

　Device種別をつかさどるgenerationプロパティは、UnityEngine.iOS.DeviceGeneration列挙型です。

　この列挙型には、iPhone3Gとか、iPhone5とか、iPhone6Sとか、iPadAir1のような、iOS端末の種別が列挙型の要素として定義されています。

　ところで2017年秋に、iPhone8、iPhone8Plus、iPhone Xがリリースされました。これら端末のDeviceGenerationの要素はいつ追加されるのでしょうか？

Unity Technologies Japan公式のナレッジベースの「[2017 年の新 iPhone (iPhone8/8Plus/X) への対応状況](https://helpdesk.unity3d.co.jp/hc/ja/articles/115012920507-2017-%E5%B9%B4%E3%81%AE%E6%96%B0-iPhone-iPhone8-8Plus-X-%E3%81%B8%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81)」によると、

* 5.5.X
* 5.6.X
* Unity2017.x

　上記のUnityでは、2017年10月中旬のパッチリリースで追加されるそうです。Unity 5.5以前には追加されないようです。ある程度前のUnityにもサポート中であれば、UnityEngine.iOS.DeviceGenerationが追加されるのですね。

　（けれど、Deviceによる挙動違いのコードとか書きたくないorz）

# 要素の追加履歴

　関連してUnityのドキュメント差分による追加履歴を示します。もしかしたら、パッチリリースなどでドキュメントには追加されていないけど要素としては追加されているかもしれません。

　Unity5.0のドキュメントは[こちら](https://docs.unity3d.com/500/Documentation/ScriptReference/iOS.DeviceGeneration.html)。

　Unity5.1のドキュメントは[こちら](https://docs.unity3d.com/510/Documentation/ScriptReference/iOS.DeviceGeneration.html)。Unity5.0との差はないようです。

　Unity5.2のドキュメントは[こちら](https://docs.unity3d.com/520/Documentation/ScriptReference/iOS.DeviceGeneration.html)。次の要素が増えています。

* iPhone6S
* iPhone6SPlus
* iPadPro1Gen
* iPadMini4Gen

　Unity5.3のドキュメントは[こちら](https://docs.unity3d.com/530/Documentation/ScriptReference/iOS.DeviceGeneration.html)。次の要素が増えています。

* iPhoneSE1Gen
* iPadPro10Inch1Gen

　Unity5.4のドキュメントは[こちら](https://docs.unity3d.com/540/Documentation/ScriptReference/iOS.DeviceGeneration.html)。次の要素が増えています。

* iPhone7
* iPhone7Plus

　Unity5.5のドキュメントは[こちら](https://docs.unity3d.com/550/Documentation/ScriptReference/iOS.DeviceGeneration.html)。次の要素が増えています。

* iPodTouch6Gen

　Unity5.6のドキュメントは[こちら](https://docs.unity3d.com/550/Documentation/ScriptReference/iOS.DeviceGeneration.html)。次の要素が増えています。

* iPad5Gen
csv のデータが重複してるよ〜 -> それ、pandas で除けまっせ

# こんなこと起きた

csv を DB に入れようと思ったけど、primary key がダブリまくってる！
重複してる行を削除したいけど、excel で開けないほど重い・・・。
python でデータ処理しようかな・・・でも、たまには違う方法でやりたい・・・。

**せや、pandas 使ったろ**


# 環境整備

はしょります(^o^)
[Macにanacondaをインストールする→ライブラリの追加](https://qiita.com/berry-clione/items/24fb5d97e4c458c0fc28) などを見てください。
anaconda を入れた後で jupyter を起動すると、
pandas を使うときに、途中経過などが見やすくて便利です。


# こうするんじゃ！

まずは pandas を import して、csv を読み込む！

```py3
import pandas as pd
hoge = pd.read_csv('hoge.csv')
```

date にしたければ、parse_dates を使ってみたり、
column に名前つけたければ names 使ってみたり、
型指定したければ dtype を使ってみたりしてください。

```py3
hoge = pd.read_csv("hoge.csv",
                   parse_dates=[1],  # 対象のカラムインデックス
                   names=['hoge', 'fuga', 'hage'],
                   dtype={2: str}  # カラムインデックスと型の dict
                   )
```

次に重複を削除するために、先にソートします。
ソートしておくと、先にヒットするものを残すという処理が使えるようになるので、
残したい行が上に来るようにソートします。

```py3
sorted_hoge = hoge.sort_values(['hoge', 'fuga'],  # カラム名
                               ascending=[1, 0])  # desc か asc か
```

そして削除！

```py3
no_duplicated_hoge = sorted_hoge.drop_duplicates('hoge',  # このカラムで重複していると、
                                                 keep='first')  # 最初を残すようにする
```

最後に csv に書き込みましょう。

```py3
no_duplicated_hoge.to_csv('result.csv', 
                          index=False,  # 0, 1, 2... みたいなデータは要らないので削除 
                          date_format='%Y%m%d')  # 日付データがある場合は、これで変換可
```


# 結果

全然大したことしてないんですけど、
ささっと jupyter 起動して、ちゃかちゃか pandas 使うと、
「なんか俺凄いじゃん？」って気分になれるのでおすすめです。


## おまけ（jupyter で使った、その他メソッド）

jupyter で途中経過を表示するために、`head()` というメソッド使うと良いと思います。
重複具合を調べたければ `value_counts()`。
データの加工は、例えば行追加は `loc()`、中の文字列を置換したければ `replace()` とかあって、とても便利です。

「python で `import csv` して、`with open()` で `reader = csv.reader(f)`、`for line in reader` して...」に飽きたら、
jupyter + pandas に挑戦すると良いと思います！
なかなかうまく行かなかったCharlesの初期設定をメモ

環境
Mac OS X 10.11.6 (EL Capitan)



Map Localを使いたかったが、反応してくれない

ログも出ない
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/eaa5b77c-efce-b7c6-cc24-ecb5cfdc6d9c.png)

困ったので以下を設定したら、動いた
根本原因は不明なままだが・・・

## Charlesの設定

### SSL証明書のインストール

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/925aad64-7622-dc8a-c91e-020f75bff773.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52847/b018f585-7f3c-4c37-9744-b2e8b572da53.png)


### Proxy Settings

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/ea1a57d6-f212-bb82-6a7b-80a02da5bb73.png)

### SSL Proxy Settings

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/ca87fafc-207a-2539-048d-382b89069337.png)


Mac OS Proxy
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/a2418c4c-abab-3d43-d3b9-079addd19c19.png)


## Macの設定

### ネットワーク > Wifi > 詳細 > プロキシ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/7ef1bc2e-831c-a21a-fc1d-f324b0e39e6c.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/52847/57030907-9497-29c0-2e5c-a01807ea86ce.png)
Javaのお勉強#6(ブロックの書き方)

お久しぶりです、休日は遊び歩いていたので今日から引き締めて再開していきます！
## ブロックの書き方
ブロックとは
ブロックとは複数の文をひとまとまりとして扱うためのもの。

### ブロックを扱う上での２つのルールの存在
**ルール(1)**
**波カッコの省略**
内容が一行しかない場合、波カッコを省略しても構わない

```java
if (tenki == true){
//略
} else
System.out.println("RIDLEYの技術は世界イチｨｲｲｲｲｲ");
```

ただ、実際にはプログラムミスを防止する為に、推奨はされていない。
**ルール(2)**
**ブロック内で宣言した変数の寿命**
ブロック内で宣言した変数は、そのブロックが終わると同時に消滅する。
例えばif文のブロックないで宣言した変数はそのブロックの外側で利用できない。
このように"変数が利用可能な場所の範囲"のことをスコープ(scope)という。

```java
int a;
while(/*条件式*/){
 int b;
 //変数bのスコープ
}
 //変数aのスコープ
```

## 条件式の書き方
- 条件式とは?
条件式とはif文やwhile文のような処理を分岐する条件や繰り返しを続ける条件を表現するためのもの

```java
if (tenki == true ){ //if文条件式

while(age > 21 ){ //while文条件式

```
ここで出てくる"==",">"は関係演算子と呼ばれる。
## 関係演算子

|演算子|意味|
|:--:|:--:|
|==|左辺と右辺が等しい|
|!=|左辺と右辺が異なる|
|>|左辺が右辺より大きい|
|<|左辺が右辺より小さい|
|>=|左辺が右辺より大きいか等しい|
|<=|左辺が右辺より小さいか等しい|

例
`sw != false` 変数swがfalseでなかったら
`deg - 273.15 < 0`変数degから273.15を引いたものが0未満なら
`initial == '宮'` 変数initialに入ってる文字が"宮"だったら

**等しいを表す関係演算子はイコールが2つ"=="**であることに注意すること

## 文字列の比較
Javaでは条件式の中でString型の変数や、文字列を比較する際**特別な書き方**をする必要がある。

```java
if (s == "夕日"){ //間違い
```

一見正しいように見えるものの、Javaでは文字列の比較は"=="ではできないことになっている。
正しい記法は

```java
if (s.equals("夕日")){
```
となる。

## 論理演算子
- 論理演算子(〇〇以上、かつ〇〇のような２つ以上の条件を組み合わせた複雑な条件式)

|演算子|意味|
|:--:|:--:|
|&&|かつ|
| ‖ |または|

- 使用例

```java
if (age >= 10 && gender == 1) {･･･
if (name.equals("空条") || married == true {･･･
```

## 雑談
とりあえず今日はここまでで･･･
なんとかブロックの書き方に関してはわかったような気がしています。
文字列の比較は書き方の違いに気をつけていこうと思います。
過去に出てきたこともありますが、覚える事が大変です(つд⊂)
2日ほど空けてしまっていたので、遅れを取り戻さねば…！
また明日も頑張ります！おやすみなさいzzz
Revealjsで外部サービスを使わずにプレゼンを音声で操作する

# 元ネタ
teratailさんとIBMさんから「[Angular + Watson でプレゼンスライドを奇妙な冒険にしよう！](https://www.ibm.com/developerworks/jp/cloud/library/angular/)」という記事が公開されていたよ。プレゼン内にてWatsonで音声認識をして、特定ワードに反応して「ド・ド・ド・ド」エフェクトを表示するみたいだ。クイズ王にも勝っちゃうWatsonをスライドにつかっちゃうなんて贅沢なプレゼンだー！すてきだね！

[![引用画像](https://public.dhe.ibm.com/software/dw/jp/cloud/angular/jojo.gif "Angular + Watson でプレゼンスライドを奇妙な冒険にしよう！")](https://public.dhe.ibm.com/software/dw/jp/cloud/angular/jojo.gif)

# やりたいこと
でも、Watsonはネットにつながないと使えないから、発表時にネットワークが弱いと怖いよね。それにWatsonさんを使うのにアカウントを作ったりとか多少手間がかかるね。
そこで、Web Speech APIの出番だ。Web Speech APIのSpeech Recognition APIを使うと、ブラウザの機能としてローカルで音声認識ができるよ。また、Reveal.jsをつかうとブラウザでプレゼンができるので、この２つを使えばteratail×IBMさんと同じことができそうだ。Web Speech APIの[ブラウザ対応状況](http://caniuse.com/#search=Speech%20Recognition%20API)は芳しくないけど、プレゼン用途ならブラウザも自分で選べるから問題なし！

<img src="https://qiita-image-store.s3.amazonaws.com/0/160451/98f68a0d-3d0f-22e6-a977-4f88cb3137c8.gif" width=70%>

# やりかた
Web Speech APIはHTTPSまたはローカルのWebサーバからでないと使えないからハードルが高いと思われがちだけど、Reveal.jsならばローカルからの配信（grunt serve)なので、最初にマイクの許可さえOKすればすぐに使えるんだ。
ただ、そのまま使うと、一度音声を認識後に停止してしまうので、こちらの「[Jellyware: Web Speech APIで途切れない音声認識](http://jellyware.jp/kurage/iot/webspeechapi.html)」にあるように、録音が止まるたびに音声認識を再実行してあげよう。
また、Reveal.jsのスライドの操作は`Reveal.next()`や`Reveal.slide()`でできるよ。[API一覧](https://github.com/hakimel/reveal.js/#api)をみて音声認識の結果に応じて呼び出してあげよう。
音声認識＋スライド操作の部分は先ほどの「[Jellyware: Web Speech APIで途切れない音声認識](http://jellyware.jp/kurage/iot/webspeechapi.html)」にあるソースコードほぼそのままで使えるよ。
上のGIF画像の例では、「スライド」「前」「後」という言葉に反応したページ移動と、「ざわ」という言葉に反応したエフェクトを実装しているよ。

```js
recognition.onresult = function(event) {
  var results = event.results;
  for (var i = event.resultIndex; i < results.length; i++) {
    if (results[i].isFinal) {

 　　　// ここにキーワードチェックを追加したよ
      let script = results[i][0].transcript;
      if (script.match(/スライド/)) {
        if (script.match(/次/)) {
           Reveal.next();
        } else if (script.match(/前/)){
           Reveal.prev();
        } 
```

Web Recognition API、はじめて使ってみたけど認識率もそれなりに良くいろいろ使えそうだ。「ゴールデンカムイ」もしっかり認識したよ。
音声認識のクラウドサービスはいろいろあるけど、簡単な処理ならばぜひWeb Recognition APIを使ってみよう:blush:
Ruby 命名規則まとめ

別言語からRubyに来た人にとって、最初に引っかかるポイントである言語の慣用について、今回はRubyらしくあるために、Rubyの命名規則をまとめてみました。

## クラス名、モジュール名
**キャメルケース(CamelCase)**：各単語の頭文字を大文字にする、`_`は使用しない。
ただし、`HTML`や`FTP`などの略語はすべて大文字にします。

```ruby
# NG
Foo_Class
barmodule
bazClass
ApiServer

# OK
FooClass
BarModule
BazClass
APIServer
```

## ファイル名、ディレクトリ名
**スネークケース(snake_cace)**：すべてを小文字にし、単語の区切りを`_`で繋ぐ

そして、ファイル名にはクラス名やモジュール名をスネークケースに変更した名前を使用し、ディレクトリ名にはモジュールの名前空間をスネークケースに変更した名前を使用します。

```ruby
class FooClass
end

# ファイル名はスネークケース 
foo_class.rb
```

```ruby
module HogeHoge
  module Foo
    class Bar
    end
  end
end

# ディレクトリ構造は名前空間と対応させる
hoge_hoge/foo/bar.rb
```

## メソッド名、変数名
**スネークケース(snake_cace)**：すべてを小文字にし、単語の区切りを`_`で繋ぐ

```ruby
# NG
Foomethod
barMethod

# OK
foo_method
bar_method
```
## 定数名
**スクリーミングスネークケース(SCREAMING_SNAKE_CASE)**：すべてを大文字にし、単語の区切りを`_`で繋ぐ

```ruby
# NG
Max_Size

# OK
MAX_SIZE
```

## 返り値が真偽値のメソッド
真偽を返すメソッドであれば最後に`?`を付与します。冗長になるためメソッドの先頭に`is`や`does`、また`can`などの助動詞を置かないようにします。

```ruby
# NG
class MotocrossGP
  def is_fast_rider?
    true
  end
end

# OK
class MotocrossGP
  def fast_rider?
    true
  end
end
```

## 破壊的なメソッド
selfや引数を変更するようなメソッドは最後に`!`を付与します。また可能であれば破壊的メソッドに対応する非破壊的なメソッドも用意します。

```ruby
# NG
def update!
end

# OK
def update # 可能であれば非破壊的なメソッドも用意する
end

def update!
end
```

## 参考
https://shugo.net/ruby-codeconv/codeconv.html
https://techracho.bpsinc.jp/hachi8833/2017_02_13/35364
dockerでbuildしたら"Empty continuation lines will become errors in a future release"って言われた

# はじめに
docker for macにアップデートがきたので17.09.0-ceにupdateして作業を再開(build)したら急にWarningが出て焦りました。

```
[WARNING]: Empty continuation line found in:
...
[WARNING]: Empty continuation lines will become errors in a future release.
```

# いったい何があったのか
ChangeLogを追ってみたところ、[17.07.0-ce](https://github.com/docker/docker-ce/releases/tag/v17.07.0-ce)で[こんな修正(Issue)](https://github.com/moby/moby/pull/33719)があったようです。

```
-			// TODO: warn this is being deprecated/removed
  			if isEmptyContinuationLine(bytesRead) {
+				hasEmptyContinuationLine = true
 				continue
  			}
```
要は今までスルーされていた空行はスルーするんじゃなくて警告するようにした模様。
本来この修正で警告を出したかったのは、

```
RUN apt-get update -y && \
    (空行)
    apt-get upgrade -y && \
    ...
```
などのように、空行に対する警告なのですが、
ここで判定に使われている`isEmptyCOntinuationLine(...)`関数(以前から存在)は

```
func isEmptyContinuationLine(line []byte) bool {
	return len(trimComments(trimWhitespace(line))) == 0
}
```
という実装で、`# install xxxx`などのコメントは長さ0として扱います。
そのため、今までは

```
RUN apt-get update -y && apt-get upgrade -y && \
    apt-get install -y vim git curl wget \
                       make g++ python libkrb5-dev && \
    # install nodejs(dependency: 6.x)
    curl -sL https://deb.nodesource.com/setup_6.x | bash - && \
    apt-get install -y nodejs && \
    ...
```
などのようにコメントを途中にはさみながら書いていた部分に対して警告が行われるようになったということでした。

# おわりに
警告は消しておきたい派の筆者はとりあえずコメントを消して事なきを得ましたが、
その代わりに分かりにくい部分の補足をしてくれていたコメントとさよならすることになりました。
こんなときどんな風にするのが良いのでしょう。。
CentOS6にGitbucket4.16.0をインストールする

Gitbucket４．１６．０をインストールした際に起動できなくてハマったのでここに残します
同じ様に起動出来無い方の助けになればと思います。


#環境
 CentOS6.9
 apache2.2系

#実装手順
下記サイトを参考に実装しました。
http://blog.ligun.net/2014/05/gitbucket_install
tomcat以外に関しては上記サイトの手順通りで問題ないのですが
tomcat7ではGitbucket4.9までしか動作しないのでtomcat8以降が必要です。
tomcat8はyumにはまだ無いのでwgetでDLします。
任意のディレクトリにDL後解凍してユーザーとグループをtomcatに変更します。
$wget　http://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz
$tar xvzf apache-tomcat-8.5.20.tar.gz
$chown tomcat:tomcat -R /解凍したディレクトリ

webappsディレクトリにGitbucketをDLします。
$cd apache-tomcat- 8.5.20/webapps

binディレクトリに移動してtomcatを起動
$cd apache-tomcat-8.5.20/bin
$./ startup.sh

http://サーバーのIPアドレス:8080/gitbucket/
にアクセスしてくださいGitbucketが表示されるはずです。
お疲れ様でした。
uDesktopDuplicationを使ってVR空間に仮想ディスプレイをつくった

##概要
凹みさんが配布している[uDesktopDuplication](https://github.com/hecomi/uDesktopDuplication)を使ってUnityで作成したVR空間に仮想ディスプレイを表示した。

##はじめに
「VR空間で作業をしたい」
そう思ってVRワークスペースを作り始めました。
Unity素人が右往左往しながらゆっくり作成しています。
今回はPCワークには欠かせないデスクトップを表示する仮想ディスプレイの実装を紹介します。

##使用したもの
- Unity 5
- [uDesktopDuplication](https://github.com/hecomi/uDesktopDuplication) v1.5.1

##uDesktopDuplicationのダウンロードとインポート
今回は一からの実装が難しかったので凹みさんが配布されているuDesktopDuplicationを使用させていただきました。

[こちら](https://github.com/hecomi/uDesktopDuplication/releases)から**uDesktopDuplication-v1.5.1.unitypackage**をダウンロードします。 
※この記事の更新時(2019年4月19日)には最新版としてv1.6.0が公開されています。

ダウンロードしたパッケージファイルを作成中のunityの画面にドラッグ&ドロップさせます。
以下のような表示が出るので**Import**を選択します。

![import画面.png](https://qiita-image-store.s3.amazonaws.com/0/203750/77b7b61f-1272-c95a-1e78-75fec835bcbd.png)

これで必要なファイルがいろいろインポートされたと思います。

![files.png](https://qiita-image-store.s3.amazonaws.com/0/203750/0b64d0a8-3660-497d-2a34-e3b305b7a7ab.png)

##VR空間に仮想ディスプレイを表示させる
先ほどインポートされたファイルたちの中から**Examples>Prefabs**の順に開きます。
ここにあるファイルが例として用意してある仮想ディスプレイのオブジェクトです。

### Monitor Board 
メインディスプレイの画面を平面状に表示したディスプレイ

![normal.png](https://qiita-image-store.s3.amazonaws.com/0/203750/0f2f7c38-2dbe-265b-8d92-fd51b110f78b.png)

### Monitor Plane for Displacement Mapping
少し弧を描くように曲がったディスプレイ

![cave.png](https://qiita-image-store.s3.amazonaws.com/0/203750/6f1a8568-fefd-6ce8-c371-3687890147e7.png)

使いたいディスプレイのファイルをUnityのHierarchyにドラック&ドロップさせます。
ちなみに私はMonitor Boardを採用しました。
これでVR空間に仮想ディスプレイが表示されたと思います。

##おわり
まだUnity初心者ということもあって今回は用意していただいたサンプルで実装しました。
うまく使いこなせば平面形状のディスプレイだけでなく、球や立方体のディスプレイも作成できそうですね。

今後ともVRワークスペース作成の投稿をするつもりです。
良かったらまた覗いてみて下さい。

[2019/4/19]
同じ製作者の方がWindowsのウィンドウをキャプチャするAssetも配布されています。
用途に合わせて使い分けるといいかと思います-> [uWindowCapture](http://tips.hecomi.com/entry/2018/08/26/231618)

##参考
- [uDesktopDuplication](https://github.com/hecomi/uDesktopDuplication)
- [uDesktopDuplication ダウンロードページ](https://github.com/hecomi/uDesktopDuplication/releases)
Slack上でタイムレコーダーをするbot作った。

# なぜやったか
複数のプロジェクトにまたがると、工数管理が大変なので、
Slack上でbotに管理してもらうことにしました。

# 何をしたか
こちらを参考にさせて頂きました。

[Slackにハッシュタグ的な「ゆるく情報をまとめる方法」が欲しかった話](http://tech.connehito.com/entry/2016/05/17/170626)

[Slackでらくらく工数管理](http://blog.serverworks.co.jp/tech/2015/12/16/slack-de-manhour/)


* `#___` のPrefixを付けたタスクを登録すると、botがそれを待ち受けてオウム返しします。

* `@botの名前 集計して` と入力するとbotが発言した履歴から時間を計算して返します。

* 同じタスク名は合算します。

<img width="305" alt="スクリーンショット 2017-10-02 22.16.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/190454/bc85a963-f5b3-f067-d14c-efa5c826a866.png">



# どうやったか

* botのFrameWorkは`Hubot` 
* 名前は`pigbot` 
* お家は`Heroku`  
* 時間管理用のチャンネルを作成しました。 
* APIに必要な情報は環境変数で渡しました。 

## SlackとHubotの連携
[こちら](https://qiita.com/chibi929/items/79161111dee411000411)を参考にさせて頂きました。

## 履歴を取得するSlackAPI
[channels.history](https://api.slack.com/methods/channels.history)

## コード 

* Prefixを待ち受ける所  

```coffeescript: 
robot.hear /#___/, (msg) ->  
   msg.send msg.message.text 
```

* 時間を集計する所  

```coffeescript:
robot.respond /集計して/i, (msg) ->
    today = new Date()
    oldestMilliSec = new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime() / 1000
    # 当日０時以降の履歴のみ取得する。
    request = msg.http('https://slack.com/api/channels.history')
                  .query(token: process.env.HUBOT_SLACK_TOKEN, channel:process.env.CHANNEL_ID, oldest:oldestMilliSec)
                  .post()    
                  
    request (err, res, body) ->
      json = JSON.parse body
      contents = json.messages
                .filter((v) -> v.user == process.env.USER_ID)
                .filter((z) -> z.text.startsWith("#___"))
                .reverse()
        
      if contents.length == 0
         msg.send "ないやで"
         return

      formatTime = (seconds) ->
        result = ''
        #時間計算
        hour = Math.floor(seconds / 60 / 60)
        min = Math.floor(seconds / 60 % 60)
        sec = Math.floor(seconds % 60)
        #フォーマット
        if hour > 0
          result += hour + '時'
        if min > 0
          result += min + '分'
        if sec > 0
          result += sec + '秒'
        result  

      tasks = contents.map((val,i)->
        if i == contents.length-1
          obj = {}
          task = val.text.slice(4)
          cost = (Date.now()/ 1000 - val.ts)
          obj[task] = cost
          return obj

        if (i + 1 < contents.length)
          obj = {}          
          task = val.text.slice(4)
          cost = (contents[i+1].ts - val.ts)
          obj[task] = cost 
          return obj         
      )
```


* 同じタスク名の時間を合算する所  


```coffeescript:
resultList = []

      hasSameTask = (list,taskName,result) ->
        if list.length == 0
          return false
        for obj in list
          taskInList = Object.keys(obj)[0]
          if taskName == taskInList
            obj[taskInList] += result[taskName]
            return true
        return false

      for result in tasks
        task = Object.keys(result)[0]

        if not hasSameTask(resultList, task, result)
          resultList.push(result)

```

# 感想
botかわいい🐷
色んなAPI用意されているので、工夫して使ったらより捗りそうだと思いました。
[Rails]フォームで入力した値を計算して別の値をデータベースに入れる

# やりたいこと
- 身長体重カラムを持った**人**モデルがあるとする
- フォームで身長体重を送信すると同時に**BMI**,**身長を2倍したもの**をデータベースに格納

要は身長体重を入力させるだけでその他の情報もデータベースに格納したいとき

# 私の回答
```html+erb:persons/new.html.erb
...
<%= form_for(@person) do |f| =%>
  <%= f.text_field :weight =%>
  <%= f.text_field :height =%>
<% end %>
...
```

```person.rb
class Person < Application
  def bmi
    weight / height ** 2
  end
  
  def height_2
    height * 2
  end
  
  def set_extra_information
  {:bmi => bmi, :height_2 => height_2 }
  end
end
```

```persons_controller.rb
def new
  @person = Person.new
end

def create
  @person = Person.new(person_information)
  @person.save
end

private

def person_params
  params.require(:person).permit(:height, :weight)
end

def person_information
  person_params.merge(@person.set_extra_information)
end
```

入力されたフォームをperson_paramsで受け取ってそれをそのままインスタンス生成するのではなくてperson_informationというメソッドでhashとしてマージすることでデータベースに**BMI**,**身長を2倍したもの**を格納できる

正しいのかわからないにゃあ
STS 3.9.0 インポートの編成（自動インポート） ショートカットが使えないバグがある 

STS 3.9.0をダウンロードしてセットアップすると、いつものCtrl + Shift + Oが効かなくて、あれ？となったのでメモを残しておきます。

まず、不具合でショートカットが使えない場合、Javaソース編集中このようになっています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136617/e0cf3f52-e0b4-6e77-3731-9fc960010932.png)

## 改善方法
[ウィンドウ]-[設定]-[一般]-[キー]のオプションを開きます。
フィルターというボタンを押します。すると下記のウィンドウが開くので
カテゴリーがないコマンドをフィルターの**チェックを外す**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136617/c885d59a-7415-2f3a-9fd7-80d1451f40d6.png)

カテゴリーがないコマンドが表示された状態で、検索エリアに "Go"と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136617/32876354-f1a4-d4b3-1332-fecca19440b9.png)

コマンドのアンバインドを押して、適用して閉じる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136617/94301874-7028-2ab4-5689-daeb10870c17.png)

これでCtrl + Shift + O インポートの編成ショートカットが使えるようになります！

## 参考
[spring tool suite - Organize Imports shortcut not working after STS update - Stack Overflow](https://stackoverflow.com/a/45087158)
NLBでfluentdのforwardパケットを分散させてみた

AWSの新しいロードバランサであるNLB(Network Load Balancer)を使ってfluentdのforwardパケットを分散してみたので、レポートをまとめておく。

NLB自体については、クラスメソッドのブログ等で紹介されているのでそちらを参照するのが分かり易い。

[静的なIPを持つロードバランサーNetwork Load Balancer（NLB）が発表されました！](http://dev.classmethod.jp/cloud/aws/elb-network-load-balancer-static-ip-adress/)
[試してわかった NLB の細かいお作法](https://dev.classmethod.jp/etc/sugano-032-nlb-first/)

ざっくり言うと、TCPプロトコルを対象にしたALBって感じ。
ターゲットグループはポートレベルで設定できるので、コンテナ環境と相性が良い。
ポート違いで複数fluentdが立っていても同じグループとしてまとめて分散できる。

## 利用までの流れ
1. ターゲットグループを作成し、TCPレベルでコネクションが貼れるかのヘルスチェックの設定をする
2. インスタンスもしくは対象IPと、ポートの組をターゲットグループに登録する
3. NLBを作成し対象となるAZを設定、リスナーポートとターゲットグループを紐付ける
4. DNSを登録してそのDNS向けにforwardパケットを流す様にする

## fluentdで利用する場合
普通、fluentdのforwardパケットはクローズドなネットワークを流れるので、internal NLBとして作成した。
この時、NLBはEIPを紐付けられる様になっているので、必要があればEIPを準備する。その場合AZ毎に必要になる。後からの変更はできないらしい。
EIPを紐付けない場合は自動でプライベートIPが採番される。
ヘルスチェックパケットは、NLBのIPからやってくる。
NLBはセキュリティグループを持つことができないので、ヘルスチェックを通過するにはノード側のセキュリティグループでNLBのIPから対象ポートへの通信を許可する必要がある。
VPCのレベルで通信を許可して問題になることはあんまり無さそうなので、VPCのCIDRレベルで通信を許可しておくのが楽だろう。

エントリポイントとしてDNS名が自動で生成されるので、そこかもしくはEIPを対象にしたDNSのレコードを作っておく。
~~どうもALIASレコードには対応していない様なので、NLBのDNS名を登録する場合はCNAMEレコードになる。~~
一回作ろうとして失敗した記憶があるんですが、さっき試してみたらALIASレコード作れました。

## 実際に通信する時の動きについて
forwardの送信元になるノードはNLBのIPに対してTCP接続している様に見える。
forwardを受信するノードは送信元のノードのIPからTCP接続されている様に見える。
コネクションは長時間に渡って維持できるので、どちらかの要求で再接続されない限りは同じコネクションをずっと使い回すことができる。
動作を見るにProxyはせずに、IPの送信先だけを書き換えてパケットフローをコントロールしているっぽい。
しかし、これでは送信側と受信側でIPが噛み合わないので、戻りパケットがどうやって戻ってきているのか良く分からん。
送信側と受信側でtcpdumpを使ってパケットをキャプチャした結果、送信側はNLBとやり取りしている様に見えてるし、受信側は各個別のノード宛にパケットを送っている。
受信側のルーティングテーブルを弄ることなく繋がっているので、VPC内のスイッチで何らかの魔法が行われていないと戻りパケットがNLBに戻らないと思うのだが、この理解で合ってんのかな。
まあ、VPCとはいえ内部では色々とスイッチレイヤーを経てインスタンス同士が通信しているだろうし、そういう事は出来そうだけどちょっと気持ち悪いw

## health checkについて
NLBからのhealth checkはTCPで疎通できれば通過するので、実際にfowardパケットが届くかどうかまでは分からない。
out_forwardプラグインのhealth checkは0.14系からはtransportモードがデフォルトになっていて実際に通信を行うコネクションをそのまま利用してheartbeatを送っている。
デフォルトだと基本的にはTCPのコネクションをそのまま利用するはずなので、ちゃんとheartbeatの疎通が通る。
もしノードが死んだ場合、即座にheartbeatパケットが反応してconnectionが切断される。(この辺からもTCPレベルでは直結してる様に見える)
再接続する際は、実際にout_forwardのheartbeatパケットが届く所に対して接続されるので、すぐに生きてるノードに対してのコネクションが復活する。
LBを噛ました時の動作としては望ましい感じがする。

## パフォーマンスについて
今のところ最大で40Mbpsぐらいの流量でパケットを受け取っている。
すごい大規模なサービスではないので、そんなに大した量ではない。
アクティブなコネクション数は、2箇所のAZを合計して200前後。
LBのCapacityUnitは大体0.3ぐらいを推移している。
パケットの分散具合も安定している。
当分は使っていけそう。
面倒だったので実際のレイテンシまでは測定してない。まあうちぐらいだと問題になることは無さそう。
弊社の流量では限界があるので、もっと大規模なトラフィックが流れている環境でのレポートがあると良さそう。
SRE本まとめ（7章 Googleにおける自動化の進化）

自分の理解を深めるためにまとめてみました。[6章](https://qiita.com/bassbone/items/86414eddcc2b2d2b05ac)の続きです。

## 7章 Googleにおける自動化の進化

### 自動化のステップ
1. 自動化以前
    - ロケーション間でのデータベースマスタのフェイルオーバーが手動で行われる状態。
2. 外部でメンテナンスされるシステム固有の自動化
    - SREが自分のホームディレクトリにフェイルオーバーのスクリプトを持っている状態。
3. 外部でメンテナンスされる汎用の自動化
    - 誰もが使用する「汎用フェイルオーバー」スクリプトにSREがデータベースのサポートを追加した状態。
4. 内部でメンテナンスされるシステム固有の自動化
    - データベース自身にフェイルオーバーのスクリプトが同梱されてリリースされている状態。
5. システムが自動化を必要としない
    - データベースが問題を検出し、人間の介入なしに自動的にフェイルオーバーを行う状態。

（[8章](https://qiita.com/bassbone/items/2a908ac3889dd5a6bca0)に続く）
VS Codeのテーマをディレクトリごとに変える

# これって何のコードだ？
複数のディレクトリや異なるレポジトリのコードを触っていると、「あれ、今何のコードを表示してるんだっけ？」となることはありませんか？私は１日に３0回くらいあります。

そんな時、もしあなたVS Code使いならテーマの使い分けがオススメ。VS Codeにテーマを設定する機能があることは知っているかと思いますが、その設定はディレクトリ（ワークスペース）単位で行うこともできます。そのため、ディレクトリやレポジトリごとにテーマを設定しておけば、VS Codeを見た時に何のコードを表示しているかすぐに判別できるのでなかなか便利です。

# テーマの設定方法
それでは、設定方法を見てみましょう。なお、VS Codeでは作業対象としているディレクトリを「ワークスペース」と呼ぶので、ここでもワークスペースという言葉を使うことにします。

1. `⇧⌘P`を入力して、コマンドパレットを表示
2. `Open Workspace Settings`と入力して、ワークスペースの設定ファイルを表示
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/f36b1668-df70-7b76-1687-56544baa794e.png)

3. 設定項目の検索フィールドに`colortheme`と入力して、`workbench.colorTheme`の編集アイコンをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/9f625b78-3d63-5d6d-0192-93792b667dc4.png)

4. 現在のワークスペースに適用したいテーマを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/2579730b-d623-5c6c-679f-886e87d5f903.png)

これで、現在のワークスペースを表示する度に、選択したテーマが適用されるようになります。ワークスペースごとに異なるテーマを使っておけば、何のコードを表示しているのかすぐにわかりますね！:tada:

なお、ワークスペース用の設定を追加すると、現在のディレクトリに`.vscode`というディレクトリが作成されるので、Gitを使用している場合は`.gitignore`で`.vscode`以下のファイルを管理対象外としておきましょう。

# 参考
[VS Code テーマ](https://vscode-doc-jp.github.io/docs/getstarted/themes.html)
MonacaとOnsenUIを使ってみる

- Monaca
    - アシアル株式会社によるスマホアプリ開発ツールの総称。
- OnsenUI
    - アシアル株式会社によるUIフレームワーク。

## インストールと起動

```sh
# nodeはインストールされているものとする
npm i monaca -g
monaca create hello # ここでOnsenUIを選ぶ
cd hello
monaca preview
```
社内の開発環境を整理

社内のシステム部署に異動したので、開発環境の整備をメモする。

#開発言語

**・typescript**
マイクロソフトによって開発されメンテナンスされている
コンパイルすると、JavaScriptのソースコードになる
現在JavaScriptコードが動作する環境であればtypescriptも使える

**・Scala**
Javaの良さを継承し、かつスクリプト言語や関数型言語のメリットを吸収した言語Javaの後継的な位置づけ

**・node.js**
サーバー側で動作するJavaScript
データベースから大量の情報を取得してWebページ上に表示をする処理に適している
コマンドラインで操作できる
ノンブロッキング処理ができる

#バージョン管理ツール

*・nodist*
node.jsのバージョン管理ツール
Windowsしか対応していない
コマンドプロンプトでnode.jsのバージョンを切り替えられる

#フレームワーク

**・PlayFramework**
Javaのフレームワーク
MVCモデルを採用

**・Angular**
JavaScriptのフレームワーク
Googleと個人や企業のコミュニティによって開発されている
React.jsの競合的なイメージ(こっちはFacebookが開発している)

#統合開発環境

**・IntelliJ IDEA**
JetBrains という会社が開発している
Eclipceの競合

#データベース
**Amazon Aurora**
Amazonのクラウドリレーショナルデータベース
MySQL 5.6 と互換性を持つ、つまりSQL5.6で動くコマンドはAmazon Auroraでも動く
また、MariaDBはMySQLとニアリーイコールなので、こっちとも互換性がある

#データベース管理ツール
**MySQL Workbench**
MySQLの公式サイトで配布されている、データベースの設計・開発・管理を一本で実現している無料ツール、GUI的に使える。
Adminerなどが競合のイメージ(MySQL Workbenchはソフトウェアだが、Adminerはブラウザでいじれる)


#ソース管理ツール

**・Bitbucket**
Gitを使いやすくするWebサービス
GitHubの競合的なイメージ
GitHubと違って、無料で非公開リポジトリ管理ができる

**・SourceTree**
BitBucketやGitHubなどソース管理ツールと連携する
ソフトウェア上でGit操作をGUI的にできる
*Gitflow*
プロジェクトのリリースを想定して設計された厳密なブランチモデル。
Gitから落としてきたリポジトリを、本番環境に反映させる完成したリポジトリ(masterと呼ぶ。プロジェクト管理者の監視が望ましいリポジトリ)、本番環境に反映させる一歩手前のほぼ完成しているリポジトリ(developと呼ぶ。各メンバーのいじったリポジトリが集約される)、改修,バグ対応に使うリポジトリ(feature branchesと呼ぶ。各メンバーが思い思いに触っているリポジトリ)へと枝分かれさせる。
参照先
https://www.atlassian.com/ja/git/workflows#!workflow-gitflow
https://qiita.com/KosukeSone/items/514dd24828b485c69a05
the little book mongodbのAggregating Dataをざっくり説明

[the little book mongodb](https://github.com/karlseguin/the-little-mongodb-book/blob/master/en/mongodb.markdown)は無料で読めるMongoDBの本です。
[MongoDBの薄い本](https://github.com/hamano/the-little-mongodb-book)として有志による日本語訳も公開されています。
先日、英語の勉強も兼ねて日本語訳で補完しながら原文を読んでいたところ、いくつか異なる部分を見つけました。
中でも、[Chapter 6 - Aggregating Data](https://github.com/karlseguin/the-little-mongodb-book/blob/master/en/mongodb.markdown#chapter-6---aggregating-data)の部分が日本語訳では[Map Reduce](https://github.com/hamano/the-little-mongodb-book/blob/master/ja/mongodb.markdown#mapreduce)となっていて、結構内容が異なります。
というのも、原文のほうが2014年5月にガッツリ変わっているようです。
MongoDBのRelease Noteを追ってみると確かにそのあたり(2.2～2.4らへん)がAggregationFrameworkが導入されたようなのでそれを受けての改稿かと思われます。

今回は、そのAggregating Dataの部分をざっくりと訳してざっくり説明します。
使うデータなどは原文を参照。
ユニコーンのデータらしい。My Little Ponyとかその辺かと思ったら違った。
vampiresというフィールドも謎なんだけど、何か元ネタとかあるのかなあ。

# Aggregating Data
## 集約パイプライン
集約パイプラインはコレクション内のドキュメントに対して、(UNIXのパイプのように)変換して組み合わせることができます。
今まで使ってきたcount()は単純な数なら数えられましたが、男性、女性の各人数を知りたいときには以下のようにします。

```js
db.unicorns.aggregate([
    {$group:{_id:'$gender',total: {$sum:1}}}
])
```
```
{ "_id" : "f", "total" : 5 }
{ "_id" : "m", "total" : 7 }
```

`$group`はSQLでのGROUP BYのように`_id`フィールドによってグループ化を行います。
フィールドの値を参照するため、`gender`ではなく、`$gender`になります。

そのほかの演算子としては、`$match`があります。これは、集約されるドキュメントを制限します(`find`の条件部分のようなもの)。

```
db.unicorns.aggregate([
    {$match: {weight:{$lt:600}}},
    {$group: {_id:'$gender',  total:{$sum:1}, avgVamp:{$avg:'$vampires'}}},
    {$sort:{avgVamp:-1}}
])
```
```
{ "_id" : "f", "total" : 3, "avgVamp" : 61.5 }
{ "_id" : "m", "total" : 2, "avgVamp" : 50.5 }
```
`$sort`を使って集約結果をソートすることができる。`$limit`や`$skip`も用意されています。
また、`$group`の中では`$avg`を使って平均を求めることもできます。

配列の内部に格納されている値を集約したい場合は、一度`$unwind`演算子を使ってフラットにする必要があります。

```
db.unicorns.aggregate([
    {$unwind:'$loves'},
    {$group: {_id:'$loves',  total:{$sum:1}, unicorns:{$addToSet:'$name'}}},
    {$sort:{total:-1}},
    {$limit:3}
])
```
```
{ "_id" : "apple", "total" : 5, "unicorns" : [ "Solnara", "Raleigh", "Leia", "Pilot", "Roooooodles" ] }
{ "_id" : "carrot", "total" : 4, "unicorns" : [ "Solnara", "Nimue", "Aurora", "Horny" ] }
{ "_id" : "grape", "total" : 4, "unicorns" : [ "Kenny", "Dunx", "Nimue", "Aurora" ] }
```
多くのユニコーンが好きな食べ物のリストを、`$limit`を使うことで上位N番目を得ることができます。

そのほかにも、特定のフィールドの値を利用して新しいフィールドの作成を行うことが`$project`という強力な演算子も用意されています。
バージョン2.6からは集約は(1章の)カーソルを返したり、`$out`演算子により別のコレクションに結果を書き込むことができるようになり、より強力なものとなっています。
そのほかの演算子や例については[MongoDBのマニュアル](https://docs.mongodb.com/manual/core/aggregation-pipeline/)を参照してください。
ROT13(シーザー暗号)の解き方　備忘録


シーザー暗号の解き方に関する備忘録です。

#解き方

Pythonに元々実装であるため、

```
$ python
>>> import codecs
>>> codecs.decode('Uryyb, Jbeyq!','rot13')
'Hello, World!'
>>> 
```

これだけで解けちゃいます。

#対話型シェルの終わり方
`q`でも`quit`でも終わらず、(エディタの名残かな？)
少し困ったので書いておきます。

`exit()`

これだけでいけたんですね。
jsdoでMK-80 その3

#概要
jsdoでMK-80やってみた。
ハンドアセンブラやってみた。

#プログラム
0123456と表示する。

#アセンブラ

```
keyinput　EQU　0216H
showsegdata  EQU  01C0H
ORG 8200H

start: 
    MVI A, 01H
    STA 83F4H
    MVI A, 23H
    STA 83F5H
    MVI A, 45H
    STA 83F6H
    MVI A, 67H
    STA 83F7H
    CALL showsegdata
    hlt
```
#ハンドアセンブル

```
8200	3E 01               
8202	32 F4 83            
8205	3E 23               
8207	32 F5 83            
820A	3E 45               
820C	32 F6 83            
820F	3E 67               
8211	32 F7 83            
8214	CD C0 01            
8217	76      
```

#打ち込み

```
8 2 0 0 adrset
3 e write
0 1 write
...
7 6 write 
```

#実行

```
8 2 0 0 adrset run
```

以上
[VBA]ExcelのRangeが同じ範囲を参照しているかを判定する関数

ExcelのRangeオブジェクトが同じ範囲を参照しているかの確認が面倒だったため、判定用の関数を作成してみました。

# コード

```vbnet
'iRng1とiRng2が同じ範囲を参照しているかを判定する関数。
Function RangeEqual(ByVal iRng1 As Excel.Range, ByVal iRng2 As Excel.Range) As Boolean
    Let RangeEqual = (iRng1.Address(External:=True) = iRng2.Address(External:=True))
End Function
```

## ポイント

引数未指定のAddressプロパティでは「`$A$1`」などの形式となり、ワークシートの違いなどを判定できません。

第4引数の`External`を指定することで

```text
[ブック名]シート名!$A$1
```

のような形式となり、ワークシートが違う場合なども判定できるようになります。

## サンプル

```vbnet

Sub Sample_RangeEqual()
    
    'Trueの場合
    '単一セル
    Debug.Print RangeEqual(ActiveCell, ActiveCell)
    Debug.Print RangeEqual(ActiveCell, ActiveCell.Offset(0, 0))
    
    'セル範囲
    Debug.Print RangeEqual(Cells, Cells)
    Debug.Print RangeEqual(Rows, Columns)
    
    With Excel.Application
        '複数のセル
        Debug.Print RangeEqual(.Union(.Range("A1"), .Range("B2")), .Union(.Cells(1, 1), .Cells(2, 2)))
    End With 'Excel.Application
    
    'Falseの場合
    Debug.Print RangeEqual(ActiveCell, ActiveCell.Offset(1, 0))
    
End Sub
```
jsdoでMK-80 その2

#概要
jsdoでMK-80やってみた。
ハンド逆アセンブラ用のコード表を作ってみた。

#写真
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/M/S/j/MSjV.jpg?t=1506940130)

#成果物
http://jsdo.it/ohisama1/MSjV

以上
NSTimerの使い方

## NSTimerを使ってみた
今回、アプリの中で「スロット機能」のようなものが必要になるとのことで、初めてNSTimerを使ってみました。使い方がこれで正しいのかわかりませんが、備忘録として残します。

### 基本的な使い方
NSTimerの基本的な使用法は下記のように「〜秒ごとに何かのメソッドを呼び出す」という風に使うようです。
※下記では0.7秒ごとにhogeメソッドを繰り返し呼び出します。

```
NSTimer *timer = 
[NSTimer scheduledTimerWithTimeInterval:0.7f
target:self
selector:@selector(hoge:)
userInfo:nil 
repeats:YES];
```

### スロット機能作成
そして今回はこのNSTimerを使って、簡易的なスロットを作ってみました。

``` 
#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) NSTimer *timer;
@property (strong, nonatomic) NSArray *numberList;
@property (weak, nonatomic) IBOutlet UILabel *resultLabel;
@property (nonatomic) int getCount;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.numberList = @[@1, @2, @3, @4, @5, @6];
    
}

- (void)hoge:(NSTimer*)timer{
    if (self.getCount >= 6) {
        self.getCount = 0;
    }
    id selectCount = self.numberList[self.getCount];
    NSString *labelCountText = [NSString stringWithFormat:@"%@",selectCount];
    self.resultLabel.text = labelCountText;
    self.getCount ++;
}

- (IBAction)timerStart:(id)sender {
    [self.timer invalidate];
    self.timer =
    [NSTimer
     scheduledTimerWithTimeInterval:0.03f
     target:self
     selector:@selector(hoge:)
     userInfo:nil
     repeats:YES];
}

- (IBAction)timerStop:(id)sender {
    [self.timer invalidate];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end 

```

### まとめ
メソッドの実行間隔を調整できるので、動的な機能を作る際は便利ですね。
今後はアニメーションなどと合わせて使ってみたいと思います。
CSVファイルをMac/WindowsのExcelで開けるように変換する

## はじめに
こんにちは。10分で生産的なミーティングができるWeb会議ツール「[minmeeting](https://minmeeting.jp/)」を開発している伊勢川です。

<a title="minmeeting - 10分で生産的なミーティングができる会議ツール" href="https://minmeeting.jp/" target="_blank"><img width="100px" src="https://qiita-image-store.s3.amazonaws.com/0/199506/32e65577-a5bb-2c3b-4d30-4690c3c5ce0f.png" /></a>

未だ大人気のExcelですが、Macで使おうとするといろいろ問題があります。例えば、日本語を含むデータをUTF-8のCSVファイルで出力することはよくあると思いますが、Excelで普通に開くと文字化けしてしまいます。

ここでは、その問題を解消して、文字化けせずにMacのExcelでもCSVが開けるようになる方法を紹介します。

## 変換方法
カンマをタブに変換し、文字コードを「UTF-16LE-BOM」に変換し拡張子をxlsにすると、MacでもWindowsでもダブルクリックでExcelにて開けるようになります。macやcygwinのコマンドで実行する方法は下記の通りです。

```.sh
inputFile="変換対象のCSVファイル名（UTF8）"
outputFile="出力するファイル名.xls"
tr "," "\\t" < $inputFile > $outputFile
nkf --overwrite -Lw --oc=UTF-16LE-BOM $outputFile
```

## 指定したCSVファイルをExcelで開ける形式に変換するシェル
コマンドを覚えるのが面倒な場合は、下記のようにシェルスクリプトにしておくと便利です。

```.sh
#!/usr/bin/env bash
#----------------------------------------------------------------------#
# カレントディレクトリにあるUTF-8のCSVファイルを、
# Excelで開ける形式（UTF-16LE-BOMのTSV）に変換
#----------------------------------------------------------------------#

# 入力チェック
if [ $# -ne 2 ]; then
    echo "第一引数に入力ファイル（UTF8のCSV）を指定。"
    echo "第二引数に出力ファイル名（Excel）を指定。"
    echo '例）./csv2xls.sh inputFileName.csv outputFileName.xls'
    exit 1
fi

currentDirectory="$(pwd)"
inputFile="$currentDirectory/$1"
outputFile="$currentDirectory/$2"

tr "," "\\t" < $inputFile > $outputFile
nkf --overwrite -Lw --oc=UTF-16LE-BOM $outputFile
```

## カレントディレクトリのすべてのCSVファイルを、Excelで開ける形式に変換するシェル
カレントディレクトリ以下のCSVファイルを一気に変換するシェルは下記の通りです。

```.sh
#!/usr/bin/env bash

#----------------------------------------------------------------------#
# カレントディレクトリのすべてのCSVファイル（UTF-8）を、
# Excelで開ける形式（UTF-16LE-BOMのTSV）に変換
#----------------------------------------------------------------------#
currentDirectory="$(pwd)"
for filename in $currentDirectory/*.csv; do
    inputFile="$filename"
    outputFile="$filename.xls"

    tr "," "\\t" < $inputFile > $outputFile
    nkf --overwrite -Lw --oc=UTF-16LE-BOM $outputFile
done
```
Laravel5.5でのルーティング方法一覧

#Laravel5.5でのルーティング方法一覧

## ベーシック

```php:
Route::get('/user', 'UsersController@index');
Route::post('/user', 'UsersController@index');
Route::put('/user', 'UsersController@index');
Route::patch('/user', 'UsersController@index');
Route::delete('/user', 'UsersController@index');
Route::options('/user', 'UsersController@index');
```

## GETもPOSTも対応(複数対応)

```php:
Route::match(['get', 'post'], '/user', function () {
    'UsersController@index'
});
```

## 全HTTP動詞に対応する

```php:
Route::any('/user', function () {
    'UsersController@index'
});
```

## リダイレクト

```php:
Route::redirect('/user', '/there', 301);
```


##  ルートからビューを返すだけの場合
最初の引数にURIを取り、ビュー名は第２引数

```php:
Route::view('/user', 'user');

#配列も渡す
Route::view('/user', 'user', ['name' => 'Taylor']);
```

## 必須パラメータ

```php:
#URLからユーザーIDを取り出したい場合
Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});
```

##  任意パラメータ
パラメータ名の後に?を付けると、任意指定のパラメータになります。対応するルートの引数に、デフォルト値を必ず付けてください。

```php:
Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});
```

##  正規表現制約
whereメソッドを使って、ルートパラメータのフォーマットを制約できます。

```php:
Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
```

##  グローバル制約
指定した正規表現でいつもルートパラメータを制約したい場合は、patternメソッドを使ってください。

```php:
/**
 * ルートモデル結合、パターンフィルタなどの定義
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}
```

##  名前付きルート
ルート定義にnameメソッドをチェーンすることで、そのルートに名前がつけられます。

```php:
Route::get('user/profile', 'UserController@showProfile')->name('profile');
```

##  ミドルウェア

```php:
Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // firstとsecondミドルウェアを使用
    });

    Route::get('user/profile', function () {
        // firstとsecondミドルウェアを使用
    });
});
```

##  ルートプレフィックス
グループ内の全ルートのURIにadminを付けたければ、次のように指定します。

```php:
Route::prefix('admin')->group(function () {
    Route::get('users', function () {
        // Matches The "/admin/users" URL
    });
});
```

##  現在のルートへのアクセス

```php:
$route = Route::current();

$name = Route::currentRouteName();

$action = Route::currentRouteAction();
```
CentOS7 apache2.4 でphpmyAdminをインストールしたらForbiddenが半日治らなかった件

参考記事がたくさんヒットしたのに、まったく治らなくて発狂しそうになりましたが、


・apacheのバージョンによって権限を開く記述が違う
・記述を追記する場所も違う

上記がポイントでした。

==================

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

＜ Directory /usr/share/phpMyAdmin/＞
   AddDefaultCharset UTF-8
   AllowOverride all  <----ここにこの記述を追加！
   Require all granted　 <----ここにこの記述を追加！
   <IfModule mod_authz_core.c>
     # Apache 2.4
     <RequireAny>
       Require ip 127.0.0.1
       Require ip ::1
 ＜/RequireAny＞
   ＜/IfModule＞
   ＜IfModule !mod_authz_core.c＞
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   ＜/IfModule＞
＜/Directory＞

==================

apache2.2だと`Allow from All`みたいな記述でしたが、
２．４だと
`AllowOverride all`
`Require all granted`
になるということが分かるまでに１時間くらいかかった^^;

さらにそこから記述場所でひっかかりまして。
（<RequireAny>の中に書いちゃってた）
プログラムの文をちゃんと理解していないのが問題^^;
＜Directory /usr/share/phpMyAdmin/＞の下に書いてあげたら、
phpmyadminのログイン画面でました。やっほーい。
BSONデータをbsondumpでJSONに変換する

## 変換前にcatで表示させると文字化けするためJSONに変換する

## 変換コマンド
[root@localhost crowidb]# ls -lah
合計 2.3M
drwxr-xr-x. 2 root root 4.0K 10月  3 04:08 .
drwxr-xr-x. 7 root root   72 10月  2 22:05 ..
-rw-r--r--. 1 root root 1.3K 10月  2 22:05 attachments.bson
-rw-r--r--. 1 root root  321 10月  2 22:05 attachments.metadata.json
-rw-r--r--. 1 root root   86 10月  2 22:05 bookmarks.bson
-rw-r--r--. 1 root root  450 10月  2 22:05 bookmarks.metadata.json
-rw-r--r--. 1 root root    0 10月  2 22:05 comments.bson
-rw-r--r--. 1 root root  424 10月  2 22:05 comments.metadata.json
-rw-r--r--. 1 root root 1.5K 10月  2 22:05 configs.bson
-rw-r--r--. 1 root root  297 10月  2 22:05 configs.metadata.json
-rw-r--r--  1 root root   13 10月  3 02:33 export.csv
-rw-r--r--. 1 root root 263K 10月  2 22:05 pages.bson
-rw-r--r--. 1 root root  762 10月  2 22:05 pages.metadata.json
-rw-r--r--  1 root root 405K 10月  3 00:48 pages.txt
-rw-r--r--. 1 root root 739K 10月  2 22:05 revisions.bson
-rw-r--r--. 1 root root   99 10月  2 22:05 revisions.metadata.json
-rw-r--r--  1 root root 819K 10月  3 04:08 revisions.txt
-rw-r--r--  1 root root 1.3K 10月  2 22:05 searchwords.bson
-rw-r--r--  1 root root  101 10月  2 22:05 searchwords.metadata.json
-rw-r--r--. 1 root root 2.7K 10月  2 22:05 system.indexes.bson
-rw-r--r--. 1 root root    0 10月  2 22:05 updateposts.bson
-rw-r--r--. 1 root root  214 10月  2 22:05 updateposts.metadata.json
-rw-r--r--  1 root root  385 10月  2 22:05 user.bson
-rw-r--r--  1 root root   94 10月  2 22:05 user.metadata.json
-rw-r--r--. 1 root root 1.4K 10月  2 22:05 users.bson
-rw-r--r--. 1 root root  515 10月  2 22:05 users.metadata.json
-rw-r--r--  1 root root  116 10月  2 22:05 words.bson
-rw-r--r--  1 root root   95 10月  2 22:05 words.metadata.json

## 変換コマンド
[root@localhost crowidb]# bsondump revisions.bson

## 検索コマンド
[root@localhost crowidb]# cat revisions.txt | grep -R -e 'test'

## 2017年10月分だけ抽出
grep -e '/user/test/日報/2017/10/' pages.txt | gawk '{ match($0, /"revision" : ObjectId. "([0-9a-f]+)"/, m ); print m[1];}' | awk '{system("grep -e " $0 " revisions.txt");}'

①日付でひっかけてObjectIdを表示させる
grep -e '/user/yamagami/日報/2017/10/' pages.txt 

②ObjectIdの情報のみ表示させる
gawk '{ match($0, /"revision" : ObjectId. "([0-9a-f]+)"/, m ); print m[1];}'

③ObjectIdの情報を表示させる
awk '{system("grep -e " $0 " revisions.txt");}'
さくらのレンタルサーバー（スタンダード）にWP-CLIをインストールする（完全版）

さくらのレンタルサーバーにWP-CLIをインストールする方法を紹介します。

これについてはすでにいろいろなところで書かれていますが、設定ファイルやコマンド補完などについても紹介されているものを見つけられなかったので書くことにしました。

## WP-CLIをインストール

今回は、WP-CLIのnightlyバージョンをインストールしましょう。

以下のコマンドをコピペして実行してください。

```
mkdir -p $HOME/bin && curl -L https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar -o $HOME/bin/wp && chmod 755 $HOME/bin/wp
```

以上で `wp` コマンドが使えるようになったはず。

```
$ wp --info
PHP binary:	/usr/local/bin/php-wrapper
PHP version:	7.1.9
php.ini used:	/usr/local/php/7.1/etc/php.ini
WP-CLI root dir:	phar://wp-cli.phar
WP-CLI vendor dir:	phar://wp-cli.phar/vendor
WP_CLI phar path:	/home/xxxx
WP-CLI packages dir:	
WP-CLI global config:	/home/xxxx/.wp-cli/config.yml
WP-CLI project config:	
WP-CLI version:	1.4.0-alpha-34bfe03
```

## 設定ファイルを作成

今回はとりあえず空の設定ファイルを作ります。

```
$ mkdir -p $HOME/.wp-cli && touch ~/.wp-cli/config.yml
```

設定ファイルは使いこなすと便利なので、興味がある人は以下をご覧になってください。

https://make.wordpress.org/cli/handbook/config/

## シェルを bash に変更

これは好みですが、WP-CLIは bash をベースにテストされているので、さくらのレンタルサーバーのデフォルトの csh ではところどころで微妙に残念です。

```
$ chsh -s /usr/local/bin/bash
```

もし、bash に変更しない人は以下は関係ありません。

## WP-CLIのコマンド補完を有効化する

まずコマンド補完に必要なファイルを設置。

```
$ curl -L https://raw.githubusercontent.com/wp-cli/wp-cli/master/utils/wp-completion.bash -o ~/.wp-cli/wp-completion.bash
```

次に以下を `~/.bash_profile` に追加。`~/.bash_profile`がなければ作ってください。

```
source $HOME/.wp-cli/wp-completion.bash
```

以上で完了です。一度ログアウトしてログインし直すと以下のようにタブキーでコマンドが補完されます。

```
$ wp core 
check-update        is-installed        update              
download            multisite-convert   update-db           
install             multisite-install   version 
```
どこでも食っていけるC++のソフトウェアエンジニアになるために

以下の本は熟読しよう

- [「テスト駆動開発による組み込みプログラミング」](https://www.oreilly.co.jp/books/9784873116143/)

![](https://www.oreilly.co.jp/books/images/picture978-4-87311-614-3.gif)

　テスト・リファクタリング・良い設計とは何かを学ぶことができます。
　組み込み分野の例を用いていますが、組み込みをしない人でも役に立つ内容です。

- [「Effective C++(第3版)」](http://pub.maruzen.co.jp/book_magazine/book_data/search/9784621066096.html)
- [「Effective Modern C++ ――C++11/14プログラムを進化させる42項目」](https://www.oreilly.co.jp/books/9784873117362/)

![Effective Modern C++](https://www.oreilly.co.jp/books/images/picture978-4-87311-736-2.gif)

C/C++言語のやっかいな点は、使うべきでない機能やライブラリが多数存在していて、言語を学ぶときの標準として影響し続けていることです。昔のライブラリを使った実装ではメモリーリークを生じがちでした。その後ライブラリのバージョンが上がってC++インタフェースで使うようになるとメモリリークの問題ははるかに生じにくくなりました。C++言語は進化し続けていて、それによってより安全な、よりパフォーマンスを確保しやすいものになっています。昔のC++ではコピーコンストラクタが必要以上に呼ばれてしまう書き方をしてしまいやすいという欠点があります。しかし新しいC++の中ではそのような欠点が克服されています。

- [「Optimized C++　――最適化、高速化のためのプログラミングテクニック」](https://www.oreilly.co.jp/books/9784873117928/)

![](https://www.oreilly.co.jp/books/images/picture978-4-87311-792-8.gif)

- [「Effective Debugging　――ソフトウェアとシステムをデバッグする66項目」](https://www.oreilly.co.jp/books/9784873117997/)

![](https://www.oreilly.co.jp/books/images/picture978-4-87311-799-7.gif)

これらの本を熟読して、使いこなせていけば、C++の上級のエンジニアと言っていいでしょう。
品質を確保した、最適化されたコードにたどりつけるでしょう。

追加(2024年）[Modern C++ チャレンジ C++17プログラミング力を鍛える１００問](https://www.oreilly.co.jp/books/9784873118697/)
![](https://www.oreilly.co.jp/books/images/picture978-4-87311-869-7.gif)

コンピュータ言語自体での強みの他に、自分がどういった対象領域に強みを持つのかを設定する。
そうして、自分は「何屋です」と言い切るようにしていく。その何屋に期待される平均的な手法を自分のものにしていきます。

強みをもつ領域が何であるのかを宣言することは、あなたに仕事を任せたい側にとって判断しやすくなることにつながります。

そしてその何屋といえる部分のレベルをあげていくことです。
そうすれば、その分野で需要があるかぎり、どこでも食っていける技術者になれます。

2022.12　追記：
- C++の弱点として過去のライブラリとの互換性の束縛があります。
- その互換性の束縛を切り捨てて、新しい言語仕様・新しいライブラリの実装がありえます。
- 実際に、そのような選択肢としてRustがあります。