OmniAICreator/Qiita-1.07M huggingface dataset:
input type="file" のボタンをオリジナルのボタンにする。

#概要
Bootstrapを使うとボタン類は綺麗に装飾されますが、ファイル選択のボタンってCSSでは装飾出来ません。
そこでjqueryを使えば擬似的に好きな画像やbutton要素をファイル選択ボタン代わりに使うことが出来るようになります。

なお、jqueryを使用しているのでjqueryは読み込んでいる前提です。

##ソース

```html:HTML
<input type="file" id="file" style="display:none;" onchange="$('#fake_input_file').val($(this).val())">
<input type="button" value="ファイル選択" onClick="$('#file').click();">
<input id="fake_input_file" readonly type="text" value=""  onClick="$('#file').click();">
<input type="submit" name="submit" value="送信" id="Submit">
```

##解説

```html:HTML1
<input type="file" id="file" style="display:none;" onchange="$('#fake_input_file').val($(this).val())">
```
この部分が本来のファイル選択ボタンになります。ここを非表示にします。
`display:none`は非表示になっているだけで機能を無効化してるわけではありません。

```html:HTML2
<input type="button" value="ファイル選択" onClick="$('#file').click();">
```
ここが擬似的にファイル選択ボタンの役目を果たしている部分。
ここではわかりやすいようにinputを使ってますが、imgで好きな画像を表示させてもbuttonタグを使ってもOKです。

`onClick="$('#file').click();"` ここがポイント。
この要素をクリックした時に、非表示にしている`HTML1`に対してclickイベントを発生させています。
つまり、ここをクリックすれば`HTML1`のボタンもクリックしたことになり、ファイル選択のダイアログが表示されるようになります。


ただ、これだけだとどのファイルを選択したのかがわからないのでファイル名を表示させるためのテキストボックスを用意します。

```html:HTML3
<input id="fake_input_file" readonly type="text" value=""  onClick="$('#file').click();">
```
`readonly`属性を付けてユーザーが変更出来ないようにします。
`HTML1`の`onchange`によって、この値が変化した際に`HTML3`のvalue部分が変更されるようにしました。

`HTML3`の`onclick`のところは`HTML2`と同じで、テキストボックスをクリックした時もファイル選択のダイアログを表示させるようにしました。



これで`HTML2`の部分をCSSで装飾してあげればオリジナルボタンの完成です。
Gitのコミットメッセージを楽に書く

```
$ git commit -m 'Fix hogehoge'
```
とか書くのがめんどくさいから少し楽に書こう的なアレ。


```~/bin/git-ci```  というのを作る。

``` ~/bin/git-ci
if [ $# -eq 0 ]; then
  git commit -v
else
  if [ "$1" = "--amend" ]; then
    git commit -v --amend
  else
    git commit -m "$*"
  fi
fi
```

そうすると、``` git ci ``` の後にコミットメッセージをそのまま書けばコミットできる。 

```
$ git ci Fix hogehoge 
```

これだけでOK。```-m``` も、```''``` も要らない。

amend したいときは、

```
$ git ci --amend
```

ってすれば ```git commit -v --amend ``` になる。

```
$ git ci
```

のみだと、 ```git commit -v``` になる。


これ、以前 某プログラマさんが私のMacに書き残して行かれたのだが、とても便利でよい。

## 追記

シェルのrcに、`~/bin`へのパスを通しておくべし

```
export PATH="$HOME/bin:$PATH"
```
pyenvとminiconda3で数値計算環境構築


Pythonの数値計算系ライブラリは2012年からほぼすべてPython3に移行完了したらしいので、Python3で環境構築してみた。

複数バージョンのPythonをインストールして使い分けるのは最近ではpyenvが定番らしい。MacだとHomebrewで入るので楽。

```
brew install pyenv
```

↓このへんを.zshrcなりに書いておくのを忘れずに。

```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

eval "$(pyenv init -)"
```

pyenv installでインストールできるバージョン一覧が見られる。

```
pyenv install

...
  anaconda-1.9.1
...

...
  miniconda-3.0.5
...

...
  miniconda3-3.0.5
...
```

というふうにして、anacondaやminicondaを見つけたので、最初はvirtualenvを使おうと思ってたけど、pyenvだけでいくことにした。

miniconda3をインストールし、

```
pyenv install miniconda3-3.0.5
pyenv global miniconda3-3.0.5
```

ここで`pyenv rehash`が必要だったかも。

condaコマンドでその他のライブラリをインストール。

```
conda install numpy scipy matplotlib ipython pandas
conda install pyzmq Jinja2 tornado
```

（後ろのやつはipython notebookで必要っぽい）

ここでまた`pyenv rehash`が必要のはず。（`eval "$(pyenv init -)"`をすれば`pyenv rehash`もしてくれるので、zshrcとかにこれを書いていれば、単に別のシェルを立ち上げるだけで良い）

ビルド済みで配布されているパッケージをインストールしただけなので、自前でのビルドは一切不要。すばらしい。

## miniconda3とは

Pythonの数値計算環境構築はみんな面倒だと思ってるらしく、全部入りパッケージとしてAnacondaというのが作られている。AnacondaにはMac用インストーラーとかもあるが、minicondaという最小限ツールだけを入れてライブラリ等を自分で入れることもできる。今回はPython3ベースのminiconda3を使った。

他にもEnthought Python Distribution (EPD)という全部入りパッケージもあって、昔は自分もそれを使っていた。今はCanopyというらしいが、まだPython3に対応していないっぽい。
selectedBackgroundViewの背景色を変更するときのメモ


これも超基本なことなのだろうが、少々時間をとられたためメモしておく。
下記の①、②は一見同じ実装のように見えるが、前者は想定通りの動きとなり、後者はそうならなかった。

```objc
//collectionView:cellForItemAtIndexPath:内の処理にて

...

//①選択時に背景色がオレンジ色になる
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.backgroundColor = [UIColor orangeColor];
cell.selectedBackgroundView = selectedBackgroundView;

//②上の実装を１行で表すとうまくいかない
cell.selectedBackgroundView.backgroundColor = [UIColor redColor];
```

後者について調べたところ、ここで`cell.selectedBackgroundView`は初期化されていないため`nil`になっていた。`nil`に対してプロパティセットしようとしても意味はなく、`nil`になってしまうことがわかった。

なんとなく一行で済ませようとしてもダメであるという教訓。
swaksを使ってgmailのsmtpで送信

# swaks インストール

```
$ sudo apt-get install swaks
```


# GmailのSMTPを使ってメール送信テスト

```
$ swaks \
-t 送信先メールアドレス \
-f 送信者メールアドレス \
-a -tls \
-au gmailアカウント \
-ap gmailパスワード \
-s smtp.gmail.com \
-p 587 \
--h-Subject "件名" \
--body "内容"
```
gonum/matrix のデザインコンセプトに関するメモ

