OmniAICreator/Qiita-1.07M huggingface dataset:
[Mac]sbtの特定のバージョンをbrew installでインストールする方法

最新のsbtは1.0系だが(2017年11月現在)0.13系のsbtをbrew installでインストールしたかったので調べました。
自分用メモです。

## sbtのアンインストール
1.0系が入ってる場合はアンインストールする

```bash
$ brew uninstall sbt
Uninstalling /usr/local/Cellar/sbt/1.0.3... (494 files, 73.8MB)
```

## インストールできるsbtのバージョンを調べる
sbtの0.13系があるのを確認する

```bash
$ brew search sbt
==> Searching local taps...
sbt                   sbt@0.13                  sbtenv
==> Searching taps on GitHub...
==> Searching blacklisted, migrated and deleted formulae...
```


## 0.13系をインストールする

```bash
$ brew install sbt@0.13   
==> Downloading https://dl.bintray.com/homebrew/mirror/sbt-0.13.16
######################################################################## 100.0%
==> Caveats
You can use $SBT_OPTS to pass additional JVM options to SBT:
   SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"

This formula uses the standard Lightbend sbt launcher script.
Project specific options should be placed in .sbtopts in the root of your project.
Global settings should be placed in /usr/local/etc/sbtopts

This formula is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/sbt@0.13/bin:$PATH"' >> ~/.zshrc

==> Summary
🍺  /usr/local/Cellar/sbt@0.13/0.13.16: 384 files, 63.5MB, built in 26 seconds
```


## パスを通す
インストールした時の説明にも書いてあるがパスが通ってない場合があるのでパスを通す

```bash
# パスが通ってないので
$ which sbt
sbt not found

# パスに追加する
$ echo 'export PATH="/usr/local/opt/sbt@0.13/bin:$PATH"' >> ~/.zshrc

$ source ~/.zshrc 

# パスが通った！
$ which sbt
/usr/local/opt/sbt@0.13/bin/sbt
```

## バージョン確認
0.13系がインストールできました

```bash
 $ sbt sbt-version
(省略)
[info] 0.13.16
```

## 一言
sbtじゃなくてもbrew installで特定のバージョンを入れるのはこの方法でいけそう