[github.com/gonum/matrix - Scientific math package for the Go language.](https://github.com/gonum/matrix)

Goの線形代数のライブラリに関するただのメモです

## APIは標準パッケージの[math/big](http://golang.org/pkg/math/big/)に則っている

https://groups.google.com/forum/#!searchin/gonum-dev/math$2Fbig/gonum-dev/uwlLBQg6tp0/4YwBJDdJBY4J
から引用：

>In fact, the API is basically the same as in math/big. If you call M.Add(A,B) the result of A+B is stored in M. All of the operators are methods, not functions.

by David Neumann 2013/05/11

## 掛け算、足し算、引き算など、返り値は基本なし

math/bigとは違うので注意。メソッドのレシーバに結果が入るのは一緒

```go
a := mat64.NewDense(2, 2, make([]float64, 1, 2, 3, 4))
b := mat64.NewDense(2, 2, make([]float64, 1, 2, 3, 4))
a.Add(a, b) // a = a + bを意味する
```

詳細は、作者の一人のDan Kortschakによる[行列の掛け算の実装例](https://gist.github.com/kortschak/5559519)を参考

### 返り値がほしいとき

`a = a.Add(a, b)`のように書きたいときは、自分でメソッドなり関数を書く。例えば以下

```go
func Add(a, b *mat64.Dense) *mat64.Dense {
    a.Add(a, b)
    return a
} 
```

これで、以下のように書ける

```go
a = Add(a, b) // a.Add(a, b) と同じ。人によってはわかりやすい表記かもしれない（少なくとも自分はそう）
a = Add(a, Add(b, c)) // a = a + b + c
```

## その他雑多メモ

* 返り値にポインタがほしいならclientが書く（↑の例、[G+のポスト](https://plus.google.com/u/0/+RyanneDolan/posts/TuzQgVRfmAw )でDan Kortschakはそう言ってる。デザインポリシーだと思う）
* 返り値がない理由は、Dense, Sparse, .. 等行列の型に応じた実装が必要でかつ煩雑になってしまうから？(イマイチ納得しきれてない
* おそらく、現時点で一番有力な線形代数のライブラリはgonum/matrixだと思う。ただしまだかなり発展途上。
* 行列演算の内部ではblasが動いている
* cublasをエンジンにしようとする計画もある（API Discussionより）
* gonum/matrixはbiogoの一部からより使いやすい形で切り出そうとしてる印象をうける

## 参考
* [gonum-dev -> API discussion | Google Groups](https://groups.google.com/forum/#!searchin/gonum-dev/return$20reciever/gonum-dev/uwlLBQg6tp0/5x8C5SHfnpsJ)
* [API discussionに関するG+の投稿その1](https://plus.google.com/u/0/+RyanneDolan/posts/TuzQgVRfmAw)
* [API discussionに関するG+の投稿その2](https://plus.google.com/u/0/104245239733029001688/posts/6DftKS5nJrt)
* [Dan Kortschakによる行列の掛け算の実装例](https://gist.github.com/kortschak/5559519)
twitter風にハッシュタグ抽出をしたい


## やりたかったこと
- 文字列からハッシュタグを抽出したい
- ハッシュタグとみなすのは#からスペースまでの文字(記号は除く)
- 複数個のハッシュタグの抽出もしたい

## 出来たもの
```ruby
"文字列".scan(/[#＃][Ａ-Ｚａ-ｚA-Za-z一-鿆0-9０-９ぁ-ヶｦ-ﾟー]+/).map(&:strip)
```

## 結果
```ruby
def extraction_hashtag(string)
  string.scan(/[#＃][Ａ-Ｚａ-ｚA-Za-z一-鿆0-9０-９ぁ-ヶｦ-ﾟー]+/).map(&:strip)
end
```

こんな感じで定義しておけば…

```ruby
pry(main)> extraction_hashtag("お腹すいた #ラーメン食べたい")
=> ["#ラーメン食べたい"]
```
取得できる

```ruby
pry(main)> extraction_hashtag("お腹すいた #ラーメン食べたい #おなぺこ")
=> ["#ラーメン食べたい", "#おなぺこ"]
```
複数個取得できる

```ruby
pry(main)> extraction_hashtag("お腹すいた #ラーメン食べたい#おなぺこ")
=> ["#ラーメン食べたい", "#おなぺこ"]
```
スペースがない場合も分けて取得


```ruby
pry(main)> extraction_hashtag("#今日は、いい天気だ")
=> ["#今日は"]
```

記号が入ると途切れる

```ruby
pry(main)> extraction_hashtag("＃今日は、いい天気だ")
=> ["＃今日は"]
```

全角の＃でも平気。



追記 4/6　全角数字が抜けていたので修正

```ruby
pry(main)> extraction_hashtag("全角数字 ＃０１２ ")
=> ["＃０１２"]
```

追記 4/10　いろいろ追記

全角

```ruby
pry(main)> extraction_hashtag("#ＡＢＣａｂｃ #ラーメン #０１２")
=> ["#ＡＢＣａｂｃ","#ラーメン", "#０１２"]
```

半角

```ruby
pry(main)> extraction_hashtag("#ABCabc #ﾗｰﾒﾝ #123")
=> ["#ABCabc", "#ﾗｰﾒﾝ", "#123"]
```
Windowsでghp-importを使う

# 現象

Windows で pip を使って ghp-import をインストールしようとすると、以下のエラーが出ます。

```bat
>pip install ghp-import

Downloading/unpacking ghp-import
  Downloading ghp-import-0.4.1.tar.gz
  Running setup.py egg_info for package ghp-import

Cleaning up...
  Exception:
Traceback (most recent call last):
  File "C:\Python33\lib\site-packages\pip\commands\install.py", line 236, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "C:\Python33\lib\site-packages\pip\req.py", line 1139, in prepare_files
    req_to_install.assert_source_matches_version()
  File "C:\Python33\lib\site-packages\pip\req.py", line 394, in assert_source_matches_version
    version = self.installed_version
  File "C:\Python33\lib\site-packages\pip\req.py", line 390, in installed_version
    return self.pkg_info()['version']
  File "C:\Python33\lib\site-packages\pip\req.py", line 357, in pkg_info
    data = self.egg_info_data('PKG-INFO')
  File "C:\Python33\lib\site-packages\pip\req.py", line 297, in egg_info_data
    data = fp.read()
UnicodeDecodeError: 'cp932' codec can't decode byte 0xef in position 1876: illegal multibyte sequence

```

# 解決策

公開されているZIPをダウンロードして、解凍する

* [davisp/ghp-import](https://github.com/davisp/ghp-import)

中にある setup スクリプトを実行してインストールする

```bat
> setup.py install
```

`C:\Python33\Scripts\ghp-import` ファイルが作成されていますが、これだけだとコマンドプロンプトから実行できません。

なので、バッチファイルを作成します。

```bat:C:\Python33\Scripts\ghp-import.bat
@"C:\Python33\python3.3.exe" "C:\Python33\Scripts\ghp-import" %*
```

これで、ghp-import コマンドが使用できるようになります。
ディスプレイ切り替えに便利な displayswitch.exe をデスクトップPCでも利用する．

ノートＰＣでだいたいFn + F5とかに割り振られている displayswitch.exeの場所．
ディスプレイが複数ある場合ミラーリングや片方にだけ映し出すなどの設定ができます．便利．
マルチディスプレイなデスクトップ機を使っている時にも役立つのでショートカットをつくっています．
"C:\Windows\System32\displayswitch.exe"にあるので適当につくりましょう．
僕はLaunchyで起動できる場所においてあります．
VBScriptで分かち書きを実行（MS標準機能のみで実装）

#概要
[VBScriptによるInternetExplorerクローラー化サンプル](http://qiita.com/nezuq/items/ecf6302b36598a4afaf4)に関連して、
Webサイトのテキストを分かち書き(単語ごとにスペースで区切る形)で出力できたら面白そう。
簡単なテキストマイニングができる。

指定の1文を分かち書きで表示するVBScriptコードを書いた。
Windows・MSOfficeの標準機能のみでの実装で、職場でも安心実行！

#前提
・MeCab？　知らない子ですね。
・MSWordなら知っています。

#コード
```vbs:分かち書き.vbs
Option Explicit

Dim doc
Set doc = CreateObject("Word.Application").Documents.Add()
Dim rng
Set rng = doc.Paragraphs(1).Range

rng.Text = "サンプルの文章です。半角スペースで区切られます。"

Dim wrd
Dim aryWrd()
Dim i
i = 0
For Each wrd In rng.Words
    ReDim Preserve aryWrd(i)
    aryWrd(i) = wrd.Text
    i = i + 1
Next

doc.Close False
Set doc = Nothing

MsgBox(Join(aryWrd," "))
```

#参考
[Excelで自然言語処理: VBA自作関数でわかち書きしてみる](http://pub.ne.jp/arihagne/?entry_id=2099220)
脳筋で使えるjQueryプラグイン作った『waiwai-carousel』

仕事でjavascriptのコードを読んでいた時に自分も興味を持ってしまったので、勉強用に作ってみることにした。

# 紹介
## 名前
waiwai-carousel 【[github](https://github.com/chuross/waiwai-carousel)】

- 色々機能を入れているので、賑やかなプラグインという意味でこの名前になった。

## 特徴
- リスト要素に対して簡単な記述をするだけでカルーセルの動作を実装できる
- リスト毎のサイズは自由に設定できる
- 好きな要素をnext・prevボタンにできる
- 特に指定しなければ、親要素のサイズを見て自動的にカルーセルの範囲を調整してくれる
- 縦・横方向どちらにも対応
- 移動量変更可能
- アニメーションの時間を変更可能
- 各イベントのコールバックを設定できる

# 使い方
## javascriptの読み込み
head内など任意の場所にjQueryとセットで読み込む

```html
<head>
...
<script src="jquery-1.11.0.min.js"></script>
<script src="jquery.waiwai-carousel.js"></script>
...
</hrad>
```

## waiwai-carouselを適用する時の定義
任意の場所のscriptタグ内に定義する。オプションはデフォルトから変更したいものだけ記述するとスッキリする。

```html
<script type="text/javascript">
$(document).ready(function() {
    // ulタグを指定してね
    $('.ultag').waiwaiCarousel({
        // カルーセルの幅。autoだと親要素に追従する
        width: 'auto',
        // カルーセルの高さ。autoだと親要素に追従する
        height: 'auto',
        // カルーセルの移動する向き。縦の場合はvertical
        direction: 'horizontal',
        // 押した時に次に移動させるための要素を指定できる
        next: null,
        // 押した時に前に移動させるための要素を指定できる
        prev: null,
        // カルーセルの移動時間
        animationDuration: 500,
        // 移動量
        transitionSize: 'auto',
        // 次が押された時に呼ばれるコールバック
        onNextClick: null,
        // 前が押された時に呼ばれるコールバック
        onPrevClick: null,
        // カルーセルの移動を始めた時のコールバック
        onTransitionStart: null,
        // カルーセルの移動を終えた時のコールバック
        onTransitionEnd: null
    });
});
</script>
```

## CSSの設定
- カルーセル内の並び方はwaiwai-carousel側で自動でセットしていないので使う側が設定する必要がある。
- 横に並べたいときはliタグに対してinline-blockかfloatを掛けると良い
- 最初横置きの場合はプラグイン側で自動で要素に対してCSSを掛けるようにしてたんだけど、[inline-blockに隙間ができる問題](http://inspire-tech.jp/2011/06/inline_block_spaces/)があったり、float使うとvertical-alignが効かなかったりするので、そういう細かい調整は使う側の好みに任せるようにした。
 - サンプルではinline-blockで配置し、ulに対してfont-size=0pxを設定し、li要素内でfont-sizeを再セットする方法を使っている
- 横置きとかプラグイン側で自動に追加される要素に対してCSSを自動的に入れるのは良いと思うけど、それ以外の要素に対して勝手にスタイルを適用するのは良くないかなと思ったので、基本プラグイン側からスタイルを適用するのはなしにしてる。(計算狂わせないためのスタイルはいくつか適用している)

# サンプル
色々な設定とその動作をまとめたので、細かい使い方はこっちで確認してね

- http://htmlpreview.github.io/?https://github.com/chuross/waiwai-carousel/blob/master/sample/index.html
 - a～lまでの項目があって、可変のサンプルは全部表示されてる状態だとnext押しても反応しないのでウインドウサイズ変更して試してみてね

# 技術的な話題
## 多機能にしようと思った経緯
1. カルーセルの動作は一つのサイト内でも色々な場所で使われてることがある
 - トップページとか商品説明画面のサムネイルとか 
1. 用途ごとにカルーセル作ってるとキリがないし、やりたいこと大体一緒なのに使い分けるのは面倒

## こだわったとこ
- とにかく呼び出しを簡単にして、面倒なことは大体プラグインが吸収するようにしたい
- [カルーセルの移動する単位をul単位にする](http://ascii.jp/elem/000/000/481/481241/)やり方は個人的に好みではなかったので、個々のliタグの幅を見て移動量を計算するようにした
- 仮にブラウザのサイズが変えられていたとしても、ちゃんと動作するようにしたい

## テスト書いた
- jQueryのテストってどうやるのか興味があったので書くことにした
 - ライブラリなら他の人が使う可能性も考えてテスト追加するべきだよねっていうのもある
- 今回テストに使ったのは[QUnit](https://qunitjs.com/)を使った
- 簡単に導入できて、jQueryのコールバック後のテストとかもちゃんと書けるので特に不満なく書ける
- テストはこんな感じ
 - http://htmlpreview.github.io/?https://github.com/chuross/waiwai-carousel/blob/master/test/qunit.html

# 今後追加していくもの
- カルーセルのループ
 - 当初から作ろうと決めていたものの、まだ手を付けてない
- リスト要素の幅・高さ変更にも対応
 - 現状だと親要素の変更には対応してるけど、リスト要素の幅が可変になってると正しく動かない
- 反省会の内容は直す

# 反省
- スマホだと正常に動かない
 - クリックイベントが2回拾われて端っこで止まるはずが止まらなかったりしてる
 - い、一体何がどうなて
- 現状だとリスト要素の柔軟な変更に対応してない
 - リスト要素が可変だと、移動量の計算が古い値を基に計算してしまう
 - ここらへんまだ脳筋で使えない部分なので何とかする

# 備考
コードはforkして煮るなり焼くなりご自由に
cronでinode使用率を監視する

cronで定期的にシェルスクリプトを実行することで、簡易的にinode使用率を監視したい場合のスクリプト。

```bash:monitor-inodes.sh
set -e

INODES_LIMIT_RATE=80

inode_rates=$(df -i | egrep -o '[0-9]+%' | cut -d '%' -f 1)
for inode_rate in $inode_rates
do
  if [ $inode_rate -ge $INODES_LIMIT_RATE ]
  then
    df -i
    exit 1
  fi
done
exit 0
```

crontabで`MAILTO`を設定しておけば、閾値に達した時にメールで連絡してくれます。

たぶんみんな（監視ツールを入れていないサーバーでは）書いてるんだろうけど、ググっても見付からなかったので。
と言うかむしろ、みんなどうやってるのか、もっと簡単なやり方ないのか、教えてもらえたら嬉しいです。
DigitalOcean上でさくっとSquidでProxyサーバーを立てる


諸事情によりAWS以外に建てたかったので、DigitalOceanに。
月$5ってすごいですよ。

## iptables

AWSのSecurityGroupでぬるま湯生活をしていたので、一苦労。

SSH以外にも、3128ポートあけておく。

```/etc/sysconfig/iptables
*filter

:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3128 -j ACCEPT

COMMIT
```

```
/etc/init.d/iptables restart
```

iptablesいじるのってちょっと前までは結構恐怖だったんですが、今どきは最悪インスタンス作りなおせばいいので気が楽になりましたね...

CentOS7からはiptablesがデフォルトで動かなくなったので下記参考にしました。

第47回　RHEL7/CentOS7の新規コマンド総まとめ！ (中井悦司)
http://www.school.ctc-g.co.jp/columns/nakai/nakai47.html

```
yum -y install iptables-services
systemctl stop firewalld.service
systemctl mask firewalld.service
systemctl enable iptables.service
systemctl start iptables.service
```

## squid

```
yum update
yum install squid
```

```/etc/squid/squid.conf
# 使うIPを定義する
acl my_pc               src xxx.xxx.xxx.xxx # your source ip

# http_access deny all よりも手前に
http_access allow my_pc

# And finally deny all other access to this proxy
http_access deny all

# ファイルの最後に
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all
```

```
/etc/init.d/squid restart
```

つなげてテストしてみましょう。
(今更)scriptコマンドで作業手順を保存

今の今まで存在を知りませんでした... orz
scriptコマンドを使用するとそれ以降の終了(exit or C-d)するまでのコンソールへの出力をファイルに残せます。
使い方は以下のコマンドを実行するだけ

```shell-session
script <出力先のファイル名>
```

すでに存在するファイルに追記したい場合はaオプションでOK

```shell-session
script -a <追記するファイル>
```


インストール手順などを保存するときに便利です。
プログラミングを始めたいけど環境構築がわからない人用メモ

# この記事の対象者

- プログラミングとかやったことない
- Windows 以外の OS 触ったことない
- でも Linux は気になるかもしれない
- プログラミングもできたらやりたいかもしれない

# はじめに

「プログラミングをやってみたいけど『Windowsじゃつらいよー』『MacやLinuxのほうが向いてるよー』と言われた」という人は多いと思います。
Windows は Eclipse や Visual Studio でカバーできる範囲のことならいいのですが、

- 周りのプログラマがみんな Linux か Mac OS X を使ってる
- Windows はなんとなく嫌なのでカッコつけたい
- 使いたいソフトウェアをググったら Linux の記事しかなかった
- フォロワーに質問したら「Windowsじゃわかんないわ」って言われた

など、様々な理由から「Windowsはプログラミングに向いていない気がする」と感じてる人は多いと思います（個人の感想です）。

というか、そういうリプライをよくもらうので、私がいつも答えてるものをまとめておこうと思っただけです。


# じゃあどうするのがいいか

考えられる現実的なパターンは次の3種類

- Mac を買う
- Windows のままがんばる
- Linux をインストールする

iOS アプリを開発したい人か、お金持ちか、スタバでドヤ顔したい人は Mac を買ってください。
Windows のまま進めるのは私はあまり詳しくないので扱いません。
ここでは Linux をなんとかして使う場合で考えています。
というわけで以下の様な選択肢があります。

## デュアルブート

既存の Windows とは別に Linux をインストールする方法。
パソコンを起動した時に、Windows と Linux どちらを起動するかを選択する画面が表示されるようになります。

### メリット

- 後述する仮想マシンによる方法とくらべて無駄にCPUやメモリを食わないので軽い。

### デメリット

- インストールに失敗すると Windows が消える。
- パーティションの設定や概念が面倒（簡単に言うと、ハードディスクのどれくらいの容量を Windows と Linux で分け合うか決めないといけない）

## 仮想マシン

Windows の中に仮想的なパソコンを生成して、その仮想マシンに対して Linux をインストールできるという革新的な技術を使ったアプリがあります。

![OSX上にLinuxを動かしている様子](https://qiita-image-store.s3.amazonaws.com/0/11852/9c3e9737-0d2a-7bca-34af-2642f8f4ca88.png)


たとえば上記は Mac OSX の中に仮想マシンを作って、そこに Ubuntu Linux を入れて起動しているところです。
ちょっとよくわからないかもしれませんけど、ウィンドウの中で更に別のOSが動いています。ほんとどえらいアプリですね。

### メリット

- 仮想マシンに Linux を入れるのでなにをしようが Windows には影響がない。

- 仮想マシンはひとつのファイルのように扱うことが出来るので、マシンをたくさん作ったり、削除したり、コピーしたりすることもできる。

### デメリット

- 仮想マシンを扱うためのソフトウェアのインストールの手間がある
- OSの上でOSを動かすのでそのぶん余計にメモリやCPUリソースが費やされる(要するに重い)

# 結局どうすればいいの

メモリが8GB以上あって、HDDの空き容量が30GB以上あって、CPUが Core i5, i7 かそれ以上なら仮想マシンを扱うためのソフトウェアである Virtualbox のインストールをおすすめします。

というかデュアルブートは失敗してブートできなくなっても責任が取れないのでおすすめしません。自己責任でやってください。

# どうやって仮想マシンとか入れるの？

長くなったので続きはまた今度（ググればたくさん出てきます）。
Chrome拡張でツールバーからのHTMLページ表示

Chrome拡張では、しばしばポップアップを用いて情報表示が行われます。これはこれで便利な機能ではありますが、別のウィンドウにフォーカスを合わせてしまうとポップアップが消えてしまったりして、場合によっては少々使い勝手が悪くなってしまう場合があることは否めません。なので、ここではChrome拡張で通常ポップアップを表示する処理を少し変更して、新しいタブを生成して普通にHTMLページを表示させるようにしてみます。この時、WWW上にあるHTMLページを表示させてもよいのですが、Chrome拡張に同梱したHTMLページを表示させるようにしてみます。

![Chromeのツールバー](https://qiita-image-store.s3.amazonaws.com/0/13728/534859cc-b8cc-fc1e-27d8-eb10989e93cf.png)

まず、Chrome拡張の中にHTMLファイルを同梱しておけば、Chromeにてそのページを表示することができます。
以下のURLをアドレスバーに入力すれば、同梱したHTMLファイルを表示させることができます。

> chrome-extension://\<Chrome拡張のID\>/\<HTMLファイル名\>

もちろんHTMLだけではなくCSSや画像ファイルなどを入れておくことも可能です。ライセンスがクリアならば、jQueryなどのライブラリを同梱しておくことも出来るでしょう。

とはいえ、このURLを毎回入力するのもなかなか大変です。Chrome拡張のインストール時に、ブックマークに登録するようにしておくのもいいかもしれません。冒頭に述べた通り、今回は通常ポップアップを表示するのに用いられる事の多い、ツールバー上のアイコンを利用することにします。ツールバー上にアイコンを表示させる方法は、Chrome拡張のBrowser Actionのページに詳しく書かれています。manifest.jsonに以下のように書くことにより、ツールバーにアイコンが表示されるようになります。

```json:manifest.json
"browser_action": {
  "default_icon": {
    "19": "icon_small.png", 
    "38": "icon_big.png"
  }
}
```

このアイコンを押した際にポップアップメニューが表示されるようにするだけならば、manifest.jsonに"default_popup": "popup.html" と書くだけで済みます。しかし、今回はポップアップを表示したいのではなく、新しいタブでChrome拡張中のHTMLファイルを表示させることが目的です。この為には、アイコンをクリックした際に新しいタブでHTMLファイルを表示するようにイベントを登録する必要があります。

イベントの登録には、Event Pagesを利用します。Event Pagesは、Chrome拡張がロードされている間に実行したいスクリプトを書いておくことができます。Event Pagesを利用する為に、manifest.jsonに次のように書き加えます。

```json:manifest.json
"background": {
  "scripts": [ "icon_clicked.js" ], 
  "persistent": false
}
```

続いて、アイコンをクリックした時にHTMLページを表示させるイベントを登録します。icon_clicked.jsというJavascriptのファイルを作成し、以下のように書きます。

```js:icon_clicked.js
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.create({"url": "newtab.html" });
});
```

これで、アイコンをクリックした際に新しいタブを開き、Chrome拡張の中に一緒に入れておいたnewtab.htmlという名前のHTMLファイルを表示させることができるようになりました。
Rails4.1.0.betaやってみた雑感


Ruby2.1.1 × Rails4.1.0.betaを試してみた。

## インストール
### ruby
`ruby-build`を更新して`rbenv install 2.1.1`

### rails
Gemをupdateして`gem install rails -v '4.1.0.beta'`だったと思う

## やりたかったこと

- slim試したかった
- rails_template試したかった（[オレオレテンプレート](https://github.com/shogochiai/rails_template)）
- Heroku試したかった
- Backbone.js試したかった
- デザイン練習したかった

## ハマったこと

rakeするたび糞鬱陶しいことになる

```rake後
DEPRECATION WARNING: The cattr_* method definitions have been moved into active_support/core_ext/module/attribute_accessors. Please require that instead. (called from require at /usr/local/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:76)
```

バグ報告っぽいの見つけた

https://github.com/collectiveidea/delayed_job/issues/620


## 気になったこと

どんなエラーか失念したのですがこれの前に出てたエラーで

[polyamorous](https://github.com/activerecord-hackery/polyamorous)

を使用することを勧めていて、とりあえずbundle installしたらそれは収まったんですけど、そういう厄介事がまだまだたくさん潜んでいる印象。


以上、雑感でした
CentOSにphpenvでPHP環境を構築する


# 環境
* CentOS 6.6
* rbenv 導入済み
* git 導入済み

# 準備
* [プロキシの指定方法](http://qiita.com/tunepolo/items/296c2639e0b750de41c6)
* RPMforge 導入
 * [CentOS6.x yum外部リポジトリまとめ](http://qiita.com/m2wasabi/items/6d6a68da2e9dada92369)

# phpenvのインストール

``` bash
cd /usr/local/src
curl https://raw.github.com/CHH/phpenv/master/bin/phpenv-install.sh | bash
vi ~/.bash_profile
```

<!--
vi /etc/profile.d/env.sh
-->

``` bash:~/.bash_profile
PATH=$HOME/.rbenv/bin:$PATH
PATH=$HOME/.phpenv/bin:$PATH
PATH=$PATH:$HOME/bin
 
eval "$(rbenv init -)"
eval "$(phpenv init -)"
```

``` bash
source ~/.bash_profile
```


# php-buildの導入
``` bash
git clone https://github.com/CHH/php-build.git ~/.phpenv/plugins/php-build
```

## php-buildの更新
``` bash
cd ~/.phpenv/plugins/php-build
git reset --hard && git pull
```

# バージョンを指定したPHPのインストール
今回はPHP5.5.22をインストールする（2015/3/26 PHP5.5系最新）

## インストール可能なPHPのバージョンを調べる
``` bash
phpenv install
```

## 依存関係にあるパッケージを導入する
``` bash
yum --enablerepo=rpmforge install re2c libmcrypt-devel
yum install bison libxml2-devel libcurl-devel libjpeg-devel libpng-devel readline-devel libtidy-devel libxslt-devel
```

## ビルド時のオプションを変更する

PHPをビルドする時のオプションは`~/.phpenv/plugins/php-build/share/php-build/default_configure_options`に記述されている。これは全体のオプションでどのバージョンにも適用される。

設定可能なオプションは[PHP: 中心となる configure オプションのリスト](http://www.php.net/manual/ja/configure.about.php)を参考


### カレントディレクトリのphp.iniを読み込むようにする

``` bash
vi ~/.phpenv/plugins/php-build/share/php-build/definitions/5.5.22
```

``` :5.5.22
configure_option "--with-config-file-scan-dir=.;/root/.phpenv/versions/5.5.22/etc/conf.d"
```


### httpd用のモジュールを作成する

デフォルトではhttpd用のモジュールである`libphp5.so`が作成されないので、バージョンを指定してオプションを変更する

``` bash
vi ~/.phpenv/plugins/php-build/share/php-build/definitions/5.5.22
```

以下の行を先頭に追加する

``` :5.5.22
configure_option "--with-apxs2=/usr/bin/apxs"
```

### intl拡張モジュールを有効にする


``` bash
vi ~/.phpenv/plugins/php-build/share/php-build/definitions/5.5.22
```

``` :5.5.22
configure_option "--enable-intl"
```

## インストール
``` bash
phpenv install 5.5.22
```

## PHPのバージョンを切り替える
``` bash
phpenv global 5.5.22
phpenv rehash
```


# 参考
1. [モダンなPHP開発環境を構築する  &#8211;  phpenv + php-build で 複数のPHPバージョンを管理する | Creator Life](http://creator-life.net/modern-php-env/)
1. [php-buildで複数バージョンのPHP-FPMを用意する - hnwの日記](http://d.hatena.ne.jp/hnw/20130626)

<!--1. [phpenv と php-build で PHP をインストールして管理 〜 CentOS6 | EasyRamble](http://easyramble.com/install-php-with-phpenv.html)-->
Android: WebViewでアンカーリンクが動作しない問題

# 問題

WebViewにデータを読み込む際に、Androidのバグでアンカーリンクがうまく動作しない事がある。

## 確認した現象

ページ中程のアンカーにジャンプして欲しいが、何故かページの末尾にジャンプしてしまう。

# 対策

読み込み直前にキャッシュをクリアする事で動作するようになる（少なくとも初代Galaxyでは）。

```java:HogehogeWebViewClient.java
// WebView webView;
webView.clearCache(false);
webView.loadDataWithBaseURL(url, data, "text/html", "UTF-8", null);
```
gcm.js(Titainum Module)の構造


多分こんな感じ

![20140405_194813-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/13615/762524c7-442c-1104-4bab-cd5ef8ef5152.jpeg "20140405_194813-1.jpg")

GCM push notifications for Titanium (made easy)
http://iamyellow.net/post/40100981563/gcm-appcelerator-titanium-module

GCM push notifications module for Appcelerator Titanium Android SDK
https://github.com/iamyellow/gcm.js
ポケット・ミクをJava/Clojureから操作してみる

ポケット・ミクはMIDIデバイスだということで、Javaからならjavax.sound.midiパッケージを使えばわりと簡単に操作できるようです。

Javaのサンプルはこんな感じです。

```PokeMikuSample.java
package pokemiku;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.SysexMessage;
import javax.xml.bind.DatatypeConverter;

public class PokeMikuSample {
    public static void main(String... args) throws Exception{
        try(MidiDevice d = getDevice()){
            d.open();
            Receiver r = d.getReceiver();
            
            byte[] data = DatatypeConverter.parseHexBinary("F0437909110A00"+ 21 +"F7");
            r.send(new SysexMessage(data, data.length), -1);
            r.send(new ShortMessage(ShortMessage.NOTE_ON, 80, 127), -1);
            Thread.sleep(2000);
        }
    }
    static MidiDevice getDevice() throws Exception{
        for(MidiDevice.Info i : MidiSystem.getMidiDeviceInfo()){
            if(i.getName().startsWith("NSX-39") && i.getDescription().startsWith("External")){
                return MidiSystem.getMidiDevice(i);
            }
        }
        throw new RuntimeException();
    }
}
```

"NSX-39 "（最後にスペースがある）名前のデバイスが私の環境だと2つありました。そのうち、descriptionに`External MIDI Port`とある方が使えます。

SysexMessageで発音する文字を（マニュアル裏に書いてあるものに）変えられます。
ShortMessageで音程と音量（0～127）を指定できるようです。

Clojureのサンプルはこんな感じです。Javaとほとんど同じですね。

```pokemiku_core.clj
(ns pokemiku.core
  (:import [javax.sound.midi MidiSystem ShortMessage SysexMessage MidiDevice]
           [javax.xml.bind DatatypeConverter]))

(def dev 
  (->> (seq (MidiSystem/getMidiDeviceInfo))
       (filter #(re-find #"NSX-39" (:name (bean %))))
       (filter #(re-find #"External" (:description (bean %))))
       first
       (MidiSystem/getMidiDevice)))

(with-open [dev dev]
  (.open dev)
  (let [r (.getReceiver dev)
        data (DatatypeConverter/parseHexBinary (str "F0437909110A00" 37 "F7"))]
    (.send r (SysexMessage. data (count data)) -1)
    (.send r (ShortMessage. ShortMessage/NOTE_ON 72 127) -1)
    (Thread/sleep 2000)))
```

わりと簡単にできました。
MIDIのことがまだよくわかってないですが、他にもいろいろできるようです。
HttpRequestで画像の取得と表示 (Cocos2d-x V3.0 rc1)


既出の感がありますが、まぁ、やってみたってことで。  
以下のソースでいけます。

```cpp
#include "HelloWorldScene.h"

USING_NS_CC;

using namespace network;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    HttpRequest* request = new HttpRequest();
    request->setUrl("http://www.google.co.jp/images/srpr/logo11w.png");
    request->setRequestType(HttpRequest::Type::GET);
    request->setResponseCallback(this, httpresponse_selector(HelloWorld::onHttpRequestCompleted));
    HttpClient::getInstance()->send(request);
    request->release();
    
    return true;
}

void HelloWorld::onHttpRequestCompleted(HttpClient* sender, HttpResponse* response)
{
    if (!response)
    {
        log("no response");
        return;
    }
    if (!response->isSucceed())
    {
        log("response failed");
        return;
    }

    std::vector<char>* buffer = response->getResponseData();

    Image* image = new Image();
    image->initWithImageData(reinterpret_cast<unsigned char*>(&(buffer->front())), buffer->size());
    
    Texture2D* texture = new Texture2D();
    texture->initWithImage(image);
    Sprite* sprite = CCSprite::createWithTexture(texture);

    Size visibleSize = Director::getInstance()->getVisibleSize();
    sprite->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));
    
    addChild(sprite);
}
```

ハマりどころは

```cpp
    request->setRequestType(HttpRequest::Type::GET);
```

の指定をしないと `signal SIGABRT` で怒られるあたりでしょうか。  
あとは `reinterpret_cast` の存在を知らなかった事。C++ はまだまだ修行が必要そうです。

![kobito.1396692879.846691.png](https://qiita-image-store.s3.amazonaws.com/0/25416/36f005c9-c0ad-9356-1946-0f070aa905b9.png "kobito.1396692879.846691.png")
Kobitoのローカルデータのバックアップ方法（未検証）

どうやるんだろう。

Qiita - kobitonote.py - Kobitoで編集したアイテムをEvernoteに同期保存 - Qiita http://qiita.com/naoya_t/items/4c465380b4020185a224

とか

技術検索パン屋！ http://sandbox.rubyprogrammer.info/qiita/items/a98dffc4b1ad095898b1 
を見ると、

~/Library/Kobito/Kobito.db';

をコミットしてるっぽいのでこいつをDropboxとかGoogleDriveとか何かで持たせておけば、PCにお茶を飲ませても大丈夫そう。

私はGoogleDriveユーザーなので（とても動作が不満だけど）、シンボリックリンクは使えないのでハードリンク貼りました

ln ~/Library/Kobito/Kobito.db GoogleDriveDir/.  これで本当にリストアできたら追記します
第20回オフラインリアルタイムどう書くの問題をRubyで解く

問題はこちら。
http://nabetani.sakura.ne.jp/hena/ord20meetime/

```rb
def solve(q)
  sch = 'o'*(8*60)
  sch_i = 'o'*(8*60)
  sch_j = 'o'*(8*60)
  sch_z = 'x'*(8*60)
  q.split(',').each{|s|
    m = s[0]
    st,ed=s[1..-1].split('-').map(&:to_i).map{|e| (e / 100 - 10) * 60 + e % 100}.map{|e| e < 0 ? 0 : e}
    (st...ed).each{|i|
      break if i >= (8*60)
      case m
      when 'I'
        sch_i[i] = 'x'
      when 'J'
        sch_j[i] = 'x'
      when 'Z'
        sch_z[i] = 'o'
      else
        sch[i] = 'x'
      end
    }
  }
  sch.size.times{|i|
    sch[i] = 'x' if sch_z[i] == 'x'
  }
  st_i = 0
  while(st_i < 8*60 - 60)
    start = sch.index('o'*60)
    break if start.nil?
    if sch_i[start..-1].index('o'*60) == 0 or sch_j[start..-1].index('o'*60) == 0
      start += st_i
      return "%02d%02d-%02d%02d"%[start/60+10,start%60,start/60+1+10,start%60] 
    end
    st_i +=  (start+1)
    sch = sch[start+1..-1]
    sch_i = sch_i[start+1..-1]
    sch_j = sch_j[start+1..-1]
  end
  '-'
end

DATA.readlines.each do |line|
  no,q,a = line.chop.split(/\s+/)
  ans = solve(q)
  print no + "\t"
  print ans
  puts ans == a ? 'o' : 'x'
end
__END__
0	A1050-1130,B1400-1415,I1000-1400,I1600-1800,J1100-1745,Z1400-1421,Z1425-1800	1425-1525
1	A1000-1200,B1300-1800,Z1000-1215,Z1230-1800	-
2	Z0800-2200	1000-1100
3	A1000-1700,Z0800-2200	1700-1800
4	A1000-1701,Z0800-2200	-
5	A1000-1130,B1230-1800,Z0800-2200	1130-1230
```
LANGには何を設定できるんだよ゛ぅ゛ぅ゛ぅ゛！！（藤原竜也



# A. locale -a で調べましょう

例です。

```
$ locale -a
af_ZA
af_ZA.ISO8859-1
af_ZA.ISO8859-15
af_ZA.UTF-8
（中略）
ja_JP
ja_JP.eucJP
ja_JP.SJIS
ja_JP.UTF-8
（中略）
zh_TW
zh_TW.Big5
zh_TW.UTF-8
C
POSIX
$
```

ちなみに、LANGを変更すると
LC_ とつく変数が一緒に書きかわります

```
$ locale
LANG="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_CTYPE="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_ALL=
$
$ LANG="ja_JP.SJIS" locale
LANG="ja_JP.SJIS"
LC_COLLATE="ja_JP.SJIS"
LC_CTYPE="ja_JP.SJIS"
LC_MESSAGES="ja_JP.SJIS"
LC_MONETARY="ja_JP.SJIS"
LC_NUMERIC="ja_JP.SJIS"
LC_TIME="ja_JP.SJIS"
LC_ALL=
$
```


時間だけen_USがいいぜ！って時は
LC_TIMEを直します

```
$ LC_TIME="en_US" date 
Fri Apr  4 15:52:46 JST 2014
$ 
$ 
$ LC_TIME="en_US" locale
LANG="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_CTYPE="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="en_US"
LC_ALL=
$ 
$ date
2014年 4月 4日 金曜日 15時55分06秒 JST
$ 
```


|LC|説明|
|---|---|
|LC_NUMERIC|数の形式|
|LC_TIME|日時の形式|
|LC_COLLATE|文字列のソート順序|
|LC_MONETARY|通貨の形式|
|LC_MESSAGES|メッセージの言語|
入力を安全に受け取る


scanfやgetsを使うのは危険だと聞いた。
scanfと同じ用な感じで安全に受け取るには、
fgetsとsscanfを使えば良さそう。

```c:main.c
#include <stdio.h>

int main()
{
    char buf[80];
    int a, b;

    fgets(buf, 80, stdin);
    sscanf(buf, "%d %d", &a, &b);

    printf("%d + %d = %d\n", a, b, a+b);

    return 0;
}
即売会サービスを作ろう３


アイテム管理機能のDB設計が終わったので、次はapiを作ります
必要なapiは

1. サークル作成
1. サークル情報取得
1. サークル情報更新
1. アイテム登録
1. アイテム情報取得
1. アイテム情報更新
1. 登録アイテム一覧

といったところでしょうか。結構ありますね。

今回はサークル周りを作ってみました。
サークルの作成と、アイコン、サークル名の変更ができます。

https://github.com/nagai/freemarket/tree/20140405



##新しく覚えたこと

###### webapp2 について
multipart/form-data で受け取った画像を扱う場合(キーは'circlecut'とします)

* self.request.params["circlecut"].filename でファイル名
* self.request.params["circlecut"].type でmine type
* self.request.get('circlecut') で画像バイナリ本体

にアクセスできる



###### cloud storage

GAE上で CloudStorageにアクセスする場合は Google Cloud Storage Python Client Library を使う
https://developers.google.com/appengine/docs/python/googlecloudstorageclient/?hl=ja

GCSへのファイル書き込みは

```python:controller/user/api/circle.py
circlecutBlob  = self.request.get('circlecut')
circlecutType  = self.request.params["circlecut"].type

circlecutHash = hashlib.md5(circlecutBlob).hexdigest()
circlecutpath = Common.createCirclecutPath(circlecutHash)

gcs_file = gcs.open(circlecutpath,
						'w',
						content_type=circlecutType,
						options={},
						retry_params=gcs.RetryParams(backoff_factor=1.1))
gcs_file.write(circlecutBlob)
gcs_file.close()
```

となっていて、POSTリクエスト multipart/form-data で飛んできた画像を '/freemarket/circlecut/MD5'のファイルパスで CloudStorage に保存しています。
最近のAppEngine はローカル環境用 CloudStorage というのが用意されていて、今回保存したファイルであれば devserver 起動後 http://localhost:8080/_ah/gcs/freemarket/circlecut/xxxxxx といった形でブラウザから確認できます


##残タスク
1. アイテム登録
1. アイテム情報取得
1. アイテム情報更新
1. 登録アイテム一覧

##今後の課題
* UIの色を変更したい
* 配送方法が不明
GDG DevFest 2014 Spring GAS hanson Web Application

この資料について
----

下記サンプルは、2014/04/06開催されたGDG DevFest2014 SpringのGASハンズオンの拡張資料です。

始める前に
========

メインのハンズオンが終わっていることを期待しています。設定等は下記資料参照のこと
https://docs.google.com/presentation/d/1MFWNWHOhuFJXa_vgCnRYOL0Tu6TiNszCwovAHuJPy94/edit#slide=id.p

動作デモ
========
https://script.google.com/macros/s/AKfycbyD8rM3yM0ofDMtyXOyosE5hocyzqhgjXr0UnxjaA25nzPfGmU/exec
初回実行時に承認ダイアログが出ます。実行権限はアクセスした本人になっています。検索クエリ等は収集していません。



```js:main.gs
function doGet() {
  
  ytJson = getYoutubeResult()
  var template = HtmlService.createTemplateFromFile("list.html");
  var body = template.evaluate().getContent();
  //Logger.log(body);

  return HtmlService.createHtmlOutput(body).setSandboxMode(HtmlService.SandboxMode.NATIVE);
}

function getYoutubeResult(query, cnt){
  _q = check_query(query)
  _cnt = check_cnt(cnt)
  var result = YouTube.Search.list("snippet", {
    q: _q,
    order: "date",
    maxResults: _cnt,
  });
  Logger.log("get youtube");
  Logger.log( _q );
  Logger.log( _cnt );

  return result
}


function check_query(arg){
  Logger.log("check query");  
  Logger.log( arg );
  if(arg==undefined){
    return 'Google Apps Script';
  } else {
    return arg;
  }
}

function check_cnt(arg){
        return arg || 30;
}

```


```html:list.html
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<style>
body{
  padding: 30px;
}

.contents{
  background-color: #EEE;
}
.ytVideo{
  margin: 3px;
  padding: 5px;
  float: left;
  background-color: #fff;
  border: 1px gray solid;
}

#controls{
  padding: 10px;
  margin: 10px;
  border: 1px gray solid;
  border-radius: 10px;
}

#ytList{
  float: left;
  padding: 30px;
  background-color: #AAA;
}
</style>

<script>
$(function() {
update();
$("#seatch_button").on('click', update );
$("#remove_button").on("click", removeItems );

function show_yt_list(ytJson) {
  var list = $('#ytList');
  list.empty();
  list.append('<div class="contents">');
  for (var i = 0; i < ytJson.items.length; i++) {
    list.append(
    '<div class="ytVideo">' + 
    "<a href='https://www.youtube.com/watch?v=" + ytJson.items[i].id.videoId +"' target=_blank>" +
    "<img src=" + ytJson.items[i].snippet.thumbnails.medium.url + "><br>" +
    //ytJson.items[i].snippet.title +
    "</a>" +
    '</div>');
  }
  list.append('</div');
}

function removeItems(){
  $("#ytList").html("Empty");
}

function update(){
  removeItems();
  var _query = $("#search_query").val();
  var _count = $("#search_count").val();
  console.log( _query );
  console.log( _count );
  google.script.run.withSuccessHandler(show_yt_list).getYoutubeResult(_query, _count);
}
});


</script>

<div id='controls'>
  <label>Search:</label>
  <input type='text' size=50 id="search_query" value="Google Apps Scripts"/>
  <input type='text' size=3 id="search_count" value="20"/>  
  <button id="seatch_button">update</button>
  <button id="remove_button">reset</button>
</div>
<div id="ytList">empty</div>


```
第20回オフラインリアルタイムどう書くの問題


オフラインでリアルタイムに「どう書く」をやるイベント( http://atnd.org/events/48500 )を行っています。

問題は「会議の時間」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/ord20meetime/
です。

出題者の気分としては、問題を読み始めてから解けるまで1時間ぐらいあれば足りるかな、と思ってますが、ひとそれぞれで。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。

似たような問題をもっと解きたいという方は、上記の atnd に過去問リンク集がありますので、そちらをご覧になると良いと思います。

【宣伝】
CodeIQ に出している問題
https://codeiq.jp/ace/nabetani_takenori/q820
もよろしく。
※ CodeIQ の方は締め切るまで解答を公開しないようお願いします。
Qiitaで自分のプロフィールアイコン画像がリンク切れの時

Qiitaで自身のプロフィール画像にTwitterのものを使っている場合2、3週間前から画像がリンク切れ状態になってました。
pbs.twimg.comから画像を引っ張ってきてるようですが、画像URLに直接アクセスしてもやっぱり表示されない。

という事で自分のQiitaプロフィール編集ページでプロフィール画像の[Reload]ボタンクリック後、プロフィールを保存すると正常に表示されるようになりました。
HaxeをFDTで使ってみる


そろそろIDEを設定してみる。MacだとFDTあたりが無難っぽい。

![fdt-haxe.png](https://qiita-image-store.s3.amazonaws.com/0/20773/7716aefd-7f7a-c700-720d-94831aa54f4f.png "fdt-haxe.png")


## FDT FREE版をインストールする
http://fdt.powerflasher.com/buy-download/

![fdt-download-6.png](https://qiita-image-store.s3.amazonaws.com/0/20773/b957aec3-e219-69da-96b3-e8fa9b6e53e2.png "fdt-download-6.png")

## SDKをインストール
Haxe SDKがまだなければ http://haxe.org/download から準備しておく
Flashターゲットで制作するので Flex SDK を入れておく

4.6
http://www.adobe.com/devnet/flex/flex-sdk-download.html
3.6
http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex3sdk

解凍したら任意の場所におく。
今回は /Applications/Adobe Flex/ に配置

## FDT を設定する
起動するとセットアップウィザードがはじまる

![FDT-Setup-3-3.png](https://qiita-image-store.s3.amazonaws.com/0/20773/7dd1e0b2-ee14-273a-b97f-2954b659f289.png "FDT-Setup-3-3.png")
FREE 版を選択

![FDT-Setup-4-2.png](https://qiita-image-store.s3.amazonaws.com/0/20773/27cd4ee5-4740-6ca8-67e9-fe7ff3f40c5d.png "FDT-Setup-4-2.png")
FlexeとHaxeを選択

![FDT-Setup-5-2.png](https://qiita-image-store.s3.amazonaws.com/0/20773/4ab54536-2922-84e8-1cd9-536cd490fd2a.png "FDT-Setup-5-2.png")
[Scan for SDK] でSDKを選択
（先ほどインストールした /Applications/Adobe Flex/ を選ぶとそこからスキャンしてくれる）

## 環境設定を開く
デバッグプレイヤーの設定をすませる

![FDT-Preferences-Player.png](https://qiita-image-store.s3.amazonaws.com/0/20773/33d6764d-8556-75f5-5c78-72698f0e70f3.png "FDT-Preferences-Player.png")
デフォルトでFlash playerが立ち上がるようにする

![FDT-Preferences-Flash.png](https://qiita-image-store.s3.amazonaws.com/0/20773/598fb698-9923-397b-c69b-fbc21080917b.png "FDT-Preferences-Flash.png")
Flash IDEとデバッグプレイヤーのパスを指定する

![FDT-Preferences-Haxe.png](https://qiita-image-store.s3.amazonaws.com/0/20773/3c516cc8-194c-d695-d542-03539ae5e824.png "FDT-Preferences-Haxe.png")
Haxe SDK のパスを指定する

## プロジェクトをつくる

![FDT-MakeProject.png](https://qiita-image-store.s3.amazonaws.com/0/20773/92352144-3b45-81b6-040c-feff97315ff1.png "FDT-MakeProject.png")
FlashベースのHaxeプロジェクトを選択する

![FDT-DebugConfig.png](https://qiita-image-store.s3.amazonaws.com/0/20773/1495f5a9-fe74-4f6a-d614-f560065110f6.png "FDT-DebugConfig.png")
デバッグ設定をつくる

![FDT-DebugConfig-Haxe.png](https://qiita-image-store.s3.amazonaws.com/0/20773/e8b3b82a-2a48-1bbc-eee6-b1ac695d1750.png "FDT-DebugConfig-Haxe.png")
External SWF を選んでおくとプレイヤー単体で起動してくれる

![FDT-compiled.png](https://qiita-image-store.s3.amazonaws.com/0/20773/5d6624dc-3aa3-8ad4-0eb2-2e2a7f8aba8e.png "FDT-compiled.png")
起動した
コメントによるコードの切り替え

2種類のコードを書いて、切り替えながらコーディングしたい場合がある。
ブロックコメントとラインコメントを利用して、1文字入れたり消したりするだけで簡単にコードを切り替える方法

**自分用にソース書きながら比較する程度なら良いですが、これコミットしたりすると迷惑なのでやめましょう。**

例えば、こんな感じで書くと、コード1が有効になる。

```java
/**/
System.out.println("コード1");
/*/
System.out.println("コード2");
//*/
```

最初の行のブロックコメントを閉じている部分にスペースなどを入れると、コード2が有効になる。

```java
/** /
System.out.println("コード1");
/*/
System.out.println("コード2");
//*/
```

SQLもできる

```sql
SELECT *
FROM shop
WHERE
/**/
shop_id = 1
/*/
shop_id = 2
-- */
```
CoffeeScriptワンポイント - 値を返さない関数にはreturnを付ける

CoffeeScriptには「関数で最後に評価した値が戻り値になる」というルールがあります。これはどの教科書にも書いてありますので説明は省略しますが、これでいちいちreturnを書く手間を省けます。

またCoffeeScriptではforやwhileも左辺値になり、最終文の値を要素とする配列を返します。こちらは簡単な例を示します。

``` coffeescript
a = for x in [0..5]
  x * x
console.log a   # => [ 0, 1, 4, 9, 16, 25 ]

b = while a.length > 0
  a.pop()
console.log b   # => [ 25, 16, 9, 4, 1, 0 ]

```

さらに内包表記を使うと一行に収まりますが、演算子の優先順位には注意が必要です。

``` coffeescript
a = (x * x for x in [0..5])         # (...)が必要
console.log a   # => [ 0, 1, 4, 9, 16, 25 ]

b = (a.pop() while a.length > 0)    # これも(...)が必要
console.log b   # => [ 25, 16, 9, 4, 1, 0 ]

```

ところがこれを関数の中で用いると思わぬ副作用を生じることがあります。次の例は簡単な数値配列のフォーマット出力関数です。

``` coffeescript:printNumbers.coffee
# sprintf("%#{w}.#{f}f", n) のCoffeeScript版
sprintf = (n, w, f) ->
  buf = n.toFixed f
  buf = ' ' + buf while w > buf.length
  buf

printNumbers = (numbers, w, f) ->   # CoffeeScriptならたった一行(なのに...)
  console.log sprintf n, w, f for n in numbers

printNumbers [1.5, 7.3, -4.1], 5, 1
### 出力は次の通り
  1.5
  7.3
 -4.1
###

```

これは正しく動作しますが、`coffee -c printNumbers.coffee`でJavaScriptソースを生成すると無駄なコードが作られているのが分かります。

``` javascript:printNumbers.js
// Generated by CoffeeScript 1.7.1
(function() {
  var printNumbers, sprintf;

  // 中略

  // 何でこんなに長くなるのか? 実は理由がある
  printNumbers = function(numbers, w, f) {
    var n, _i, _len, _results;
    _results = [];      // 値を返すための(無駄な)配列
    for (_i = 0, _len = numbers.length; _i < _len; _i++) {
      n = numbers[_i];
      _results.push(console.log(sprintf(n, w, f)));
      // console.log(...)の戻り値(undefined)を追加
    }
    return _results;    // => [ undefined, undefined, ... ]
  };

  // 以下略

}).call(this);

```

原因はたまたまprintNumbers関数の最終文がforだったためです。forの中は`console.log`ですがこれは値を返しません。そこでprintNumbersは`[ undefined, undefined, ... ]`を生成して戻り値として返します。

undefinedだけの配列は無害ですが何の役にも立ちませんから直しましょう。最後に単独のreturnを追加すれば解決できます。

``` coffeescript
printNumbers = (numbers, w, f) ->
  console.log sprintf n, w, f for n in numbers
  return        # <= !!! 追加 !!!
```

これでJavaScriptの出力もすっきりします。

``` javascript
// Generated by CoffeeScript 1.7.1
(function() {

  // 中略

  // この出力ならリーズナブル(修正不要)
  printNumbers = function(numbers, w, f) {
    var n, _i, _len;
    for (_i = 0, _len = numbers.length; _i < _len; _i++) {
      n = numbers[_i];
      console.log(sprintf(n, w, f));
    }
  };

  // 以下略

}).call(this);

```

しかしforやwhileが最後にならない場合も「(最終版コードには)値を返さない関数は必ず最後にreturnを付ける」ことをお勧めします。次のような簡単な場合でもCoffeeScriptは「最後に実行した結果が戻り値」というルールに従い不要なreturn文を生成しています。

``` coffeescript
log = (x) ->    # console.logの短縮形
  console.log x
```

``` javascript
// Generated by CoffeeScript 1.7.1
(function() {
  var log;

  log = function(x) {
    return console.log(x);      // このreturnは不要
  };

}).call(this);
```

これを抑制するのがCoffeeScriptの単独return文です。

``` coffeescript
log = (x) ->
  console.log x
  return        # <= 追加
```

``` javascript
// Generated by CoffeeScript 1.7.1
(function() {
  var log;

  log = function(x) {
    console.log(x);     // returnは付かない
  };

}).call(this);
```

これは私が[天気データマップ](http://tenki-data-map.herokuapp.com/)を作っている最中に気付いたCoffeeScriptのちょっとした注意点です。returnを書かなくても動作は変わりませんが、これに気付いてコードを修正したところけっこうな最適化効果がありました。
RubyCocoaでCPU温度を取得する

# 背景

この前、[21世紀のパソコンサンデーを聞いた感想をツイート](https://twitter.com/kjunichi/status/448991896229003264)したらご本人にフォぼられるというプレッシャーから書いてます。

[RubyCocoa で IOKit を使う - ぼんやりと考えたこと](http://h7a.org/blog/entry/1515)

## なんでLinuxと違って、WinやOSXはCPUの温度すらコマンドラインで取れないの？

そんな素朴な疑問から初代MacBook AirのKernel task問題に苦しめられる以前の、ページを見つけるも、デスマーチに巻き込まれて触らずじまいで、気がついたらイクメンやってる状況でした。


# Mavericksで動かすには

## APIの変更が必要
### IOConnectMethodStructureIStructureOからIOConnectCallStructMethodに

Firefoxの以下のページが分かりやすかった

[mozilla-central: changeset 33086:aae349de03be](http://hg.mozilla.org/mozilla-central/rev/aae349de03be)


### ioservice.rb

```
def structure_io(cmd, isize, osize, i, o)
    #return OSX::IOConnectMethodStructureIStructureO(@conn.int, cmd, isize, osize, i, o)
    return OSX::IOConnectCallStructMethod(@conn.int, cmd, i, isize, o, osize)
end
```

### myIOKit.bridgesupport

```
<function name='IOConnectMethodStructureIStructureO'>
    <arg type='I'/>
    <arg type='I'/>
    <arg type='I'/>
    <arg type='^I' type_modifier='N'/>
    <arg type='^[' type_modifier='n'/>
    <arg type='^[' type_modifier='o'/>
    <retval type='I'/>
  </function>
```

を、以下のように変更

```
<function name='IOConnectCallStructMethod'>
    <arg type='I'/>
    <arg type='I'/>
    <arg type='^[' type_modifier='n'/>
    <arg type='I'/>
    <arg type='^[' type_modifier='o'/>
    <arg type='^I' type_modifier='N'/>
    <retval type='I'/>
  </function>
```
# MavericksでRubyCocoaを動かす

```
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby smc.rb
```

# 動かしてわかったこと

## 当時のMacBook Proに依存したコードだった

HDDを保護するGセンサーはSSDな時代のMacBook Proには
無いですし、うまく取得できない項目がnilとして扱われて怒られたりで、
smc.rbを適当にコメントアウトして、動いたり動かなかったりでした。

# まとめ

OSXのブリッジサポートの仕組みに触れることが出来た。

[C言語版](https://gist.github.com/edvakf/4049362)をこの作業中に見つけることが出来た。

こちらは、自分の環境では安定して動いた。

NodObjCで同様の実装をする際の参考になりそう。

# 関連記事

- [macOSのCPU温度をgRPCを使ってElectronで作ったデスクトップマスコットに表示させた](https://abrakatabura.hatenablog.com/entry/2018/07/23/100505)
shunit の導入(zshで使う場合)

# shunit の導入(zshで使う場合)

## 持ってくる

 * 最新とか簡単に入れたいからgithubから

```
$ git clone https://github.com/zanshine/shunit2.git
```

## テストコード書く
```
#!/usr/bin/env zsh

set -ue

cd $(cd $(dirname $0); pwd)

# zshの場合は明示してあげないとダメ
SHUNIT_PARENT=$0

. ../bin/string.sh

function test_trim () {
    # 1. 先頭だけにスペースがあるケース
    assertEquals "$(trim '    hoge  foo   bar')" 'hoge  foo   bar'

    # 2. 末尾だけにスペースがあるケース
    assertEquals "$(trim 'hoge  foo   bar   ')" 'hoge  foo   bar'

    # 3. 先頭/末尾ともにスペースがあるケース
    assertEquals "$(trim '    hoge  foo   bar   ')" 'hoge  foo   bar'

    # 4. 先頭/末尾ともにスペースがないケース
    assertEquals "$(trim 'hoge  foo   bar')" 'hoge  foo   bar'
}

. ../../shunit2/src/shunit2
```

## テストが通る関数書く
```
#!/usr/bin/env zsh

set -ue

function trim () {
    echo "$(echo "$1" | sed 's/^  *//' | sed 's/  *$//')"
}
```

## とりあえず、動かしてみる その1

 * これだと何も起こらない

```
$ zsh string.t
```

## とりあえず、動かしてみる その2

 * shwordsplit オプションが必要

```
$ zsh -o shwordsplit -- string.t
../../shunit2/src/shunit2:readonly:64: not valid in this context: (標準入力)
```

## 問題箇所を修正する

 * あとでプルリク投げておこう

```
diff --git a/src/shunit2 b/src/shunit2
index 7077149..796fa18 100755
--- a/src/shunit2
+++ b/src/shunit2
@@ -51,7 +51,7 @@ __SHUNIT_MODE_STANDALONE='standalone'
 __SHUNIT_PARENT=${SHUNIT_PARENT:-$0}

 # set the constants readonly
-shunit_constants_=`set |grep '^__SHUNIT_' |cut -d= -f1`
+shunit_constants_=`set |grep --text --binary-files=text '^__SHUNIT_' |cut -d= -f1`
 echo "${shunit_constants_}" |grep '^Binary file' >/dev/null && \
     shunit_constants_=`set |grep -a '^__SHUNIT_' |cut -d= -f1`
 for shunit_constant_ in ${shunit_constants_}; do
```

 * これで動く

```
$ zsh -o shwordsplit -- string.t
test_trim

Ran 1 test.

OK
```
dplyr で unsupported type for column てエラーが出た

```r
mutate(data, RegisterDate=strptime(RegisterDate, "%Y/%m/%d %H:%M:%S"))
```

```
Error: unsupported type for column 'RegisterDate' (VECSXP,  classes = POSIXlt, POSIXt)
```

どうやら POSIXlt 使えないらしい。
POSIXct に変換したらうまくいきました。

```r
mutate(data, RegisterDate=as.POSIXct(strptime(RegisterDate, "%Y/%m/%d %H:%M:%S")))
```
ls コマンドをカラーで

# ls の結果をカラー表示

## Debian

 * ls --color=auto

### ディレクトリが青色だと黒い画面で見づらい(Debian)

 * 色設定を一旦、ファイルに吐き出してディレクトリ部分を変更する

```
$ dircolors -p > ~/.colorrc
$ $EDITOR ~/.colorrc
```

 * 下記の 34 を 41 にすれば背景色赤になってディレクトリ判定しやすい

```
DIR 01;34 # directory
```

## Mac

 * ls -G

### ディレクトリが青色だと黒い画面で見づらい(Mac)

 * 先頭の1文字目がディレクトリ文字色、2文字目が背景色
 * 1文字目をx(無効)にして、2文字目をb(赤)に変更

```
$ export LSCOLORS=xbfxcxdxbxegedabagacad
```

## .bashrc に反映しておく
 * uname コマンド使ってOS判定してもらえば個別管理しなくて済む

```
if [ "$(uname)" = 'Darwin' ]; then
    export LSCOLORS=xbfxcxdxbxegedabagacad
    alias ls='ls -G'
else
    eval `dircolors ~/.colorrc`
    alias ls='ls --color=auto'
fi
```

## 参考にしたサイト
 * [シェル(bash)でOS判定分岐](http://d.hatena.ne.jp/yuta84q/20090127/1233067498)
 * [ls コマンドで遊ぶ](http://www.gfd-dennou.org/arch/morikawa/memo/ls_colors.txt)
 * [Terminal.appでlsのファイル色を変える](http://d.hatena.ne.jp/edvakf/20080413/1208042916)
OutOfMemoryError対策


[【Android】OutOfMemoryと戦う【OOM】](http://qiita.com/satoshinew/items/00f277c8b96e8d4dc368)に触発されたので自分なりの対策をまとめます。主にAndroid2.3系の話です。

メモリリークとWeakReferenceの話は省きます。

##ヒープ外にBitmapをロード

BitmapをBitmapFactoryでロードする際に、隠しAPIのinNativeAllocを使ってヒープ外にBitmapをロードすることが出来ます。(Android2系まで)

```java
BitmapFactory.Options options = new BitmapFactory.Options();
try{
	Field field = BitmapFactory.Options.getClass().getField("inNativeAlloc");
	field.set(options, true);
}catch(Exception e){
}
```

ヒープの拡大も行われないことから、純粋にロード時間の短縮にもなります。注意点として、LinuxのOOM-Killerに殺される可能性が出てきます。その際は例外をスローせずに静かにプロセスが終了します。

##ActivityやService単位でプロセスを分離

プロセス単位で最大のヒープサイズが割り当てられていますので、プロセスを分離することでActivity単位で最大のヒープサイズまで使用することが出来ます。

http://developer.android.com/intl/ja/guide/topics/manifest/activity-element.html
AndroidManifest.xmlのActivityタグにprocess属性を付けることで、プロセスの分離が可能です。

プロセスの分離を行う際には変数のスコープに要注意です。static変数は同一プロセスの同一のクラスローダーの範囲で有効スコープです。最初のActivityのstatic変数にセットした値が、次のActivityで取得できなくなります。

##大きなメモリ確保を行う際にtry/catch

あまりオススメできる方法ではありませんが、try/catchでOutOfMemoryErrorを捕まえるのも方法としてありです。(実際にAndroidのAPIの実装にも見ることが出来ます。)

```java:
try{
	//メモリを食う処理
}catch(OutOfMemoryError e){
	//代替の処理
}
```

##AsyncTaskを過信しない

リストビューで画像を表示する際などにAsyncTaskを使うと思いますが、AsyncTaskは並列数の制限が大きいため、通信が遅い状態でスクロールをすると沢山スレッドが作成されます。適切に通信やタスクをキャンセルするか、Executors.newFixedThreadPoolで同時処理数が固定のスレッドプールを使うのがオススメです。
rubyのp()的なものがScalaにも欲しい

http://d.hatena.ne.jp/tonfabeem/20131110/1384044294 を参考に。ちょっとだけ改変。

```scala
//Array以外は動くpメソッド
def p[T](t: T)(implicit mt: Manifest[T] = null) = {
	println("%s: %s".format(t, 
		if (mt == null) "<?>" 
		else mt.toString)
	)
}
```

として、

```scala
val l1 = List(1, 2, 3)
val l2 = List(1, "hoge", l1)
p(l2)
```

とかすると

```scala
List(1, hoge, List(1, 2, 3)): scala.collection.immutable.List[Any]
```

こんな風にコンソールに出て幸せになれる。

リンク元にはArrayの時の解決策も載ってるので、型情報を調べてArrayの時はそっちの処理にしようかと思ったら、実行時に型情報取るのむちゃくちゃ大変っぽいので断念。

2.10以降はtagTypeで取るらしいけど最初から処理系にこれとっといてね、って指示しないと行けないのでutilがそれを前提にするのは辛いかなと。
eclipseのDBviewerよりサーバーのMYSQLへアクセス

eclipseのDBviewerよりサーバーのMY SQLへアクセスを行います。

（１）MySQL Connectorをダウンロード＆インストール
　　　http://dev.mysql.com/downloads/connector/j/
（２）eclipseのDBviewerよりデータベース定義の登録.JPG＆接続情報の設定.JPGを行う。
![データベース定義の登録.JPG](https://qiita-image-store.s3.amazonaws.com/0/37952/f3f2fd94-a00c-f37d-d283-e80d24bbdbb6.jpeg)
![接続情報の設定.JPG](https://qiita-image-store.s3.amazonaws.com/0/37952/116aaea2-6645-5ef8-6c1d-72685e96c7ae.jpeg)

これでできました！！今までターミナルでアクセスしていたのに比べて断然良いです:)