## 参考サイト
[homebrewでバージョンを指定してパッケージを入れる。](http://kkkw.hatenablog.jp/entry/mac/homebrew-install-specify-version)
MecabをPythonで使う

# Mecab
まずはMecabをインストール

```

sudo apt-get install mecab libmecab-dev mecab-ipadic mecab-ipadic-utf8
```
正常にインストールできているかを確認

```
$ mecab
君の名は
君      名詞,代名詞,一般,*,*,*,君,キミ,キミ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
名      名詞,一般,*,*,*,*,名,ナ,ナ
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
EOS

```

# mecab-ipadic-NEologd
辞書を変更する（もとの辞書は固有名詞などが弱い）

```

$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ ./bin/install-mecab-ipadic-neologd -n -a
```


# mecab-python
Python2の場合

```
$ pip install mecab-python
```

Python3の場合

```
$ pip3 install mecab-python3
```

上は環境によって違うかもしれない

確認

```test.py
import sys
import MeCab
#Taggerの引数に-dオプションとmecab-ipadic-neologdの場所を指定する
#　↓場所の確認
# echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
m = MeCab.Tagger("-d ../mecab-ipadic-neologd")
text = m.parse("君の名前は")
print( text)
```





```
$ python3 test.py
君      キミ    君      名詞-代名詞-一般
の      ノ      の      助詞-連体化
名前    ナマエ  名前    名詞-一般
は      ハ      は      助詞-係助詞
EOS

```

以上
Rubyで画像収集を行う【2】検索結果の取得

#目次
1：検索条件の入力　
2：検索結果の取得　←いまここ
3：画像の取得と保存
つづく

#前回のおさらい
【1】検索条件の入力　では、検索ワード、初めのページ数、終わりのページ数を入力した。
今回はそれらをもとに、リクエストクエリ(urlに含まれる?以降のq=XXXXとかのやつ)を
いじって検索結果を取得する



#早速始めよう
```.ruby

def i_search(start, ender)
	i=start.to_i #開始するページ数をstringからintに変換

	while i <= ender.to_i do #終了するページ数までの間、以下をループ
		url = "https://www.bing.com/images/search?q=#{$escaped_keyword}" #検索文字列を入れたurlを作る
		url = url + "&first=" + ((i-1)*29).to_s #何番目の画像を最初に表示するかを追加　※後述
		$doc = Nokogiri.HTML(open(url)) #作成したurlでアクセスした結果をhtmlで取得
		j=0 #画像のカウンタ
		$doc.css('div.item > a').each do |a| #HTML内のdiv内のitemのaタグに関して以下をする
			$result[j]=a[:href] #aタグのhref(画像のリンク)を取得
			puts $result[j] #画像のurlを画面に出力
			save_image($result[j]); #画像を保存する関数へ画像のリンクを渡す
			j=j+1; #画像のカウンタを増やす
		end

		p j #画像のカウンタを画面に出力
	i=i+1 #ページ数を増やす
	end

	p "i="+i.to_s #ページ数を画面に出力
end
```

#コメント
やってることを軽く解説する。
まずurlは検索ワードと何枚目の画像を先頭に表示するかをリクエストクエリに含める。
bingが返すhtmlは、画像が28枚(たしか)含まれているので、2ページめの検索結果が
欲しい場合にはfirst=29とすることで、これが実現できるというカラクリ。

htmlはNokogiriというライブラリで解析して、その中の画像のリンクを抽出する。
bingの返すhtmlの中身を見たところ、div内のitem内のaタグに画像のオリジナルの
リンクを含んでいるので、それぞれのurlを取り出してresult[]配列に格納する。
それをsave_image()関数に投げて、保存する、という流れ。

次回はsave_image関数で画像を保存する部分を書きます。
輸出暗号とFREAK

世界が改変される12月18日ですが、いかがお過ごしでしょうか。

さて、SSL暗号の世界も普及までの道のりは平坦なものではなく、途中にはいろんなできごとがありました。

# 暗号≒軍事
シーザー暗号とか、第2次大戦期の暗号解読をめぐる情報戦を例に引くまでもありませんが、軍事上、情報管理、そして暗号は重要な役割を占めています。

インターネットの普及や、個人レベルで豊富な計算能力が利用可能となった20世紀末ごろまで、暗号は基本的に軍事利用がメインでした。

## 暗号の輸出規制

軍事利用できる技術が拡散すれば問題となるので、軍事上さまざまな規制を行っていました。昔はかなりガチガチだったのですが、1つの事件を機として大幅に緩和されます。今でもiOSアプリの配信にあたって「輸出コンプライアンス」に基づく申告が求められますが、これは現在も残っている規制のためです。

「Pretty Good Privacy」というソフトウェアがありますが、発表当時はまだアメリカの暗号規制がガチガチにかかっていて、インターネット上でPGPを公開した作者が輸出規制違反として捜査対象となる、という事件がありました。

そのさなか、作者は本を発表します。それは、「PGPのソースコードを**印刷して本にした**」ものでした。合衆国憲法修正第1条にあるように、出版物の検閲は法的にも行えないので、輸出規制で揉めているのを尻目に本は堂々と海外に輸出され、共感した海外のボランティアがこの本をOCRにかけて復元したソースコードから「国際版PGP」が作られるに至り、規制は公然と突破されてしまうこととなりました。本人に及んでいた捜査の手も、「合法的に拡散してしまった以上、もはや意味がない」ということで打ち切りとなったといいます。

このことや、インターネットショッピングなどで「暗号通信できないと不安」という経済界の声もあり、規制緩和が進んだ結果、十分な強度の暗号が（一部の国を除く）世界中で使えるようになっています。

# SSLと輸出規制

SSL 2.0[^1]のリリースは1994年と、まだ暗号規制が行われているさなかであったため、当然ながら対策が求められることとなりました。具体的には、許可なしで扱えた強度の暗号（RSA 512ビット、共通鍵暗号40ビット[^2]）を使う国際版と、128ビットなどフルに暗号をかける「アメリカ版」がブラウザで用意されていたほか、サーバ側でも輸出暗号を受け付けるようになっていました。

もちろん、通信内容の暗号化に使う共通鍵暗号は「適切」なものを使えるのですが、RSA 2048ビットの証明書のあるサーバで、RSA 512ビットの鍵交換はどうすればいいのでしょうか。ここで登場するのが一時的な鍵です。2048ビットの鍵で署名した512ビットの一時的な公開鍵をサーバからクライアントに送信して、こちらを使って鍵交換を行う、という仕組みとなっています。

なお、「一時的な鍵」とはいっても、サーバから署名して送っているように、2人にしか知られないものではなく、また処理負荷を考えて1日ぐらい使いまわしていたとのことで、現代のForward Secrecyとはまったく別概念です。

## 輸出暗号を破る

強度512ビットのRSAを使うこと、またその鍵を使いまわすことなどがあって、使いまわしているうちに鍵を因数分解できてしまえば、輸出暗号を受け付けるサーバ⇔クライアント間で、でダウングレードさせての中間者攻撃を行うことができます。

まず、中間者はクライアントからサーバへ提示するプロトコルリストを改ざんして、輸出暗号だけにします。そうすればサーバから512ビットのRSA鍵が来ますので、すでにこの公開鍵に対する秘密鍵が得られていればあとはこっちのものです。クライアントにはそのまま輸出暗号での接続を続けさせれば、サーバへの接続を構築しつつ、ネゴシエーションも完全に解読できるので、中間者攻撃が成立します。

## 亡霊 - FREAK

上述のような攻撃は1998年には報告されていたのですが、時は流れて2015年。どういうわけか輸出暗号を受け入れるままとなっているサーバが大量に存在し、そしてAWSなりでクラウドを借りれば512ビットRSAは半日ほどで解ける、というように、攻撃の方は格段に楽となっていました。そして、もはや時代として求められていないはずの輸出暗号を、ブラウザなどクライアントサイドで受け入れてしまうという脆弱性があって、この期に及んで輸出暗号を使った攻撃が成立してしまうという事態となりました。

対策としては、

* サーバサイド…輸出暗号をオフにする
* クライアント…輸出暗号を受け入れないようにする

ということで、古い暗号を受け付けるままとなっているのは、時として脅威となる、という話でした。

# 脚注

[^1]: SSL 1.0はプロトコルレベルで脆弱性があったため、リリース前に取り下げられています。
[^2]: 実際に使うアルゴリズムはRC4（128ビット）やDES（56ビット）ですが、40ビットを超える鍵を平文で送って、わざと強度を落としていました。
vmware - kaliの環境へ共有フォルダを作成する

ubuntuの設定と同じで、VMware toolsのインストール後に、管理>オプションから共有フォルダを指定するだけです。

1. VMware toolsのインストール  
Player > 管理 > VMware toolsのインストール  
<br>
`$ cd /media/cdrom0`  
`$ sudo cp VMwareTools-10.1.15-6627299.tar.gz /path/to/your/local/file/`  
`$ cd /path/to/your/local/file/`  
`$ sudo tar zxvf VMwareTools-10.1.15-6627299.tar.gz`  
`cd vmware-tools-distrib/`  
`./vmware-install.pl`  
ひたすら、enterで諸設定をする。 
<br> <br>
2. 共有フォルダの指定  
    Player > 管理 > オプション > 共有フォルダ  
    常に有効を選択、追加を選択、共有したいフォルダを選択  
<br>
3. 共有フォルダを確認  
    mnt > hgfs > shareを確認
[*Java*] JJUG CCC 2017 Fall に行ってきた

# はじめに
[JJUG CCC 2017 Fall](http://www.java-users.jp/ccc2017fall/)に参加しました。
前日飲んでたので午後からの参加になりましたが。
その時のメモです。

# セッション一覧
## [DDD × CQRS - コマンドとクエリでORMを使い分けた話](https://www.slideshare.net/koichiromatsuoka/ddd-x-cqrs-orm )
* CQRS・・・書き込み用モデルと読み込み用モデルを分ける
* システムが大きくなると書き込みの制御が複雑化、読み込みは複数テーブル参照…となっていく
* 書き込みと読み込みの要件の違い
* 分離すると処理効率がいい書き方ができてコードがシンプルに
* ORM・・・オブジェクト中心とSQL中心
* オブジェクト中心・・・Hibernateなど
* SQL中心・・・jOOQ、JPQLなど
* HibernateとjOOQは併用できる
* 質問「パフォーマンスは？」　回答「今回は内部システムだったのでそこまで重視しなかった」

## [劇的改善 CI4時間から5分へ〜私がやった10のこと〜](https://www.slideshare.net/aha_oretama/ci-82258405)
* CIの時間が長すぎて深夜に1回しか回せない問題
* CIは速いほうがいい（10分以内がよい、遅くとも20分以内）
* CIが長くなると複数人のコミットが混ざったりして問題があった時の原因特定が難しい
* エンジニアもCIが自分のコミットで回っているのをそもそも忘れる
* CIが終わらなくてリリースが遅れる
* ビルドと単体テストでCIを使っていたが特に単体テストが問題点だった

### やったこと
1. Controller⇛Service⇛Repository⇛RDB…の層をまたぐようなテストを原則しないようにした
2. アノテーションの変更：`@SpringBootTest`はビーンが全部登録されてWebサーバーまで立ち上がってしまうので重い、`@WebMvcTest`は必要なビーンしか登録されないから速い
3. Service層はアプリケーション外とのやり取りがないのでシンプルなJUnitテストをやってDIは使わない
4. （やらなかった）RepositoryでFilterによるBean選択・・・本番のデグレがこわい、稼働しても車輪の再開発になる
5. 負債となったテストの改善： ある程度の規模の開発だとテストが増える、ひとつずつ潰したり、レビューしたり遅かったら潰すなど
6. テストの削除: テスト自体は何回も回すことにメリットが有り、保守しにくいテストを残すとデメリットなので削除する決断を
7. CI再構築＆並列テスト環境構築: CIはそんなに重視してなかったから個人のPCでやっていた ⇛ AWSに移行、金で解決できるものは金で解決した方がいい
8. テストサイズの導入: Googleが提唱するテストサイズの導入、テスト実行タイミング　JUnit `@Category`、`maven-surefire-plugin`のgroupsで実施
9. プルリクエストのFeedBack: プルリクエスト単位で速く開発者にフィードバックするようにした　プルリク上で行えるものを色々フィードバックできるようにした（CIの充実性の向上）　


速くなってフィードバックしやすくなった！

#### 質問:
もっと入り組んだようなシステムもあると思うが今回はちゃんと層が分かれていたからこういう改善ができたということか
#### 回答: 
最近作られたプロダクトで、比較的キレイに作られていたので層にちゃんと分かれている。
コード自体がぐちゃぐちゃだったりする場合はまずはコード自体のリファクタが必要となる。


## [Docker ではじめる Java EE アプリケーション開発](https://www.slideshare.net/KoheiSaito2/docker-java-ee-for-jjug-ccc-2017/1)
* いちいち開発用PCにプロジェクトごとに環境作って…みたいなのはつらい
* 【Dockerデモ】なかなか上手く行かず
* DockerHubからコンテナのイメージをダウンロードしてインスタンス化することで仮想的なプロセスが上がる仕組み
* JavaEE環境がたった3コマンドでできる
* JavaIDEはDockerフレンドリーなものが無い

## [Java 8 Stream APIの代わりにEclipse Collectionsを使って開発してみた](http://slides.com/nashcft/jjug_ccc_2017_fall/#/2)
Eclipse Collectionsのサンプルがいっぱい紹介されてて、ほえーって見てた

## [入社してから運用しているサービスの運用改善奮闘記](https://docs.google.com/presentation/d/1G5fLHaX5-ECgplPel7rwklJ-gUAafqz-lD1-OHpLKy0/edit#slide=id.p)
* 若い女性がターゲットのピクトリンクというアプリの運用、会員1300万人
* 様々なプロジェクトやツールが持っているDBの接続URL⇛DBリプレース時に全プロジェクトファイルを修正
* [The Twelve-Factor App](https://12factor.net/ja/) Ⅲ.設定: 環境変数に設定値を入れてアプリケーションを参照
* `Spring Cloud Config`: リポジトリから設定を取得してJSONとして返却
* JavaScriptの依存関係の解決: フロントエンドでやりたいことが増えた ⇛ ファイル間での依存関係ができた ⇛ 機能を削除しにくい
* `Require.js`を使おうと思ったが依存JS実行が遅い ⇛ `webpack`を使用して一つのJSに！ ⇛ Node.jsの環境が要る、トランスパイルが必要
* 非エンジニアの人にはNode.jsのインストールは敷居が高い
* UIテストの自動化では[Gauge](https://getgauge.io/)を使用
* `Gauge`を使用すると日本語でテスト内容が書ける
* `Selenium`だとプログラムライクになってしまうが、`Gauge`だと非エンジニアでも書けるようになる
* `Gauge`のデメリットとしては、現在ベータ版でバージョンアップすると動かなくなることがある、テストが多くなるとステップの定義がごちゃごちゃになりやすい
* `Gauge`のプロジェクト構成 （`Gauge` ⇛ `Gauge Java` ⇛ `DbUnit`や`Selenide`）
* 改善はコツコツが大事！

# おわりに
いきなり何もかも便利なものを導入するわけにはいかないけど、
少しずつでもコツコツと良い方向に改善していくことが大事だなーと思いました。
Goでとある文章中に任意の文字列が何回出たかruneで数える。

# はじめに。
「このたけがきに　たけたてかけたのは　
　　たけたてかけたかったから　たけたてかけた」

何回「**たけ**」って言ったでしょう～～～？？を
ブラウザではCtrl + Fで答えを知れますが、Goでやる時どうしましょうか。

## どうして。
例えばこの「たけ」が「た」や「け」であればi == rune(た)等でさばけばすぐですが、「たけ」なのでそうもいけません。しかも、私がざっと見た限りはこういったワードマッチング系は標準パッケには「最初に出できた」場合、しかもtrueとかで返す的な感じです。なので書いてみたでござる。

## こうやる。
```go
package main

import "fmt"

var runeSlice = []rune("たけ")
var text = 
`
このたけがきに　たけたてかけたのは　
　　たけたてかけたかったから　たけたてかけた
`

func main() {
  var k int
  var i int
  for _, r := range text {
    if r == runeSlice[k]{
      if k < len(runeSlice)-1 {
        k++
      } else if k == len(runeSlice)-1 {
        i++
        k = 0
      } 
    } else {
      k = 0
    }
  }
 fmt.Printf("%d回", i) //=> 4回
}
```
https://play.golang.org/p/DBC-r4j7LP

こういうのも出来ます。

```go
package main

import "fmt"

var runeSlice = []rune("たけ")
var text = 
`
たけたけ
たけたけたけたけ
たけたけたけたけたけたけたけたけ
`
//2 + 4 + 8 = 14たけ

func main() {
  var k int
  var i int
  for _, r := range text {
    if r == runeSlice[k]{
      if k < len(runeSlice)-1 {
        k++
      } else if k == len(runeSlice)-1 {
        i++
        k = 0
      } 
    } else {
      k = 0
    }
  }
 fmt.Printf("%d回", i) //=> 14回
}
```
https://play.golang.org/p/g_a9S_NPag

要は、まず順番に「た」を探して、「た」が見つかったら次に「け」を探す。
次「け」だったら１ポイント、「け」じゃなかったらまた「た」を探す的な。

# いちいち書くのめんどい
ご用意いたしました。

```go
package main

import "github.com/nnao45/go-wordcount"
import "fmt"

var word = `
このたけがきに　たけたてかけたのは
　　　たけたてかけたかったから　たけたてかけた
`
var kensaku = "たけ"

func main() {
        fmt.Printf("%d回\n", wordcount.WC(word, kensaku)) //=>4回
}
```
https://github.com/nnao45/go-wordcount

他に良い方法ござましたら是非ご指摘お願いします。

# かんそう
Goはマジで日本語に強い・・・。
Microsoft FlowでOneDriveの日本語ファイル名作成変更を通知・コピーする

## 概要
Microsoft Flowを使ってOneDrive fro Businessのファイル変更をSlackに通知したり、別のOneDriveにコピーしようとした際に、日本語ファイルが文字化けしてしまったのでその対応方法をメモ。

しらない間に修正はされそうですが。

## 対応
トリガーとなる処理で、「ファイルが作成されたとき」「ファイルが変更されたとき」を選択する場合、「(メタデータのみ)」を使用すると上手く行った。

<img width="50%" alt="Microsoft_Flow02.png" src="https://qiita-image-store.s3.amazonaws.com/0/101125/90e60e23-8602-022c-b717-cd0a9228acec.png">

ファイルを別のOneDriveに作成する場合は、ファイルコンテンツが必要になるので、間に「Get file content」を挟むと出来た。

## slackへ通知
メッセージテキストは好きに記載する。

<img width="50%" alt="Microsoft_Flow03_slack.png" src="https://qiita-image-store.s3.amazonaws.com/0/101125/28d4af0e-0d0c-5f02-a637-54a7ddc48fa2.png">

## Ondrive for BusinessからOneDriveへ
間にGet file content を挟む(Idを指定する)

<img width="50%" alt="Microsoft_Flow03_onedrive.png" src="https://qiita-image-store.s3.amazonaws.com/0/101125/ea8475c1-d6c0-5698-a1e4-3cdce6b76a6c.png">
AWSライトユーザの自分が感じたGoogle Compute Engineのメリット３つ

Google Cloud Platform（GCP）のCompute Engine。AWSでいうEC2です。

新しいものにはついついガードが上がってしまって色々抵抗感を感じてしまうんですが、そんな自分でもこれはいい！　と思ったもの。

# 前提：自分のスペック

* AWS歴 - 付き合いは3～4年になるけれど、実質高頻度でログインしている期間をまとめると1年にもならないくらいのライトユーザ。EC2利用が主だったが最近LAMBDAに足を踏み入れたとかそんな感じ。
* GCP歴 - 1日。

# メリット１：インスタンスの起動時に月額コストがわかる

* 明朗会計最高です。

# メリット２：インスタンス直後から、勝手に外部IPを割り当ててくれる

* だから、外部IPってもんがないとインターネットからはアクセスできない…ってことを知らなくてもなんとかなる。多分。
* ここ、AWSだといちいち確保して割り当てるの面倒だったのでいきなり使えるのは超嬉しい
* デフォルト（エフェメラルIP）ではインスタンスを再起動するとIPが変わってしまうけれど、インスタンスを再起動できる時点でもうIPくらいわかっとけってことなんだ、きっと。
* ちなみにエフェメラルIPから静的IPへの変更も簡単でいい。その際にIPが振り直されて変わってしまうのはご愛嬌。

# メリット３：さらに、SSH接続がWEBからできる

* ちょいちょい文字化けします。押すキー間違えるとウィンドウがフリーズします。
* でも、それでももうこれでいいやってくらい便利。
* 正直、SSHの新しいインスタンス立ち上げるたびにターミナルで疎通確認とかするの、もういやになってたのかもしれない自分に気づける。

# 所感

* Googleといえばスーパー技術者集団なイメージですが、GCPは、技術的知識がないひとがそれっぽいことをするにあたり初動時の精神的な障壁ができるかぎり低くなるよう工夫されている気がしました。
* Go言語も、あまり技術力が高くなくてもちゃんと書ける言語として設計されている的な話を聞いたことがあるんですけど、なんかそっちのほうに力注いでいるのかな、と。
[Spring Boot] @Scheduled のスレッドプールサイズでハマった話

Spring Boot でタスクを定期実行するには @Scheduled を指定するのが手軽で良い。
だが @Scheduled のデフォルトスレッドプールが**シングルスレッド**ということを知らないと、思わぬ落とし穴にハマるのでご注意を。

## ハマったケース

次のような構成でプールサイズを意識しないで実装すると、ClassB の処理でスレッドが掴まれたままで ClassA の処理が行われなくなる。

### 構成

ClassA.java というクラスで「毎分 0秒 と 30秒 に処理を行う」設定をし

```java:ClassA.java
@EnableScheduling
ClassA {

    @Scheduled(cron = "0,30 * * * * *")
    public void execute() {
        // todo
    }
}
```

ClassB.java というクラスで「起動後 60秒 経ったら処理を行い、その処理が終了した後に 30秒 経ったら次の処理を行う」という設定をした。

```java:ClassB.java
@EnableScheduling
ClassB {

    @Scheduled(initialDeley = 1000 * 60, fixedDelay = 1000 * 30)
    public void execute() {
        // 他の処理の結果を受けて処理を終了するポーリング
    }
}
```

### スレッドが掴まれる状況

```:スレッドが掴まれる可能性のあるケース
                  16:00:00          16:00:30           16:01:00
ClassA.java |---------+-----------------+-----------------+------------>
            |
            |                               起動後 60秒
ClassB.java |-------------------------------------+-------------------->
```

この図の説明をすると

* ClassA では 16:00:00、16:00:30、16:01:00 と、30秒 毎に処理が定期的に行われる
* ClassB では起動後 60秒 経過してから最初の処理が行われる

ことを想定したものである。
で、

* ClassB の処理が (ここでは登場しない) 他の処理の結果を受けて処理を終了するポーリング処理で、延々と処理をし続ける

ことになった場合、

* ClassA は 16:01:00 の処理がいつまでたっても開始されない

状態に陥る。これは

* @Scheduled のデフォルトスレッドプールが**シングルスレッド**

であることが原因で、**ClassB のポーリング処理がスレッドを掴みっぱなしになっている**ために発生する。

このケースで厄介なのは、ClassA の方では初回の 16:00:00 と 16:00:30 の処理がしっかり行われること。
デバッグ実行でブレイクポイントを貼ったとき、16:01:00 の処理からブレイクポイントに止まらないため @Scheduled の設定に問題があるとばかり思ってそちらの調査に時間を割いてしまっていた。

## スレッドプールサイズの変更方法

上記のような状況を回避するにはスレッドのプールサイズを変更してやれば良い。
(もちろん ClassB の状況次第では延々とポーリングし続けて、いつまでたっても一回の処理が終了しない、というのも解決すべき問題であるが。。。)

その方法について後述の参考サイトに例が記載してあるが、それを転載すると

```java:ExampleConfiguration.java
@Bean
public ThreadPoolTaskScheduler  taskScheduler(){
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(2); // プールサイズを変更する
    return  taskScheduler;
}
```

といった感じで ThreadPoolTaskScheduler を @Bean 登録してやり、その際に **setPoolSize でプールサイズを設定**してやれば良い。

## 参考

* [Does spring @Scheduled annotated methods runs on different threads?](https://stackoverflow.com/questions/21993464/does-spring-scheduled-annotated-methods-runs-on-different-threads)
* [27. Task Execution and Scheduling](https://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#scheduling)
DockerにPostgreSQL10を入れてみた

# 参考サイト
[Docker Hub](https://hub.docker.com/_/postgres/)

# イメージ取得
- 以下のコマンドをローカルで実行し、イメージを取得  
今回は[Version 10.1]を使用する。

```
docker pull postgres:10.1
```
- 取得できたことを確認

```
docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
postgres            10.1                599272bf538f        7 days ago          287MB

```

# インスタンスの起動

参考サイトの
>start a postgres instance  

に記載されたコマンドを参考に実行  
[POSTGRES_PASSWORD]には[postgres]用ユーザーのパスワードを指定するらしい。　　
なので、お好きなパスワードを指定してください。

```
docker run --name postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres:10.1
```

起動確認

```
docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
b16b102cb76c        postgres:10.1       "docker-entrypoint..."   11 seconds ago      Up 10 seconds              5432/tcp            some-postgres
```

# PostgreSQL実行
まずはコンテナを実行

```
docker exec -it some-postgres bash
```

ログイン

```
psql -U postgres
```

データベース一覧を表示

```
postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)
```

---

以上です。

今回はDocker上にDjangoの開発環境を構築する予定なので、
引き続き他の環境も構築したいと思います。
Windows の Git Bash で Python の REPL が起動しないことへの対処法

Windows の Git Bash で Python の REPL が起動しなくてハマったので、その対処法です。

## 検証に使った環境

Windows 10 Home
Git for Windows v2.13.1
Python 3.6.2


## 問題と対処法

Git Bash で

```
$ python 
```

と打っても REPL が起動せず、止まったまま。
なぜだと思ってググったら

```
$ winpty python.exe
```



のように実行すれば動くとのこと。
実際にやってみて動いた。

お好みなら、
.bashrc に 
`alias python='winpty python.exe'`
の行を追加するとよいとのこと。

マジか・・・。全然知らなかった。


## 参考

[windows - Python not working in the command line of git bash - Stack Overflow]
https://stackoverflow.com/questions/32597209/python-not-working-in-the-command-line-of-git-bash
Go言語でMarkdown・HTMLのリンクを爆速チェックするコマンド書いた

# 動機

ReadmeとかドキュメンテーションとかよくMarkdownで書くと思いますが、リンクが切れてないか手作業で点検するのがだるいので自動チェックするコマンド書きました。爆速です（当社比）。

名前は[liche](https://github.com/raviqqe/liche)。

# こんな感じで動きます

[![asciicast](https://asciinema.org/a/148896.png)](https://asciinema.org/a/148896)

# 機能

`<a/>`の`href`と`<img/>`の`src`属性に指定されているURLに対してHTTPリクエストを送りチェックします。相対パスや絶対パスもチェックできますが、絶対パスをチェックするときはドキュメントルートディレクトリの指定が必要です。

他の機能としては、

- 再帰的にディレクトリを廻ってMarkdown・HTMLファイルを探す
- HTTPリクエストの並列度を調整する
- HTTPリクエストのタイムアウトを設定する
- チェックが成功したリンクも表示する

などです。

```
> liche --help
Link checker for Markdown and HTML

Usage:
	liche [-c <num-requests>] [-d <directory>] [-r] [-t <timeout>] [-v] <filenames>...

Options:
	-c, --concurrency <num-requests>  Set max number of concurrent HTTP requests. [default: 512]
	-d, --document-root <directory>  Set document root directory for absolute paths.
	-r, --recursive  Search Markdown and HTML files recursively
	-t, --timeout <timeout>  Set timeout for HTTP requests in seconds. Disabled by default.
	-v, --verbose  Be verbose.
```

# 実装

- Markdown・HTMLファイルを探す処理
- ファイル内のURLをチェックし結果をまとめる処理
- URLをチェックする処理

の３つの処理をgoroutineで並列に回し、channelでつなげています。これによって上のターミナルキャプチャのようにチェックが終わったファイルの結果がどんどん表示されていきます。

# まとめ

Markdown・HTMLファイル内のリンクを爆速チェックするコマンド[liche](https://github.com/raviqqe/liche)を書きました。CIとかで走らせるのが手間もかからずよいと思います。

また、`ulimit -n`でリミット解除し、`--concurrency`をギリギリまで上げるとパソコンをいじめられます。ぜひお試しください。
sys.pathの最初の要素


``sys.path``は、Pythonがインポートするモジュールを検索するパスのリストですが、コマンドラインから起動するスクリプトの指定方法により`sys.path`の最初の要素が変わります。

例えば、カレントディレクトリ`/home/user1`に、`test.py`とPython packageディレクトリ`test`があるとします。

```
test.py
test/
    __init__.py
    __main__.py
```
`test.py`と`test/__main__.py`には、sys.pathを出力する下記のコードが入っています。(Python3)


```py3
import sys
print(sys.path)
```
まず、スクリプトファイルをコマンドライン引数としてPythonを起動した場合、`sys.path[0]`は、そのスクリプトがあるディレクトリがセットされます。

```shell-session
$ python test.py
['/home/user1', ...]
```

`-m`オプションで実行するモジュール(パッケージ)を指定した場合、`sys.path[0]`は、空白列`''`がセットされます。これはカレントディレクトリと解釈されます。

```shell-session
$ python -m test
['', ...]
```
引数無しで、Interactive modeでPythonを起動した場合や、`-c`オプションで実行するコードを与えた場合も、同様に`sys.path[0]`には、空白列`''`がセットされます。

```shell-session
$ python
>>> import sys; print(sys.path)
['', ...]
```
```shell-session
$ python -c "import sys; print(sys.path)"
['', ...]
```

`__main__.py`を含むディレクトリを実行するスクリプトに指定した場合、`sys.path[0]`は、そのディレクトリの名前がセットされます。

```shell-session
$ python test
['test', ...]
```

*参考*

* https://docs.python.org/3/using/cmdline.html
* https://docs.python.org/3/library/sys.html#sys.path
node.js Tips

ソースコード修正するたびに、npm startするのはめんどくさい
--
ソースコードを変更すると自動でサーバーをrestartしてくれるnodemonを使おう

npm i -g nodemon

以降
nodemon start
でサーバー実行

参考:https://qiita.com/twipg/items/cb969b335d66c4aee690

npm コマンド集
--
参考:https://qiita.com/yoh-nak/items/8446bf12094c729d00fe

Jade
--
npm install -g jade

書き方の参考:https://blog.mismithportfolio.com/web/20160117jadebeginner

対象jadeファイルが存在するディレクトリにて
下記コマンドでhtmlに書き出しを行い確認可能

jade top.jade --pretty

同じディレクトリにhtmlファイルが作成される

forever
--
いちいちサーバーを起動しなくても済む
ただし、ソースコードを変更などした場合はrestartする必要あり
Zabbixにホストを追加する

## 概要
Zabbixに監視対象のホストを追加します。
Zabbixは初めてインストールして触り始めたばかりなので、まだまだ未熟です。
テンプレートもよく分かっていないので、それっぽいのを選んでいます。

・Window用エージェントのインストール参考
[Windows用ZabbixエージェントをCドライブ直下以外のconfを使用してインストールする](https://qiita.com/flat9th/items/cf5cd326be3926987ce5)

## 環境
* サーバー
    * Zabbix 3.4
    * CentOS7.2

* クライアント(エージェント)
    * Windows Server 2012 R2

## ホストの作成画面を開く
Zabbixに接続します。

* 設定 > ホスト > ホストの作成

をクリックします。

<img width="50%" src="https://qiita-image-store.s3.amazonaws.com/0/101125/6f4bc4de-8f4e-1652-0ea4-2a54d306288e.png">

## ホストの入力
ホストの情報を入力します。
「ホスト」タブと「テンプレート」タブに入力してから「追加」します。

> ホストの入力

* ホスト名を入力
ホスト名を入力します。自分はホストのIPにしたのですが、名前でもよい？のかは不明です。

* 表示名を入力
Zabbix上で表示される表示名を入力します。対象のPC名とかIPとか、分かりやすし名前で良いと思います。

* グループを指定、もしくは新規グループを作成
グループを指定します。グループは必須のようなので、何かしら指定します。
複数選択可能です。
既存のその他のグループから選択するか、無い場合は新規グループ作成にグループ名を入力します。

* エージェントのインターフェースでIPアドレスを入力
監視対象のサーバーIPアドレスを入力します

<img width="50%" src="https://qiita-image-store.s3.amazonaws.com/0/101125/bfa80dd4-84ed-2070-edc4-d21afd9d0520.png">

> テンプレートを選択する

* テンプレートタブをクリックします
* 選択ボタンをクリックするとテンプレート一覧が表示されるので、目的に合ったテンプレートを選択します
今回エージェントがWindowsだったので、「Template OS Windows」を選びました。

* **リンクになっている「追加」**をクリックします(ボタンではなく、リンクの追加)
ここでリンクの追加をクリックしないと、追加ボタンを押しても反映されないです

<img width="50%" src="https://qiita-image-store.s3.amazonaws.com/0/101125/e6c2f40e-4548-7bf2-dc6c-5dc11b763534.png">

* テンプレートが追加されたことを確認して「追加」ボタンをクリックする

<img width="50%" src="https://qiita-image-store.s3.amazonaws.com/0/101125/17d4a632-37b2-1066-0e3a-866b269ecdf4.png">

## 確認
ホストの一覧に戻って、エージェントの状態を確認します。
待つ場合、エージェント認識まで結構時間がかかります(５分？１０分？くらいかかった気が)
エージェントが認識できれば以下のように「ZBX」が緑になります。

<img width="50%" alt="11_エージェント確認.png" src="https://qiita-image-store.s3.amazonaws.com/0/101125/3ea61f14-88e1-b787-e60d-1bd32a64311f.png">

以上です。
boot2dockerを仮想マシンで使う場合のメモ

* [boot2dockerのデータ永続化まとめ](https://qiita.com/tukiyo3/items/07f1eb77b5ffd9031e30)

* user:pass = docker : tcuser
* 消えない場所 : /var/lib/boot2docker/
* 他と比べて良いと思った点
    * 起動時にrootでログインされている状態になる。
    * 軽い
    * OSインストールしなくても動く
    * メンテナンスが続いている

## IPアドレス固定

* [How to configure static IP address for boot2dock VM · Issue #129 · boot2docker/boot2docker](https://github.com/boot2docker/boot2docker/issues/129#issuecomment-34293127)

```rb:/var/lib/boot2docker/bootlocal.sh
# DHCP無効
killall udhcpc
# IP固定
ifconfig eth0 192.168.100.46 netmask 255.255.255.0 up
echo nameserver 8.8.8.8 >> /etc/resolv.conf
route add default gw 192.168.100.1
```

## timezone

```sh:/var/lib/boot2docker/profile
export TZ="JST-9"
```

## sshパスワード認証無効化

```sh:
sudo sed -i -e "s/^#PasswordAuthentication no/PasswordAuthentication no/" \
 /var/lib/boot2docker/ssh/sshd_config
```

```sh:バックアップ(ssh-copy-idは済ませておく)
cp -a /home/docker/.ssh /var/lib/boot2docker/opt/
```

```sh:/var/lib/boot2docker/bootlocal.shに追記
# home
if [ ! -e /home/docker/.ssh ];then
    cp -a /var/lib/boot2docker/opt/.ssh /home/docker/
fi
```



## docker-composeの取得

https://github.com/docker/compose/releases

```sh:docker-composeの取得
sudo mkdir /var/lib/boot2docker/opt
sudo chown docker:staff /var/lib/boot2docker/opt
cd /var/lib/boot2docker/opt

# ダウンロード
export VERSION="1.17.1"
curl -L https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-`uname -s`-`uname -m` \
 > docker-compose

chmod +x docker-compose
```
CVE-2017-2641 を使ってMoodleサイトを攻撃してみる

# イントロ
Webアプリには脆弱性はつきものだが、Moodleにも時々重大な脆弱性が発見される。実際にこの脆弱性を利用してMoodleサイトを攻撃してみる。
あと次回では防御方法を考える。

## おことわり
このメモを試す場合は**必ず**自分の管理しているMoodleサイトで行うこと。いろいろと大事なものを失う可能性があるよ？

# CVE-2017-2641 について
## 概要
[CVE-2017-2641](http://www.cvedetails.com/cve/CVE-2017-2641/)はMoodle 3.2.1以前に存在するSQLインジェクション攻撃で、ユーザプリファレンス機能の脆弱性を利用している。
[Moodle公式サイト](https://moodle.org/mod/forum/discuss.php?d=349419)にも記載があり、[commit diffを確認](https://git.moodle.org/gw?p=moodle.git;a=commitdiff;h=6e65554ea19f4e90c09864081e47424f8efca02e)すると*unserialize()*にユーザ入力を渡しているのが問題点だと見られる。

## 実証コード (PoC)
わざわざ貼らないが、ググるとPoCが見つかるので、それを使って試してみる。試したPoCではDBを更新させるためのオブジェクトを作成してserializeしたものをJSONにしてPOSTしている。
ここで攻撃に必要になるのは以下のものになる。

- 攻撃対象のMoodleサイトのユーザアカウント
- ログイン時のCookieのMoodleSessionの値
- ログイン時のMoodleのsesskeyの値
- ログインユーザのユーザID

このPoCでは実行時にユーザプリファレンス設定ページにアクセスする必要があるため、ゲストユーザでは攻撃は行えない。また、利用している*update_user_preferences()*がMoodle 3.2以降にしか存在しないため、Moodle 3.1.x以前ではこのPoCは動作しないように思える。従ってMoodle 3.2(.0)および3.2.1が対象となる。
このPoCでは、”任意のテーブルの任意のフィールドを行idを指定して更新すること”が可能であることが示されており、実際にPoCではconfigテーブルのサイト管理者のIDを指定している行をSQLインジェクションで更新し、指定したユーザIDを持つユーザをサイト管理者としている。
インストール時の設定によってはテーブル名に*mdl_*とかプリフィックスがついている事があるが、Moodle側で勝手に補完してくれるから分からなくても安心♪

## 実際に攻撃してみる
### 標的サイトの準備
[過去の記事](https://qiita.com/papillon/items/4c82e2af320d631f0284)に従ってMoodle 3.2のサイトを構築し、ここに「サイト管理者」と「一般ユーザ」の2つのアカウントを作成する。

### 事前準備
一般ユーザでログインする。
![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/845aecf8-9a8c-1de1-8966-69cd0a85816d.png)

ヘッダ情報からMoodleSessionの値を調べる。
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/253f94bd-5fb2-4dfd-2bc5-f66d45bb8a6c.png)

ユーザIDを調べる。
![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/001f7a7a-83c9-4336-a314-822ef7fdb28a.png)

sesskeyの値を調べる。
![キャプチャ4.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/1279bfb7-a6b1-3117-1cc9-44d3013d5227.png)

### PoCの実行
これらの値を利用してPoCを実行する。実行すると下記の値が正常な値の代わりに送信される。

```
a:2:{i:0;a:1:{i:0;O:29:"gradereport_overview_external":0:{}}i:1;O:40:"gradereport_singleview\local\ui\feedback":1:{s:5:"grade";O:11:"grade_grade":1:{s:10:"grade_item";O:10:"grade_item":6:{s:11:"calculation";s:12:"[[somestring";s:22:"calculation_normalized";b:0;s:5:"table";s:6:"config";s:2:"id";i:25;s:5:"value";i:3;s:15:"required_fields";a:2:{i:0;s:5:"value";i:1;s:2:"id";}}}}}
```

### 確認
一度ログアウトしてから再度ログインすると一般ユーザがサイト管理者になっている。（サイト管理用メニューが表示されている）
![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/bdc3b95e-8c78-9b0e-8a1b-84633ef01580.png)

DBを確認するとサイト管理者のユーザIDが書き換えられていることが確認できる。本来は2になっている（1はゲストユーザ）。
![キャプチャ6.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/b448e732-a0dd-6752-deef-8d407c8c3881.png)

代わりに管理ユーザでログインするとサイト管理者で無くなっていることが分かる。
![キャプチャ7.PNG](https://qiita-image-store.s3.amazonaws.com/0/63695/5e9989c5-3e5c-ec9e-5e72-d1a11606c0e1.png)

### その他
下記のように指定するとMoodleサイトの```longname```を書き換える事ができる。

```
$table = 'course';
$rowId = 1;
$column = 'fullname';
$value = 'ALL YOUR MOODLE ARE BELONG TO US!';
```

### 解説メモ
[このブログ](http://netanelrub.in/2017/03/20/moodle-remote-code-execution/)のPart3まででこの脆弱性でSQLインジェクション攻撃ができる説明がされている。
しかし今回のPoCで必要な行IDが必要な問題についてPart4で検討している点が異なっている。
AndroidでSceneとDataBindingを一緒に使う

こんにちは。仕事でAndroidプログラムをやってるものです。
きょうは、最近仕事でやったことについて、知見を共有したいと思います。
ソースだけ見たい方は以下のリポジトリへどうぞ。(この記事もほとんどソースですが…)
[サンプルソース](https://github.com/Shiozake/AndroidSceneDataBindingSample/tree/master)

# テスト環境
macOS High Sierra
Android Studio 3.0.1

# ベース画面作成
レイアウトファイルを作成します。Sceneを設定したいViewGroupにIDを振っておきましょう。

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scene_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</FrameLayout>
```

# Scene用のレイアウト生成
レイアウトファイルを作成します。データなどは適当に設定してます。

```xml:scene_a.xml
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="description"
            type="String"/>
        <variable
            name="buttonText"
            type="String"/>
        <variable
            name="onClickListener"
            type="android.view.View.OnClickListener"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="シーンA"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:text="@{description}"
            tools:text="説明"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{buttonText}"
            android:onClick="@{onClickListener}"/>

    </LinearLayout>

</layout>
```

# SceneとDataBindingの連携

Bindingから作成したレイアウトとSceneを連携させます。

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    private Scene sceneA;
    private Scene sceneB;
    private Scene sceneC;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LayoutInflater inflater = LayoutInflater.from(this);
        ViewGroup sceneRoot = findViewById(R.id.scene_root);
        sceneA = createSceneA(inflater, sceneRoot);
        // sceneB・Cも同様に

        // 最初のシーンAへ
        TransitionManager.go(sceneA);
    }

    private Scene createSceneA(LayoutInflater inflater, ViewGroup sceneRoot) {
        SceneABinding binding = SceneABinding.inflate(inflater, sceneRoot, false);
        binding.setDescription("これはシーンAです。");
        binding.setButtonText("シーンBに行こうね");
        binding.setOnClickListener(view -> TransitionManager.go(sceneB));
        return new Scene(sceneRoot, binding.getRoot());
    }
    // createSceneB・Cも同様に
}

```

これでSceneとDataBindingを連携させることができました。

# まとめ
以上で説明は終わりです。
何か不明な点・間違いがあったらコメントで指摘おねがいします。
Kotlin覚書 - varargを代入する方法

# 可変長引数vararg
今日はまたハマったので、メモです。

varargについての説明は色んな所にあるので、あんまり記述はしません。
▼公式リファレンス（日本語訳版？）
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/functions.html

# 使い方
## Javaの使い方
Javaだとこんな感じで使われてますね。

```:java
private String[] mItems

public void items(@NonNull final String... items) {
    mItems = items;
}
```

引数をString...とやるとArray（配列）で渡すことができます。
そもそもKotlinだと、配列は
`Array<T>`
で表すことができます。
ということで、Kotlinでの使い方を見てみましょう。

## Kotlin化してみる
↑のJavaのコードをKotlin化します。

```:kotlin
var mItems: Array<String>? = null // itemsメソッドで代入するのでvar。

fun items(varargs items: String) {
    mItems = items   //　エラー
}
```

### エラーになる
Javaと同じように、そのまま配列のフィールドに代入しようとすると、エラーになります。
ようするにvarargsの値はそのまま代入できません。

### エラーの原因
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151973/aac991cb-7fa3-fa21-5a70-6ad6c83f8182.png)

どうやら、varargsは配列として渡せますが、`Array<out T>`という型になっているようです。

### 対処法

StackOverflowに書いてあります。
https://stackoverflow.com/questions/44090019/how-to-pass-vararg-as-array-to-function-in-kotlin

リファレンスにも書いてあります。
`すでに配列を持っており、関数にその内容を渡したい場合は、（ * を配列名の接頭辞にする）` ([公式リファレンス](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/functions.html)より引用)

ということで、kotlinの場合は以下のようになります。

```:kotlin
var mItems: Array<String>? = null

fun items(varargs items: String) {
    mItems = arrayOf(*items)
}
```

ようするに、Array<out String>型の値を、Array<String>で作り直した上で代入します。

他にいい方法があれば教えて下さいー！！
【CUI/CLI】ショートカットコマンド作成スクリプト【alias】

# はじめに

突然ですが僕はCUIが大好きです．
基本的にはCUIで作業しています．

そして趣味は定形作業の自動化です．

そんなわけで，僕は頻繁にアクセスするディレクトリにはエイリアスを貼り，
コマンドひとつでそのディレクトリへ飛べるようにしています（ショートカットコマンド）．

というわけで，今回は
「CUIでショートカットコマンドを作成するさいに，
わざわざ.zshrcにaliasを貼るわずらわしさ」を解消すべく
『ショートカットコマンド作成スクリプト』を実装します！

\* 注意：zshかつmac OS上でしか動作テストをしていません．

# 従来のショートカットコマンド作成方法（我流）

1. ショートカットコマンドを作成したいディレクトリのパスを調べる
2. エディタで.zshrcを開く 
3. 手順1で調べたパスをaliasで登録する
4. zshに設定を反映する

めんどくさいですよねー

# ショートカットコマンド作成スクリプト

```zsh:makeShortcut.sh
# 第一引数がショートカットコマンド名となる
# 引数が1つの場合のみショートカット作成コマンドを実施
if [ $# -eq 1 ]; then
	echo "alias $1='cd $PWD/'" >> ~/path/to/.zshrc &&
	echo "\nMaking Shortcut is Done" &&
	echo "  >> $PWD" &&
	exit 0
else
	echo "[ERROR] Argument Error"
	exit 1
fi

# シェルの更新をここで行うので
# 本スクリプト実行後にすぐショートカットコマンドを使用可能
exec $SHELL
```

やっていることは
”登録したいaliasをechoで.zshrcに追記”
しているだけです．


## 使い方
1. ショートカットコマンドを作成したいディレクトリに移動
2. 本スクリプトを実行

ね，手順が減った😊

## tips

```zsh:.zshrc
alias mksh='makeShortcut.sh'
```

僕は上記のように.zshrcにaliasを貼ることで

```
$ mksh SHORTCUT_COMMAND_NAME
```

これでショートカットコマンドが作成できるようにしています．
（PATHを通しておく必要あり）

# おわりに

簡単なスクリプトですが役に立ちます
jquery , javascript でカンマ区切り numberformat

numberformat、つまり 1000 を 1,000 にしたい。
phpなら簡単だけど、jsならどうすんの？
といったお話。

https://github.com/customd/jquery-number

からライブラリをDLして読み込み。
そして

```html
<span class="number">153451</span>
```

```js
$(function() {
$('.number').number(true);
});
```

```html:結果
<span class="number">153,451</span>
```

となる。とりあえず、iphoneのsafariでも動いたのでこれはおすすめ。
[Fusion360]休憩時間にfusion360と遊ぶ その5。

お久しぶりです。

時間があるとfusion 360 
よく一人で勉強したり、いじったりしています。

fusion 360 始めた時間が何か月すごしました。
気づいたのは、モデリング時間がはやくなりました。

ARDUINOのケース。

![EMMM001.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/8ea972e0-3cf6-0908-4a6b-03914d5cdbe2.jpeg)

![EMMM002.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/6d8d64ed-075a-3e22-5b03-58757b536c5a.jpeg)

![EMMM003.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/dba74eda-e83f-d9e9-171f-fe348746742a.jpeg)

#おまけ

watchを作る必要があったので、モデリングしたあと、
３Ｄプリンター作ってつくってみました。


![EMMM004.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/8179bfa7-2dd3-4332-0803-8ea2c2b052ef.jpeg)


![IMG_6094.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/e3db002c-0a56-81f7-d42a-a4a2e2db147c.jpeg)
GTX1080Ti搭載のWindows10パソコンにUbuntu16やらCUDAやらインストールする流れ（４）

#はじめに
買ってきたWindowsパソコン（GTX1080Ti搭載）に諸々設定する流れ。

ubuntuインストールするまではこちら。
https://qiita.com/masataka46/items/9548b70cc71248cc1456
その後、CUDA、cuDNNを入れるまではこちら。
https://qiita.com/masataka46/items/0ef2223d22f841b8bfb8#_reference-e76b9ba29c8104716dd1
その後、pyenv環境にpython3を入れた経緯はこちら。
https://qiita.com/masataka46/items/b5e0d39c1e3fd31e649c

今回はtensorflowとCaffe、chainerを使えるようにする。

スペック：
デフォルトのOS:Windows10 64ビット
インストール後：Ubuntu16.04 LTS
CPU:Corei7 7700K
GPU:GTX1080Ti
SSD:240GB
HDD:2TB
マザーボード:ASUS H170-pro
CUDA-8.0
cuDNN-6

pyenv
python3.6.3
など

#Tensorflowのインストール
公式ドキュメント
https://www.tensorflow.org/install/install_linux#ValidateYourInstallation
に従って進める。

pyenv環境という以外は native に入れるようなものなので、`Prerequisite: Python and Pip`の手順に従う。

まず

```shell-session
pyenv global 3.6.3

```
などとしてpyenv環境に入る。次にpip など必要なパッケージ類のインストール

```shell-session
sudo apt-get install python3-pip python3-dev
```

GPUヴァージョンでtensorflowをインストールする。

```
pip3 install tensorflow-gpu
```

ちゃんとインストールされたか確認する。Pythonの対話モードで以下を入力。

```python
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
```

Hello, TensorFlow と表示されたら大丈夫。GPUがどうたらこうたら出てるのでCUDAとかも機能してそう。

#Caffeのインストール
Openposeと一緒にCaffeをインストールする。
https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md

まずopencvとOpenBLASをインストール。

```
sudo apt-get install libopencv-dev
sudo apt-get install libatlas-base-dev
```

次にOpenPoseと一緒にCaffeをインストール。

```
./ubuntu/install_caffe_and_openpose_if_cuda8.sh
```

#chainerのインストール
次にchainerのインストールを行う。こちらも公式ドキュメント
http://docs.chainer.org/en/stable/install.html
に従う。

まず `setuptools`のupgradeから。

```
pip3 install -U setuptools
```

次に`pillow`と`h5py`と`cupy`をインストールする。

```
pip3 install pillow
pip3 install h5py
pip3 install cupy
```

次に`chainer`のインストール。

```
pip3 install chainer
```

一瞬で終わった。

#chianerのエラー対応
`chainer`の動作確認で以下を実施。

```shell-session
wget https://github.com/chainer/chainer/archive/v3.1.0.tar.gz
tar xzf v3.1.0.tar.gz
python chainer-3.1.0/examples/mnist/train_mnist.py

......
......
ModuleNotFoundError: No module named '_tkinter'
```

`_thinker`なるものが無い、と出た。調べてみると、このサイト（１）
https://qiita.com/4hiziri/items/aba80f0bc92300ea22e2
では`pyenv`で`python`を入れる前に`tk-dev`を入れろ、と書いている。

残念ながら`pyenv`のインストールからやり直し。

```shell-session
sudo apt-get install tk-dev
```
mysql5.7:SQL_JSON型データ集計検証


json型で1カラムにリスト情報を持たせてリスト内の項目をKEYにしてを検索できるなら、mysql5.6から5.7にverupしたいと思い調査。できなかったので、5.7へのverupは断念した。

# 環境構築
Vagrant(Ubuntu14.04)にて下記のコマンドでさっくり構築

```
sudo apt-get remove --purge mysql-server* mysql-common
wget https://dev.mysql.com/get/mysql-apt-config_0.8.1-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.1-1_all.deb
sudo apt-get update
sudo apt-get install mysql-server
```

# 検証
この記事のSQLを突っ込んで検証。

```
create table json_test  ( `col` JSON)
INSERT INTO `json_test` VALUES ('{"x":10, "y":20}'), ('{"x":20, "y":40}'), ('{"x":30, "y":60}'), ('{"x":40, "y":80}'), ('{"x":50, "y":100}');
INSERT INTO `json_test` VALUES ('{"x":10, "y":21}'), ('{"x":20, "y":41}'), ('{"x":30, "y":61}'), ('{"x":40, "y":81}'), ('{"x":50, "y":101}');
create table json_test2  ( `col` JSON)
INSERT INTO `json_test2` VALUES ('[10,20,30,40,50]'), ('[11,21,31,41,51]'), ('[12,22,32,42,52]'), ('{"x":40, "y":80}'), ('{"x":50, "y":100}');
create table json_test3  ( `col` JSON)
INSERT INTO `json_test3` VALUES ('{"x":1,"y":[10,20,30,40,50]}'), ('{"x":2,"y":[11,21,31,41,51]}'), ('{"x":3,"y":[12,22,32,42,52]}');
```

JSON_EXTRACTでjson型を使えるっぽい。

```
select  JSON_EXTRACT(`col`, '$.x') as x, JSON_EXTRACT(`col`, '$.y') as y from json_test order by x ,y
# x, y
'10', '20'
'10', '21'
'20', '40'
'20', '41'
'30', '60'
'30', '61'
'40', '80'
'40', '81'
'50', '100'
'50', '101'
select  JSON_EXTRACT(`col`, '$.x') as x , SUM(JSON_EXTRACT(`col`, '$.y')) from json_test  group by x
# x, SUM(JSON_EXTRACT(`col`, '$.y'))
'10', '41'
'20', '81'
'30', '121'
'40', '161'
'50', '201'
select  JSON_EXTRACT(`col`, '$.x') as x , MAX(JSON_EXTRACT(`col`, '$.y')) from json_test  group by x
# x, MAX(JSON_EXTRACT(`col`, '$.y'))
'10', '21'
'20', '41'
'30', '61'
'40', '81'
'50', '101'
```

リストをたて列に直すのは調べても大変そう。
array select mysql5.7とかで調べたらみんな苦労してそうだったのでもういいか、という結論になりました。

```
select  JSON_EXTRACT(`col`, '$.x') as x, JSON_EXTRACT(`col`, '$.y') as y from json_test3 order by x ,y
# x, y
'1', '[10, 20, 30, 40, 50]'
'2', '[11, 21, 31, 41, 51]'
'3', '[12, 22, 32, 42, 52]'

select  JSON_EXTRACT(`col`, '$.x') as x, JSON_EXTRACT(`col`, '$.y[1]') as y from json_test3 order by x ,y
# x, y
'1', '20'
'2', '21'
'3', '22'
```
《JavaScript》画像を抽出して、波打たせるようなアニメーションをcanvasに描く。

`drawImage()` で、抽出と描画座標をずらして呼び出しを繰り返すと、波打つようなアニメーションが実現できます。

* [drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)－Canvasリファレンス](http://www.htmq.com/canvas/drawImage_s.shtml)

ずっと見ていられる感じと、素材となる画像によっていろんな表情になるのが素敵かな、と思います。





##  demo

マウスオ−バーすると画像が現れます。

* [canvas image wave effect](https://jsfiddle.net/yutousui/4m8yreqz/)



## Html

```html

<canvas id="canvas" data-src=test.jpg" width="300" height="300"></canvas>

```





##  JavaScript

```js

/**
 * 画像を抽出して、波打たせるようなアニメーション
 * マウスオーバーすると画像が現れる
 */
const waveAnim = () => {

  let canvas  = document.getElementById('canvas'),
      ctx     = canvas.getContext('2d'),
      canvasW = canvas.width,
      canvasH = canvas.height,
      img     = new Image();

  img.src = canvas.getAttribute('data-src');

  /**
   * 停止させるためのid
   */
  let animId;

  /**
   * 読み込み位置を管理する
   */
  let x = 1,
      r = -1;

  /**
   * 画像の横1px縦いっぱいの色情報で塗りつぶす
   */
  const wave = () => {

    /**
     * 反転させる
     */
    x == canvasW ? r = -1 : 0 == x && (r = 1);

    ctx.drawImage(img, x, 0, 1, canvasH, -x, 0, canvasW + x, canvasH);
    x += r;

    /**
     * setInterval で速さを決めたり可変させてもいい
     */
    animId = requestAnimationFrame(wave);

  };
  img.onload = wave;


  /**
   * 波打ちながら元画像が現れる
   */
  const show = () => {

    ctx.drawImage(img, x, 0, 1, canvasH, x, 0, canvasW, canvasH);
    x < canvasW ? (x++) : cancelAnimationFrame(animId);

    animId = requestAnimationFrame(show);

  };


  /**
   * アニメーションのリセット
   */
  const reset = () => {

    cancelAnimationFrame(animId);
    ctx.clearRect(0, 0, canvasW, canvasH);
    x = 1;
    r = -1;

  };

  /**
   * canvas に触れると画像が現れる
   */
  canvas.addEventListener('mouseover', () => {

    reset();
    show();

  });

};

waveAnim();

```




おわります。
個人的によく使うショートカット(XcodeとAndroid Studio比較)

|用途|Xcode|Androd Studio|メモ|
|---|---|---|---|
|メソッド名や文言検索|Command + Shift + F|Command + Shift + F|同じ|
|ファイルツリーの中で現在見ているファイルにフォーカスを当てる|Command + Shift + J|なし|Android StudioにもXcodeと同様のCommand + Shift + Jのショートカットを当てています|
|ファイル検索|Command + Shift + O|Command + Shift + O|同じ|
|最近開いたファイルを開く|Control + 1押してから方向キーでRecent Filesを操作|Command + Eから方向キーで操作||
|定義元にジャンプ|Command + クリック|Command + クリック|同じ|
|定義元から戻る|左スワイプ|Command + {||
|インデントを揃える|Control + I|Command + Option + L||
|下のウインドウを立ち上げる|Command + Shift + Y|Command + 6|Android Studioには数字が書いてあります|
|実行|Command + R|Control + R|CommandとControl違い|
|停止|Command + .||Android Studioにはある？|
|メソッドの呼び出し元を開く|メソッドを右クリックして、Find Call Hierarchy|Command + Option + H|||
|不要な宣言を削除|なし|Control + Option + O|||

結構ショートカットを使うかは個人によりけりかもしれませんが、他によく使うショートカットあれば教えて下さい🙇
独断と偏見で更新します!笑
ローカル環境でGitBookを作成、閲覧できるようになるまで

## 概要

GitBookはマークダウンで書かれたドキュメントに目次などをつけてHTMLに変換することで、閲覧しやすくするコマンドラインツールです。
ビルドしたドキュメントを簡単にオンラインに公開できるそうです。
[GitbookIO/gitbook: 📝 Modern documentation format and toolchain using Git and Markdown](https://github.com/GitbookIO/gitbook)


## 本記事でやること

この記事では、ローカル環境でマークダウンドキュメントを作成、GitBookでビルドし閲覧できるところまで実行する手順を記します。


## 実行環境
* MacBook Pro(Retina 13-inch, Early 2015)
* OS X El Capitan
* git v2.10.1
* node v8.5.0
* npm v5.3.0


## 準備

`node.js`をあらかじめインストールしておきます。
今回はすでにインストールがされていたので飛ばしますが、検索するとたくさんの記事が出てきます。


## GitBookをインストール

```
$ npm install gitbook-cli -g
```


## 対象ディレクトリでbookを作成する

bookにしたいディレクトリに移動し、以下のコマンドを入力します。

```
$ gitbook init .
```

すると、以下の2ファイルが新規作成されました。

* README.md
* SUMMARY.md


## ビルドしてみる

`gitbook init`を実行したディレクトリ内で`gitbook serve`を実行するとビルドからローカルでのサーバの立ち上げまでを行えます。

```
$ gitbook serve
Live reload server started on port: 35729
Press CTRL+C to quit ...

info: 7 plugins are installed
info: loading plugin "livereload"... OK
info: loading plugin "highlight"... OK
info: loading plugin "search"... OK
info: loading plugin "lunr"... OK
info: loading plugin "sharing"... OK
info: loading plugin "fontsettings"... OK
info: loading plugin "theme-default"... O
info: found 1 pages
info: found 3 asset files
info: >> generation finished with success

Starting server ...
Serving book on http://localhost:4000
```

このような表示がされてサーバが立ち上がりました。

<img width="1618" alt="スクリーンショット 2017-11-23 11.37.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/174052/5b3949e3-8a4e-16ac-c152-7a0f7ce2ee3a.png">

`gitbook init`で生成された`SUMMARY.md`は以下のようになっているので、これを編集してbookを作成していきます。

```md:SUMMARY.md
# Summary

* [Introduction](README.md)

```

今回検証用に用意したディレクトリ構成は以下のようにしました。

```
~/gitbook_install
.
├── README.md
├── SUMMARY.md
├── sample1
│   ├── README.md
│   └── hoge.md
├── sample2
│   ├── README.md
│   └── poyo.md
└── sample3
    └── fuga.md
```

これを反映させるために`SUMMARY.md`を編集します。

```md:SUMMARY.md
# Summary

<!-- リンク記法で目次を作成 -->
* [introduction](README.md)

<!-- カテゴリ分けのようなこともできる -->
### category1

* [sample1](sample1/README.md)
    * [hoge](sample1/hoge.md)
      <!-- '#'でページ内にアンカーを作成することもできる -->
      * [hoge](sample1/hoge.md#hoge)

* [sample2](sample2/README.md)
    * [poyo](sample2/poyo.md)


### category2

* sample3
    * [fuga](sample3/fuga.md)
```

すると以下のようなbookが作成できます。
<img width="1423" alt="スクリーンショット 2017-11-23 12.08.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/174052/d1507f59-02ff-3d15-3ece-2addf68283bb.png">

## まとめ

ページ内で素早く検索ができたり、ドキュメントの閲覧が便利になりそうなので、普段作っているMarkdownドキュメントでもGitBookを活用できたらなと思いました。
最低限閲覧できるところまでしかしていないので、もっと便利な使い方や見逃している部分があったら指摘いただけたら嬉しいです。


## 参考資料

[Installation and Setup · GitBook Toolchain Documentation](https://toolchain.gitbook.com/setup.html)

[Pages and Summary · GitBook Toolchain Documentation](https://toolchain.gitbook.com/pages.html)

[GitBookローカル開発環境セットアップ - Qiita](https://qiita.com/mamohacy/items/98c0d790074c9bdfef1a)
DeepLearningフレームワークのベンチマーク

## はじめに
　昨今、Deeplearing熱の高まりからたくさんのPythonを使ったDeeplearningフレームワークが登場しています。現場で使うときに求められるのはフレキシビリティや実装のしやすさの他に、処理速度の速さなどが重要であると感じます。そこでQiitaではフレームワーク間の処理速度の比較に関する記事がないのでこの記事を執筆しました。また、これらの結果は環境に依存する話ですので、お手元で試せるようにソースコードを公開しております[[Github](https://github.com/0h-n0/DL_benchmarks)(開発中)]。

## 環境

| | |
|--:|--:|
|ハード|AWS g2.2xlarge|
|OS|Ubuntu 16.04|
| Python|3.6.3|
|CUDA|8.0|
|cuDNN| 6.0|
|Chainer| 4.0.0b1|
| CuPy |4.0.0b1|
|Pytorch| 0.4.0a0+5215640|
| Tensorflow| 1.4.0|
| mxnet| 0.12.1|

### その他の前提

* (3, 28, 28)のダミーデータを使用。
* CNN(6層CNN+3層FC)
* 反復回数1000

## 結果
####1. 計算を終了するまでの総時間
![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/72603/65559924-0aab-0240-d9d0-9e1d8579262b.png)
####2. １サンプルあたりの計算時間(=total_time/batch_size)
![Unknown2.png](https://qiita-image-store.s3.amazonaws.com/0/72603/8b125e7e-fad3-9175-16ae-d67c039b0077.png)
　どのフレームワークもバッチサイズ2000あたりで計算時間が頭打ちし始めている。

####3. １バッチの計算時間
![th.png](https://qiita-image-store.s3.amazonaws.com/0/72603/5eb34562-fcbe-528f-49c6-06e7033a5419.png)
![ch.png](https://qiita-image-store.s3.amazonaws.com/0/72603/e8525bc1-d485-f042-91ec-14bd1ae754b4.png)
![mx.png](https://qiita-image-store.s3.amazonaws.com/0/72603/2291cf0b-a410-ea62-9ac1-8dc72502425f.png)
＊tensorflowはバグがあり計測できませんでした。

####4. 結果について
　私の環境では結果として、小さいバッチサイズではmxnetが一番早く、大きなバッチサイズではPytorchが一番早いといった結果になりました。しかし、環境が異なればもちろん結果も異なります。また、マルチGPUを用いたときの結果は大きくことなります。Chainerが遅いように見えますが必ずしもそうとは言えません。

####5. 大きいバッチサイズで実験する意味
　一般的にバッチサイズを大きくすると精度が落ちると言われております。しかし、最近ではFacebookに始まり多くのチームが大きなバッチサイズで学習を成功させています。よって、これからは分散並列やマルチGPUを用いて大きなバッチサイズでスケールするフレームワークの需要が伸びるのではないでしょうか。

## ソースコードについて[[Github](https://github.com/0h-n0/DL_benchmarks)(開発中)]
#### 1. pytorchのインストール
　まず、pytorchをインストールして頂く必要があります。これはGPUを使った計算は非同期的に処理が行われるため、処理時間を適切に計測するためにcudaEventを使って適切に同期を取る必要があるからです。(CuPyやPyCUDAにも同様のメソッドがありますが、2017/11/23現在、PyCUDAはCUDA9.0に対応していません。)
#### 2. 対応しているDeeplearingフレームワーク
|DL|CPU|Single GPU|MultiGPU|
|--:|:--:|:--:|:--:|
|pytorch|?|o|o|
|chainer|?|o|o|
|mxnet|?|o|o|
|tensrflow|?|o|x|
|neon|?|x|x|
|cntk|?|x|x|
|caffe2|?|?|?|

#### 3. 実行方法

```bash
$ git clone https://github.com/0h-n0/DL_benchmarks.git
$ cd DL_benchmarks
$ pip install -r requirements.txt
$ python -m benchmark.main  ## default framework is pytorch
$
$ # You can change framework.
$ python -m benchmark.main with framework=chainer
$ # And also, change batch size.
$ python -m benchmark.main with framework=chainer batch_size=2000
$ # get info of command line options
$ python -m benchmark.main print_config
$
$ # check results
$ cd results/<your experiment id>
$ cat results.json
```
[bukuroswift]私の開発環境

私が普段使っている「開発環境」は次のようなものです。

<ul>
<li>Mac mini</li>
<li>MacBook Pro</li>
<li>iPhone</li>
<li>AirPods</li>
<li>AppleWatch</li>
<li>Terminal.app</li>
<li>Path Finder</li>
<li>Jedit Ω</li>
<li>Xcode</li>
<li>Android Studio</li>
<li>Affinity Designer</li>
<li>Pixelmator</li>
</ul>

<p>Mac miniは主に事務処理に、MacBook Proでプログラミングしています。開発時は音楽が欠かせませんので、再生機器としてiPhone、聴くためのAirPods、操作するためのAppleWatchも必須です。主に、エアチェックしたNHK FMの番組を聴いています。</p>

<p>自分はUNIX育ちですので、ターミナル操作は苦になりません。ですので、よく使うテキストエディタにはviも入ります。GUIでは、Path FinderとJedit Ωを組み合わせて使っています。Path Finderは最初取っつきにくいのですが、選択したファイルを状況に合わせて選択したアプリで開けるのが便利です。Jedit Ωは普通のテキストエディタとして利用できるので気に入っています。</p>

<p>XcodeはmacOSやiOS開発には必須なので説明は不要でしょう。Macintoshの開発環境はTHINK Cから始まり、MPW、Project Builder、Xcodeと使ってきましたが今のXcodeには満足しています。</p>

<p>Androidの開発はあまりできていないのですが、Android Studioを「素」で使っています。Bitzでは基本ネイティブで開発するようにしていますので、例えば、iOSとソースを共通化するために中間的な環境を利用しないようにしています。少人数での開発でしたら、そちらの方が効率悪いので。</p>

<p>アプリケーションの開発では、画像を扱うことが多く、ペイント系はPixelmatorで、ドロー系はAffinity Designerを使っています。ちょっと、高機能を持て余しているのですが、自分に見合ったものを見つけられていませんので、これを使っています。</p>

<p>これ以外にちょっとした処理の自動化ではperlを使うことが多かったのですが、今は修行をかねて、pythonやruby、Bourne Shell、list、swiftも使うようになりました。別にperlには不満はなく、一時に、自分の主な業務はPerlプログラミングといった方が正確では？という時期もありました。ありがとう、Perl。</p>

関連情報
<a href="https://qiita.com/advent-calendar/2017/cocoa">Cocoa Advent Calendar 2017</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />