OmniAICreator/Qiita-1.07M huggingface dataset:
Railsでログイン機能を自作する（少人数向け）

# 目的
gemのdeviseを使えば簡単なんだけど、利用人数が限定されていて、ID・PASSもあまり変えることはなくて、ログインユーザーによって表示する内容を変えたいという限定的な状況で、わざわざdeviseを使う必要もないので自作してみました。

# 考え方
ログイン画面でIDとPASSを入力
↓
modelでIDとPASSの整合性確認
↓
TOP画面でIDによって表示する内容を変更

# ソース
ルートファイル

```ruby:routes.rb
  get 'dogorcat' => 'dogorcat#login'
  post 'dogorcat/top' => 'dogorcat#top'
  get 'dogorcat/top' => 'dogorcat#top'
```

コントローラー

```ruby:dogorcat_controller.rb
class DogorcatController < ApplicationController
  def login
    @form = Dogorcat.new
  end

  def top
# 直接'dogorcat/top'にアクセスしようとしたらログイン画面にリダイレクトする
    if params[:dogorcat] == nil
        redirect_to :action => "login"
        return
    else
    @form = Dogorcat.new(dogorcat_params)
# ID・PASSの整合性が取れなかったらログイン画面を表示する
      if @form.valid?
      else
        render :login
        return
      end
    end
  end

    private
      def dogorcat_params
        params.require(:dogorcat).permit(:login_id, :login_pass)
      end
end
```

モデル
IDが’dog’と’cat’
PASSが’1234’と’5678’
で全て以下サイトにてMD5変換して記載
[MD5変換(MD5),MD5逆変換(MD5Reverse)](view-source:http://www.kiyori.co.jp/md5reverse/)

```ruby:dogorcat.rb
class Dogorcat < ActiveRecord::Base
  require 'digest/md5'
  validate :password_check

  def password_check
# dog
    if (Digest::MD5.hexdigest(login_id) == '06d80eb0c50b49a509b49f2424e8c805' && Digest::MD5.hexdigest(login_pass) == '81dc9bdb52d04dc20036dbd8313ed055')
# cat
    elsif (Digest::MD5.hexdigest(login_id) == 'd077f244def8a70e5ea758bd8352fcd8' && Digest::MD5.hexdigest(login_pass) == '674f3c2c1a8a6f90461e8a66fb5550ba')
# IDかPASSが間違っていたら@form.errorsの:bad_passwordに値を入れる
    else
      errors.add(:bad_password, "IDもしくはパスワードが間違っています。")
    end 
  end

end
```

ビュー(ログイン画面)

```ruby:login.html.erb
<h3><strong>ログイン画面</strong></h3>
<div>
  <p>IDとパスワードを入力して、ログインボタンからログインしてください。</p>
</div>
<p>
  <% if @form.errors[:bad_password].present? %>
    IDもしくはパスワードが間違っています。
  <% end %>
</p>
<%= form_for(@form, :url => '/dogorcat/top') do |f| %>
  <table>
    <tbody>
      <tr>
        <th scope="row"><strong>ログインID</strong></th>
        <td><%= f.text_field :login_id %></td>
      </tr>
      <tr>
        <th scope="row"><strong>パスワード</strong></th>
        <td><%= f.password_field :login_pass %></td>
      </tr>
    </tbody>
  </table>
  <div>
    <%= f.submit 'ログイン', :class => "button" %>
  </div>
<% end %>

```

ビュー(TOP画面)

```ruby:login.html.erb
<% if @form.login_id == 'dog' %>
  あなたは犬です！ワンワン♪
<% elsif @form.login_id == 'cat' %>
  あなたは猫です！ミャー♪
<% else %>
  ここは表示されないはず・・・
<% end %>
```

# まとめ
とりあえずこれでできましたが問題点が一杯あります。
まず、「目的」欄に書いた以外の条件では使いづらいです。
理由としては
1.ユーザーが増えるとモデルとビューにそれぞれ書き足さないといけない。
　※ユーザーが減る場合もモデルとビューから削除しないといけない。
2.ID・PASSの変更はソースが分かっているひとしかできない。
です。

他にもMD5変換しているとは言え、ソースに直接ID・PASSを書いているのでセキュリティ上最高とは言えないという問題点もあります。
（これは環境変数に持たせればいいかもですが・・・）

個人情報が含まれる内容とか絶対に他人には見せられない情報を載せる以外なら使えるかもしれません。
git commandが効かなくなった

##急にgitが使えなくなった
Visual code studioでcommitをしようとしたら、「gitをinstallしてください」みたいな文章を出された。Macだからgitは標準で入ってるだろと思いながらも

```
$ git --version
```
を叩いてみると、

```
Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
```

んー。Xcodeのライセンスに同意しろって言われた。

OS Xをupdateした後に初めて再起動したから？
原因がわからなかったが、Xcode開いて、利用規約に同意すると直る。

##Xcode起動するのめんどくさい問題

```
$ sudo xcrun cc
```
って打ってspace連打して最後に

```
$ agree
```
その後

```
$ git --version
```
で確認

```
git version 2.8.4 (Apple Git-73)
```
これでまたgitが使えるようになりました。

##Homebrewのgitに切り替える
このままだと、なんかのひょうしにまたライセンスに同意しろって言われそうなので、Homebrewのgitに切り替えることにした。

```
$ brew list
```
でHomebrewでinstallしたものを確認。
`git`がなかったのでinstallする

```
$ brew install git
```
installが終わったら

```
$ vi ~/.bash_profile
```
で

```
$ export PATH="/usr/local/Cellar/git/2.5.0/bin:$PATH"
```
pathを通す

最後にTerminalを再起動して

```
$ git --version
  git version 2.8.2
```

homebrew側のgitに切り替えられた。
CordovaプラグインとAndroidパーミッションについて

Cordovaを利用したハイブリッドアプリを作成する際、ネイティブ機能を利用する場合は、Cordovaプラグイン経由でアクセスする必要があります。

利用するCordovaプラグインでAndroidパーミッションの設定が必要な場合は、Cordovaプラグインの設定ファイルであるplugin.xmlに記載されています。

例として、cordova-plugin-cameraプラグインのplugin.xmlには、下記のように設定されています。

```xml:plugin.xml
<platform name="android">
  <config-file target="AndroidManifest.xml" parent="/*">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  </config-file>
</platform>
```

cordova-plugin-cameraプラグインでは、外部記憶領域への書き込みに対する「WRITE_EXTERNAL_STORAGE」が、設定されています。

このplugin.xmlに設定されているパーミッションは、ビルド時にAndroidManifest.xmlに書き込まれます。

開発するアプリで、外部記憶領域への読み込みのみ必要な場合は、cordoba-plugin-cameraプラグインの[GitHub](https://github.com/apache/cordova-plugin-camera) からダウンロードしたzipファイルを解凍し、plugin.xmlの「WRITE_EXTERNAL_STORAGE」を「READ_EXTERNAL_STORAGE」に変更し、再度zipファイルにすることにより、パーミッションを変更させたカスタムCordovaプラグインを作成することができます。

ビルドしたapkファイルに設定されているパーミッションは、[AXMLPrinter2.jar](https://code.google.com/archive/p/android4me/downloads) を利用することで確認することができます。

#確認手順
1. ビルドしたファイルの拡張子を「apk」から「zip」に変更し、解凍します。
2. 解凍したファイルにあるAndroidManifest.xmlを任意の場所にコピーします。
3. ターミナルで下記のコマンドを入力し、実行します。

```
java -jar AXMLPrinter2.jar AndroidManifest.xml
```
Excelファイルを別ウィンドウで表示したい

#やりたいこと
+ Excelファイルはそのままの設定だと、同じウィンドウで開くしかない。
+ 表示から並べてる想定だろうが。そもそもウィンドウとしてまとまってほしくない。<BR>~~（タブブラウザみたいならいいのに・・・）~~
+ xlsxファイルとxlsファイルを開くとき、何も考えずに別のウィンドウで開けるようにしたい。

#やること
レジストリをいじる
**※自己責任でお願いします。**

##xlsxの開き方に関するレジストリをいじる
下記内容をコピペした.regファイルを作ってダブルクリックする

```xls_Open_New_Window.reg
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Excel.Sheet.12\shell]
@="別のウィンドウで開く(&W)"

[HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\別のウィンドウで開く(&W)]

[HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\別のウィンドウで開く(&W)\command]
@="\"C:\\Program Files (x86)\\Microsoft Office\\Office14\\EXCEL.EXE\" \"%1\""

```


##xlsの開き方に関するレジストリをいじる
下記内容をコピペした.regファイルを作ってダブルクリックする

```xls_Open_New_Window.reg
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Excel.Sheet.8\shell]
@="別のウィンドウで開く(&W)"

[HKEY_CLASSES_ROOT\Excel.Sheet.8\shell\別のウィンドウで開く(&W)]

[HKEY_CLASSES_ROOT\Excel.Sheet.8\shell\別のウィンドウで開く(&W)\command]
@="\"C:\\Program Files (x86)\\Microsoft Office\\Office14\\EXCEL.EXE\" \"%1\""

```
#注意
Windows Updateすると規定値の開き方(Open)に戻るらしいので、そのたびにファイルを動かすとよいかと

#情報源

+ [Excel2010ファイルを別々のウィンドウで開く3つの方法](http://plaza.rakuten.co.jp/mscrtf/diary/201212280000/)
+ [Excelで新しいウィンドウで開くためにレジストリのどこをいじればよいか](http://d.hatena.ne.jp/shouh/20140531/1401493104)
zipファイルからfuelphp1.7 -> 1.8 へバージョンアップ（1.7->1.8）

fuelphp1.7のプロジェクトを fuelphp1.7.3 へヴァージョンアップした際、案外苦労したので記載します。

#1.まずはzipファイルダウンロード

Fuel のダウンロード - インストール - FuelPHP ドキュメント
http://fuelphp.jp/docs/1.9/installation/download.html
ここから1.7.3をダウンロードします。

#2.ファイルの入れ替え

以下のファイルを入れ替えます。
- fuel/core
- fuel/packages
- fuel/app/bootstrap.php
- public/.htaccess
- public/index.php

**修正しているconfigファイルは「fuel/app/config」入れて置いてください。**
普通は入れてると思うんですけど。。。僕は最初に「FuelPHPのURLからpublicを消す対応」で修正していたconfig/assets.phpをcoreに入れっぱなしで、assetsフォルダのファイルを読み込まなくなってしまっていました^^;

#3.oilのインストール
```
$ curl https://get.fuelphp.com/oil > oil_install.sh
$ sh oil_install.sh
```

#5（1.7.3以前の場合）.db.phpへunix_soketの追加
これでOKかなと思ったら、データベースへの接続ができなくなってしましました。。
1.7の時はunix_soketの記述なしで動いていたんですけど、1.7.3では必要みたいです。

```php:db.php(変更前)
'connection'  => array(
        'dsn'  => 'mysql:host=localhost;dbname=hogehoge;',
		'username'   => 'root',
		'password'   => 'root',
		),
```
```php:db.php(変更後)
'connection'  => array(
        'dsn'  => 'mysql:host=localhost;dbname=hogehoge;
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　unix_socket=/opt/boxen/data/mysql/socket',
		'username'   => 'root',
		'password'   => 'root',
		),
```



これでヴァージョンアップ後も正常動作行えました^^/
ruby puts debugger

https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html

http://www.schneems.com/2016/01/25/ruby-debugging-magic-cheat-sheet.html

```rb
require 'objspace'
ObjectSpace.trace_object_allocations_start

def foo
	x = baz
	bar x
end

def bar x
	p ObjectSpace.allocation_sourcefile(x) => ObjectSpace.allocation_sourceline(x)
end

def baz; zot; end
def zot; Object.new; end

foo
```
Gitのブランチを元にセッション管理を行うgit-switcher.vimプラグインを作った話

Vimのセッション管理には [session.vim](https://github.com/xolox/vim-session) を使っていたのですが、Git管理下のディレクトリで上手い具合にセッションを扱おうとするには物足りなかったので、ブランチ毎のセッション管理を簡単に行う [git-switcher.vim](https://github.com/ToruIwashita/git-switcher.vim) というプラグインを作りました。

## インストール

お使いのプラグインマネージャでインストールするか、[vim.org](http://www.vim.org/) から[プラグイン](http://www.vim.org/scripts/script.php?script_id=5446)をダウンロードして下さい。

[vim-plug](https://github.com/junegunn/vim-plug) の場合

```
Plug 'ToruIwashita/git-switcher.vim'
```

## 使い方

Git管理下のディレクトリ上でVimを起動して、セッションを保存したくなったら`GswSave`を実行しセッションを保存します。後はブランチを切り替える時に`Gsw`コマンドを使ってブランチを切り替えるだけです。
`Gsw`コマンド実行時、切り替えるブランチにマッチするセッションが保存されている場合にブランチ切り替えに追随してセッションがロードされます。

また、`Gsw`コマンドはデフォルトでブランチ切り替え時にセッションを保存するかの確認を行うので、`GswSave`コマンドを使わず`Gsw`コマンドだけでもセッションの保持・復元を行えます。

![git-switcher.vimサンプル](https://raw.githubusercontent.com/wiki/ToruIwashita/git-switcher.vim/images/git_switcher_example_new.gif)

## 代表的なコマンドとオプションについて

### コマンド

- `Gsw[!] <branch-name>`
作業ブランチを切り替えます。切り替え時にブランチと同名のセッションが保存されていた場合は同時にそのセッションをロードします。また、切り替え時に対象のブランチがローカルに存在しない場合は、新しいブランチを作成して切り替えます。

- `GswRemote[!] <branch-name>`
リモートリポジトリにあるブランチをローカルリポジトリに`checkout`します。その時、取得したブランチと同名のセッションが保存されている場合は、同時にそのセッションをロードします。

- `GswSave [session-name]`
現在の作業ブランチ名でセッションを保存します。引数を与えた場合は与えられた文字列をセッション名として保存します。

- `GswLoad [session-name]`
現在の作業ブランチ名のセッションを復元します。引数を与えた場合は与えられた文字列をセッション名として復元します。

- `GswDeleteSession[!] <session-name>`
指定されたセッションを削除します。

- `GswDeleteSessionsIfBranchNotExist[!]`
保存したセッションのうちローカルに同名のブランチが存在しないものを削除します。

### オプション

```
# セッションを保存するディレクトリパス。
g:gsw_sessions_dir = $HOME.'/.cache/vim/git_switcher'

# Gswコマンド実行時にセッションの保存の確認を行う。デフォルトはyes。
g:gsw_save_session_confirm = 'yes'

# vim起動時のセッション自動ロード設定。yes、no、confirmを設定可能でデフォルトはno。
g:gsw_autoload_session = 'no'

# vim起動時保存したセッションのうちローカルに同じ名前のブランチが存在しないものを削除する。yes、no、confirmを設定可能でデフォルトはno。
g:gsw_autodelete_sessions_if_branch_not_exist = 'no'
```

### 最後に

git-switcher.vim はGitのブランチを元にセッション管理を行うプラグインですが、通常のセッションの管理を session.vim、git関連のセッション管理を git-switcher.vim というように併用して使っていくのは微妙だったので、Git管理のディレクトリでなくとも`GswSave`や`GswLoad`などの一部のコマンドは動くようにしてあり、セッション管理は git-switcher.vim 一本でいけるようになっています。

良かったら使ってみて下さい。バグや要望などありましたら是非githubへの投稿お願いします。
iOS EnterpriseのOTA配信 OS 10で気をつけること

Enterprise App をOTA配信するときに気をつけること。
iOS9までは、.plist、.ipaともに
"itunesstored/1.0 iOS/10.0.1 model/iPhone8,2 hwp/s8003 build/14A403 (6; dt:142)"
こんな感じのUserAgentでくる。

iOS10の場合は、.plistは
"itunesstored/1.0 iOS/10.0.1 model/iPhone8,2 hwp/s8003 build/14A403 (6; dt:142)"
のような形でくるけど、
.ipaに対しては
"com.apple.appstored/1.0 iOS/10.0.1 model/iPhone8,2 hwp/s8003 build/14A403 (6; dt:142)"
のような感じでリクエストしてくる。

ここをみてNginxでごにょごにょっとしてたけど、
com.apple.appstoredも通すようにしないとダメでした。
[メモ] VirtualBoxの仮想ディスク変更コマンドのオプションが変わっていた

気付いたら、VirtualBoxのディスクイメージフォーマット変更と、ディスクサイズ変更のコマンドが変わっていたのでメモとして残しておく。
```
VBoxManage clonemedium disk <input disk image> <output disk image> --format <format>
VBoxManage modifymedium disk <disk image> --resize <size(MB)>
```
OpenGL 立方体描画

#OpenGLでの立方体描画のプログラミングメモ

```ruby:main1.cpp
#include <GLUT/glut.h>

#define WIDTH 320
#define HEIGHT 240

//赤
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };

//ライトの位置
GLfloat lightpos[] = { 1200.0, 150.0, -500.0, 1.0 };

void display(void)
{

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glViewport(0, 0, WIDTH, HEIGHT);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)
 gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);
 glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

 //視点の設定
 gluLookAt(150.0,100.0,-200.0, //カメラの座標
      0.0,0.0,0.0, // 注視点の座標
     0.0,1.0,0.0); // 画面の上方向を指すベクトル

 //ライトの設定
 glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

 //マテリアルの設定
 glMaterialfv(GL_FRONT, GL_DIFFUSE, red);
 glutSolidCube(40.0);

 glutSwapBuffers();
}

void idle(void)
{
 glutPostRedisplay();
}

void Init(){
 glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);

}

int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("立方体を表示");
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}
```

##実行結果
![スクリーンショット 2016-09-16 14.28.08.png](https://qiita-image-store.s3.amazonaws.com/0/85550/21966bcd-ff50-7a90-9ac0-0a58b08dc5f6.png)

・開発環境 Mac version10.10.5

・コンパイル方法
>
```bash:
 cc main1.cpp -framework GLUT -framework OpenGL -mmacosx-version-min=10.8
```

参考にさせて頂いたサイトは[こちら][link-1]
[link-1]:https://www21.atwiki.jp/opengl/pages/29.html
CentOS7(x64)でSSH接続できるクライアントをIPアドレスで制限する

    vi /etc/hosts.deny

下記を追記する。

    sshd : all

さらに、

    vi /etc/hosts.allow

下記を追記する。接続を許可したいクライアントのIPアドレスを設定

    sshd : 192.168.0.1
Rubyで相関係数の算出


SciRubyファミリーのStatsampleを使って、相関係数を一発で算出する。

```ruby
require 'statsample'
a = [1,2,3,4,5,6].to_vector
b = [5,2,nil,4,3,8].to_vector
pearson = Statsample::Bivariate::Pearson.new(a,b)
puts pearson.r
puts pearson.t
puts pearson.probability
puts pearson.summary
```

```Result
0.4608403716896188
0.8993962691856522
0.4347262709638615
Correlation ( - ) : r=0.461 (t:0.899, g.l.=3, p:0.435 / both tails)
```
CentOS 7でhostnameを変更する

## hostnamectlを使います

デフォルトのhostnameである「localhost.localdomain」から、「local.domain-server.com(任意)」に変更するため、hostnamectlコマンドを使います。

### 変更前
`$ hostname`
localhost.localdomain

### hostnamectlで変更する
`$ hostnamectl set-hostname local.domain-server.com`

※CentOS7インストール時にサーバソフトウェアを入れていると、以下のメッセージが出るので、sudoで実行します。

```
Could not set property: Interactive authentication required.
```

→権限がないので、sudoで実行。
`$ sudo hostnamectl set-hostname local.domain-server.com`

※ CentOS 7がminimalだと、以下のようなメッセージが出ます。

```
==== AUTHENTICATING FOR org.freedesktop.hostname1.set-static-hostname ===
Authentication is required to set the statically configured local host name, as well as the pretty host name.
Authenticating as: user01
Password: 
==== AUTHENTICATION COMPLETE ===
```
→Passwordプロンプトでパスワードを入力しEnterを押します。


### 変更後
`$ hostname`
local.domain-server.com

簡単ですね。

他にも、nmtuiや、nmcliで変更できますが、全部、/etc/hostnameを変更しているので、直接ファイルを編集しても同じことができます。

※ログイン中のプロンプトのホスト名は、一旦ログアウトしてログインし直さないと反映されません。
Ruby on Rails キャッシュ無効

注)Ruby on Rails 5.0.0を使っています。

Rails内をいじってサーバ再起動、いじってまた再起動を繰り返すのが面倒になってきて調べた対策をメモしておきます。下記を行うことで即座に修正が反映されるようにすることができます。

config/environments/development.rb
の1７行目あたりにある

```
config.action_controller.perform_caching = true
```
をfalseにするとキャッシュが無効になり、即反映できます。
JSONからCSVをつくるWebサービス

備忘録に

表題の通り下記にURLのWebサービスでJSONからCSVを作成することが出来る。
[Convert JSON to CSV](https://konklone.io/json/)

画面の上のほうにあるテキストボックスにJSON形式の文字列を入れてあげると
テキストボックス下に**Download the entire CSV**と出るので、
クリックすると変換後のCSVのダウンロードが出来ます

以上
PRの1行目にclose #issue番号と書くとIssueが閉じれる

#概要

コミットのメッセージに `close #Issue番号`　と書くとIssueが閉じれることは有名ですが、案外知られていないのが　**Pull Requestの1行目に `close #Issue番号`と書くとMergeされた段階でIssueを閉じることができる**事です。

# 使い方
PRを出すときにコメントの1行目に`close #Issue番号`　と書くだけです。

![PRを出している図](https://qiita-image-store.s3.amazonaws.com/0/62429/2ffb4e1c-e315-b460-e8fe-fa991888ce86.png)

すると、マージされたときに…
![スクリーンショット 2016-09-16 13.49.45.png](https://qiita-image-store.s3.amazonaws.com/0/62429/36f4eb9c-2fd9-ffb0-3e73-a548e5516b6b.png)

Issueが閉じられる！便利！

※デフォルトブランチにマージされないと閉じられないので気をつけましょう
Excel VBAで、マクロを作る時のTip


# はじめに
Office for Mac 2011で動作確認。おそらくWindowsでも動きます
Mac版はWin版に比べて使えない機能が多く(createObjectなどは一切使えない)、必ずしもWin版にとっては最適ではないかもしれません。

参考：[Mac版Excel(Office2011）のVBAを使う場合の注意点](http://qiita.com/sjuny/items/d3bf8e4dd9e609374575)

少しですが、使えるものを

[昨日までJavaJavaしてた人がいきなりExcelのVBAを実装する羽目になったときのためのメモ
ExcelExcel594VBAVBA354mvcmvc71
](http://qiita.com/opengl-8080/items/5bd8ae7fe95f5c31dfc3)

この記事も参考になります。

# モデル定義が面倒なとき

Excelのシートは肥大化しがち。それぞれにモデルを定義していたらきりがない。そんな時は、連想配列が便利でした。

Office for MacのVBAだとDictionaryが使えないため、以下ではCollectionを用いています。Win環境であれば、Dictionaryを使ったほうが良いと思います。（Containsメソッドなどが使えるため）

```vba
MaxRow = Cells(Rows.Count, 1).End(xlUp).Row
MaxCol = Cells(1, Columns.Count).End(xlToLeft).Column
```

で最終行、最終列を取得できる
最終行からたどっていくイメージ


それぞれに対し、データを連想配列に格納する。ヘッダ列を基準にカラムを決定しています

```vba
' 連想配列のキーにする列
Const HEAD_ROW_INDEX = 1

' 連想配列にする対象のデータの開始列
Const MIN_COLUMN_INDEX = 2

Private Function CreateParamsFromRow(ByVal sheet As Worksheet, ByVal rowIndex As Long) As Collection
    Dim lastColumnIndex As Long
    lastColumnIndex = sheet.Cells(HEAD_ROW_INDEX, sheet.Columns.Count).End(xlToLeft).Column

    Dim params As Collection
    Set params = New Collection

    With sheet
        Dim j As Lon
        For j = MIN_COLUMN_INDEX To lastColumnIndex
            Dim key As String
            key = NormalizedKeyString(.Cells(HEAD_ROW_INDEX, j).Value)
            ' 本来重複検査するべき
            params.Add .Cells(rowIndex, j).Value, key
        Next j
    End With
    
    Set CreateParamsFromRow = params
End Function

' キーにする際に、改行を抜く
Private Function NormalizedKeyString(ByVal s As String)
    NormalizedKeyString = Replace(Replace(s, vbCr, ""), vbLf, "")
End Function
```

本当であれば、連想配列に追加する前に`params.Contains(key)`でチェックするべきだが、MacのVBAでは使えないため諦め。

その連想配列に基づいて、マッピングする

# ワークシートをコピーしたい時

Excel VBAの関数は副作用がとても多い。操作対象がコロコロ変わるので。その副作用を消す関数を作るととても便利でした。

```vba
' ActiveWorksheetを維持したまま、ワークシートをコピー、ワークシートの参照を返す
Function CopyWorksheet(ByVal templateSheet As Variant) As Worksheet

    Dim preActivesheet As Worksheet
    Set preActivesheet = ActiveSheet
    
    Dim succeeded As Boolean
    succeeded = templateSheet.Copy(After:=Worksheets(Worksheets.Count))

    Dim newSheet As Worksheet
    Set newSheet = ActiveSheet
    preActivesheet.Activate

    Set CopyWorksheet = newSheet
End Function
```

# 拡張子を除いたファイル名を取得したい時

今あるファイルから、別のファイルに書き出したい時、名前は維持して後ろにsuffixつけるのが便利
そんな時に使えるメソッドです


```vba
'拡張子を除いたファイル名の取得
Function GetPureName(sFileName As String) As String
    Dim pureName As String
    pureName = Left(sFileName, InStrRev(sFileName, ".") - 1)
    GetPureName = pureName
End Function
```
DjangoでモデルをCSV出力するときは外部参照に注意

#経緯

モデルのバックアップを取るために以下のStack Overflowの記事を参考にしてCSV出力するようにしていたのだが、気づいたらすごい時間がかかるようになっていた。（2000件の出力に30秒以上）

http://stackoverflow.com/questions/15029666/exporting-items-from-a-model-to-csv-django-python

Google Cloud Platform上で動かしていたので、60秒以上経過するとリクエストが500エラーになり困っていた。

#原因

問題となるモデルは以下のように複数の外部参照を持つものだった。つまり、`getattr(instance, f)`でフィールドへのアクセスを行うとDB検索が行われていた。

```python
class History(models.Model):
    _from = models.ForeignKey(Profile, related_name='_from')
    _to = models.ForeignKey(Profile, related_name='_to')
    parent = models.ForeignKey(u'self', null=True)
```

#解決方法

外部参照は参照先を取ってくるのではなく、参照IDをCSVに出力するようにした。

元々のコード

```python
field_names = [f.name for f in model._meta.fields]
```

ForeignKeyはIDを出力するようにしたもの（かなりかっこわるいコード）

```python
field_names = [f.name if type(f) is not ForeignKey else f.name + '_id' for f in model._meta.fields]
```

追加のDB検索がなくなったので先のHistory 2000件でも1秒以下で処理できるようになった。
15分で便利なコマンド作った。

#便利なコマンド

世の中には、色々便利なコマンドが存在する。
多くの人が、頑張って便利機能を作ってくれている。
しかし、なぜその方々は、このコマンドの必要性に気づかなかったのだろうか？
作ってみたら超便利なのに。。。

ということで、コマンドを作った。
そのコマンドとは。。。

```
$ hiratasan
```

詳細は、
[botになる技術 YAPC::Asia Tokyo 2015](https://www.youtube.com/watch?v=u7Db9Ks2Emc)
を御覧ください。

ゴールは、
```
$hiratasan
```
と打ったら、
`#goroku` に `平田さん？` と投稿されること。

今12:46分なので、15分でチャキチャキ作っていこうと思います。



まず、slack の incoming web hook を設定します。

https://グループ名.slack.com/apps/manage/custom-integrations
の中から、`Incoming WebHooks` というのをクリックします。
そして、 `Add configuration` をクリックします。

そうすると、Post to Channel というビューが現れ、
所属するSlackグループのチャンネル一覧が現れます。

今回は、`#goroku` を選択します。
そして、Add なんちゃら というボタンをクリックします。緑色のやつですね。


ここまでで12:51。
なかなか厳しい。

出て来るWebhook URL をコピーします。
本当は画像とかを設定することもできますが、
今回は時間を短縮するために、なしにします。

変更した場合は、 Save Settings をクリックします。

ここまでで、ブラウザ作業は終了です。

次は、コンソールをクリックします。
適当に、`goroku.php`というファイルを作りましょう。

そして、この記事の中に書いてあるコードをコピペします。
http://qiita.com/hoto17296/items/621a6e16f23785a543f3

```
https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX
```
を、さっきコピーしたURL に書き換えます。

そして、
```
$message = array(
  'username' => 'Bot',
  'text' => 'fooooo!!!',
);
```

を、
```
$message = array(
  'username' => 'hiratasan',
  'text' => '平田さん？',
);
```
に書き換えます。

その後、ターミナルで
```
php goroku.php
```
と打ってみます。

そうすると、メッセージがポストされました。

めでたしめでたし。

こうなれば、後はもうかんたんです。


ホームディレクトリに戻って、
`.bash_profile`
を開きます。
そして、下の方に、
```
alias hiratasan='php goroku.php'
```

と書き、保存します。
その後、
```
source .bash_profile
```
と打ちます。

そうすると、超便利な `hiratasan`コマンドが使えるようになります！
これにて一件落着。

終了時刻は、13:04。
惜しい！

ちなみに、完成図はこんな感じ！

![hiratasan result](https://qiita-image-store.s3.amazonaws.com/0/115634/47a1eb84-e465-b0a6-fd79-94f394a2ca40.png)


また一つ、世の中を便利にしてしまった。
Xcode8でXVimを使う

# 概要
* 以前からXvimを使っていましたがXcode8にしてからうまく使えず、、一瞬はまったのでメモ

# Xvimとは
* https://github.com/XVimProject/XVim
* XcodeでVimを使うプラグイン

# Xcode8でXvimを使う
* Xcodeのバージョンが上がると毎回プラグインが消えてしまし、再度有効にする必要があります。
* 通常はこちらの手順ですぐに有効化できます。
  * [xcodeをアップデートしたらXVimとかのプラグインが動かなくなるアレ](http://wknar.hatenablog.com/entry/revive-xvim)
* ただXcode8の場合はmakeしてXcodeを起動すると**「Xcodeが壊れているため..」**と表示されて**Xcodeが起動できなくなりました。**
* ただこれは**Macを再起動することで起動できるようになります。**再起動してXcodeを開くと無事にXvimが有効になっていました。
* (自分は2回ほどXcodeのアンインストールとインストールを繰り返す無駄な時間を過ごしてしまいました。。。)

# 参考
* [開発が爆速になるSwift用Xcodeプラグインをまとめてみた](http://qiita.com/tattn/items/238b2b813be16f830bd4)
* 今回と同じ内容が上記に書かれていたので参考にさせていただきました。(内容が多かったのでXVimだけ切り出して今回の記事を立てました。)
TypeScript型定義ファイルに躓いたメモ


TypeScriptはじめました。
型定義ファイルを使うのにtypingsを入れたものの悩んだ点を大きいもの順に。

# import

インストールした定義を使う。
typingsを使うなら/path/to/typings/index.d.tsを参照すればOK。

しかし、<reference ...の記載位置にハマる。
"use strict"より先に書くのが正解。

【追記:2016/10/02】そもそもTypeScriptに"use strict"は不要でした。


```ts
// 先に<reference ...を書く
/// <reference path="../../../typings/index.d.ts" />
// パスはそれぞれ合わせて

"use strict" 

// ここに <reference ...を書いたらダメ
```

# 定義の検索とインストール

## 検索

検索するとなにかみつかる

```
$ typings search xxx
Viewing X of X

NAME    SOURCE HOMEPAGE                         DESCRIPTION VERSIONS UPDATED
xxxxx   dt     http://xxxxx/                                1        2016-XX-XX
xxxyy   dt     http://xxxyy/                                1        2016-XX-XX
......
```

## インストール

検索結果の”SOURCE"に注意する。
SOURCEがdtならdt~<名前>が指定するべき名称。

```
$ typings install dt~XXXXX --save --global
```

# 初期化

設定ファイル作成
```
$ typings init
```
typings.jsonが作成される


tsconfig.jsonの"files"にtypings/index.d.tsを追加しておく。

```json
{
    "compilerOptions": {
        ...
    },
    "files": [
        ... , 
        "typings/index.d.ts", 
        ... , 
    ]
}
```

# バージョン

この界隈の時の流れは早すぎるので念のため……

```
$ typings --version
1.3.3
```
OpenStack Days Tokyo 2016 参加レポート(社内LT用)

![OpenStack150714_.jpg](https://qiita-image-store.s3.amazonaws.com/0/78250/1a776a7c-8596-4dcd-6888-2a325823ac97.jpeg)


## 概要
↑のイベントに参加してきましたので、レポートいたします。
LT なので、すごく要約して進めます。

また、2ヶ月前のイベントのため内容齟齬はそれなにあると宣言しておきます！
詳しくは http://openstackdays.com/program/

## OpenStack とは
- 自前でパブリッククラウド・プライベートクラウドを作れるソフトウェア
- すごく誤解を恐れずに言いますと、AWS(的な仮想環境) を自社で構築・運用できる
  - パブリッククラウドとは…
      - 1つの仮想環境を、複数のユーザが共有する環境
      - AWS が主たる例。プライベートクラウドもあるのかもしれないが。。
  - プライベートクラウドとは…
      - 1つの仮想環境を、1ユーザが専有すること
      - 自社で vSphere 環境を構築して、自社のユーザのみでしか利用しない、など

![rhel-openstack-platform-3-638.jpg](https://qiita-image-store.s3.amazonaws.com/0/78250/676e53c9-58a9-e44f-6a93-43b93ac2dd25.jpeg)

## OpenStack コミュニティ
- 世界最大のオープンソース・コミュニティ
- 全世界で4万人が参加している。あの Linux Kernel の 3-4倍。
- 名だたる企業も参加
  - Intel, RedHat, Dell, VMware, etc
  - NEC, NTT Data, etc
- つまり、世界で最も開発者の多い、規模の大きいオープンソース・プロダクト

![openstack-foundation.jpg](https://qiita-image-store.s3.amazonaws.com/0/78250/31ab5e90-b543-3d50-0c04-74b3df50f93d.jpeg)

## OpenStack Days とは
- OpenStack のカンファレンスです
- Days Tokyo は日本の企業のみが出典・スピーカーとなることが特徴
- セッション内容については「これから OpenStack 導入を考えているユーザ向け」だったなーという印象です
- 一方で、OpenStack Summit というイベントもあります
- こちらは世界的なイベントで、デベロッパー・セールス 等々が世界から集結します

## OpenStack を選択する優位性
- パブリッククラウドとしての機能が豊富
  - 仮想インスタンス(仮想マシン) 簡単に作れる
  - コントロールパネル(管理UI)が充実
- フリーソフトウェアであること
  - 例えば VMware/vSphere でやろうとすると、当然ながら VMware を有償プロダクトである
- オープンソースであること
  - 自由に改修・改版できる
  - 例えば VMware/vSphere でやろうとすると、プロプライエタリなソフトウェアであるため、ユーザ独自な改修は基本的に不可である
  - その点、OpenStack はユーザ独自にカスタムできる
  - コミュニティ活動が活発であるため、早いペースで最新機能を利用できる

## OpenStack を利用する上での課題
- コミュニティが活発であるが故に、バージョンアップの頻度が高い
  - すべて追従するとなると、検証にある程度 時間を費やすことになる
- オープンソースであること
  - 通常 有償サポートが無い
  - トラブルが起こった場合、自前で解決が基本となる
  - つまりは、OpenStack を扱う技術力が必要となる
  - 体力がある企業でないと、、、 という話もありました

## では実際に、OpenStack はどう使われている?
- 基本は、自前でクラウド環境つくりたい場合
  - 自前で IaaS(パブリック・プライベート) 作りたい
  - 自前で Paas 作りたい
- ドコモ
  - モバイル通信の基盤として NFV を使っている
    - NFV とは、NW機器を仮想化していきましょう、のオープンな仕様(すごくザックリ言うと。。)
  - その NFV の基盤として、OpenStack を採用
  - OpenStack を基盤に採用することで、高価な専用ハードが必要しなくなった
  - 低コストな汎用ハードで実装できるようになった
- JFEスチール
  - 製鉄所システム という全社の業務管理システムの基盤に、OpenStack を採用
  - これまでハード・ソフト ともにベンダロックインしていた
  - OpenStack に移行したことで、様々なベンダハードの上で実装できるようになった
  - また VMware/vSphere との連携も行っており、マルチクラウドとしても対応している
- CTC
  - SI で OpenStack を使っている
  - つまり顧客ユーザへITインフラの提供として、OpenStack を提案・提供(設計・構築)している
- IBM
  - OpenStack の有償サポートをサービス化している
  - OpenStack を使いたいが、オープンソースなので不安…というユーザ企業をターゲットにしている
- NEC
  - NEC のパブリッククラウドサービス「NEC Cloud IaaS」の基盤として OpenStack を採用している
  - つまり、クラウドサービス化の土台として OpenStack を選択した
  - OpenStack の機能如何で自社のクラウドサービスの品質が左右してくるため、積極的に OpenStack コミュニティへ参加もしている

## まとめ
- 自前でクラウド作る場合の選択肢として OpenStack
- ただし、OpenStack を担ぎ上げて自社でサービス展開する場合、ある程度の技術力が必要となる
- コミュニティが活発なため、新機能の取り込みが早い
- 今後 世界標準のクラウドソフトウェアになっていく可能性大

## 最後に
ならば GLODIA は OpenStack とどう関わっていくか。
まずは…自社のプライベートクラウドを、OpenStack に移行する動きを活発にすることを考えてます。

以上。
CentOS7(x64)サーバ構築手順まとめ

前提：OSのインストールが完了していること。インターネットに接続されていること。

補足：カゴヤVPSのような最小構成インストールの場合は、最初に下記を実行しておく。

    yum groupinstall Base
    yum groupinstall Development Tools
    yum install firewalld
    systemctl status firewalld
    systemctl start firewalld
    firewall-cmd --permanent --add-service=http
    firewall-cmd --permanent --add-service=https
    firewall-cmd --permanent --add-port=21/tcp
    firewall-cmd --reload
    systemctl restart firewalld

rootでSSH接続できるようにする。
接続用IPアドレスの確認は、下記コマンドで確認できる。

    ip a



rootのパスワードを変更する。

    passwd

LAMP環境の立ち上げ。
以下を実行し、Apache, MySQL, PHP が動作することを確認する。
http://qiita.com/kenichiro-yamato/items/763f607052a9ac218b93

Gitを設定する。
あらかじめgitHubにリポジトリを作成しておき、cloneできる状態にしておく。
cloneするためにはSSH接続の公開鍵が必要になるので、作成する。
http://qiita.com/kenichiro-yamato/items/5d51393d951551e54445

ララベルをインストールする。
http://qiita.com/kenichiro-yamato/items/1f8e2c80c8067fc51f56

httpd.confを編集して、DocumentRootをLaravel/publicのパスに合わせる。
http://qiita.com/kenichiro-yamato/items/200617d9f6f688291c10

開発環境の場合、Laravelのコーディングはsambaを使うと便利である。
http://qiita.com/kenichiro-yamato/items/9ace3951c46dc2507562    

phpMyAdminをインストールする。
http://qiita.com/kenichiro-yamato/items/1a8efbfd738b85369e46

必要に応じて、MySQLのユーザを作成する。
http://qiita.com/kenichiro-yamato/items/cdf8926e9681fdb9c2a1

本番サーバの場合、SSLを設定する。
http://qiita.com/kenichiro-yamato/items/c7632499852abf67efaa

FTPを使えるようにする。

    yum -y install vsftpd
    systemctl start vsftpd

PHPからshellをroot権限で実行するために必要な設定。
http://qiita.com/kenichiro-yamato/items/3f04ca176f51473d240f

Linuxのユーザを作成する。user01にパスワード0000を付与する場合は
下記のシェルを作成して実行する。

    test.sh
    #!/bin/sh
    useradd user01
    echo 0000 | passwd --stdin user01

このユーザでFTP接続できることを確認する。
なお、そのままでは上位ディレクトリまでアクセスできてしまうため
セキュリティを考慮し、自分の名前のディレクトリしか
FTPでアクセスできないように、下記の設定をする。
http://qiita.com/kenichiro-yamato/items/08aa845b61804373d739
この設定をした後で、再度、FTP接続して、
user01が/home/user01にしかアクセスできないことを確認する。

ユーザごとのディスク使用量を制限する（FTPでアップできる容量を制限する）
http://qiita.com/kenichiro-yamato/items/604af37013da638489d2

SSH接続できるクライアントをIPアドレスで制限する。
http://qiita.com/kenichiro-yamato/items/1b95bf701f453cdec946
【AWS EC2 エラー】ssh port 22 Operation timed out

# 2022年4月17日追記

[Amazon Web Services 基礎からのネットワーク&サーバー構築](https://www.amazon.co.jp/dp/4822262960)を読み、こちらの設定について改めて学び直しました。
SSH接続を可能にするために、SSHの送信元として設定できるのは以下のいずれかのようです。
- カスタム 0.0.0.0/0 ※ 非推奨
- カスタム インスタンスを管理するパソコンのIPアドレス（おそらく[ここ](https://www.cman.jp/network/support/go_access.cgi)で見れるIPアドレス）
- マイ IP

AWS上の仮想サーバーであるEC2に、リモートログイン（SSH接続）をする際にどこから接続するか、が「送信元」に当たります。

「送信元」を「0.0.0.0/0」とした時、「どこからでも接続できてしまう」という意味になってしまうため、悪意ある第三者が不正な侵入を試みる恐れがあるようです。（※この本では「0.0.0.0/0」として設定していることもあり、商用ではなく実験用であればこの設定でもよいと思います。）
「インスタンスを管理するパソコンのIPアドレス（SSH接続を行うのに使うパソコンのこと）」、あるいは、「マイ IP」を選択するのがより安全とのことです。

「インスタンスを管理するパソコンのIPアドレス」や「マイ IP」を選んだ場合の注意点として、プロバイダーに再接続するたびにIPアドレスが変わる可能性があるため、接続できなくなったときは毎回、AWSマネジメントコンソールで、セキュリティグループの設定を開き、SSHの送信先で設定されているIPアドレスを更新する必要があるそうです。

# こうやって解決した
① セキュリティグループのインバウンドで、sshの送信元を **自分のパソコンのIPアドレス** (←重要)に設定する必要がある。

ここで"カスタム"や"任意の場所"ではなく、"マイIP"を選ばないとダメだった。
![Screen Shot 2016-09-15 at 7.52.54 PM.png](https://qiita-image-store.s3.amazonaws.com/0/54467/42ad234c-d30c-8a33-a73f-2d0de3521051.png)

② その後インスタンス上で右クリック、インスタンスの状態->停止。そして開始。(再起動ではダメなことがあるらしい。)

![Screen Shot 2016-09-15 at 8.01.30 PM.png](https://qiita-image-store.s3.amazonaws.com/0/54467/eb1b5973-f8a0-6b39-31c2-9555cbcbb3f7.png)


## 参考
・http://noshipu.hateblo.jp/entry/2014/09/16/214248
・http://www.studio-fix.com/blog/kaoru/2009/05/17/post175/

# AWS Amazon EC2公式を見ると・・・
## [インスタンスへの接続に関するトラブルシューティング](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html)

セキュリティグループルールを調べます。 **適切なポートのパブリック IP アドレス**(←自分のPCのIPアドレスのこと) からのインバウンドトラフィックがセキュリティグループルールで許可されている必要があります。

1. https://console.aws.amazon.com/ec2/ にある Amazon EC2 コンソールを開きます。
2. 画面左の[インスタンス] を選択し、インスタンスを選択します。
3. 画面下の[説明] タブで、[セキュリティグループ] にある [ルールの表示] を選択して、有効なルールのリストを表示します。
4. Linux インスタンスの場合: **ご使用のコンピュータから** ポート 22（SSH）へのトラフィックを許可するルールがあることを確認します。

カタカナ多すぎ&日本語・・・

# 前提設定の確認
## チェックリスト

1. **VPC**が作成されているか？
2. **サブネット**が作成され、1で作成したVPCを選択しているか？
3. **インターネットゲートウェイ**が作成され、1で作成したVPCにアタッチしているか？
4. **ルートテーブル**が作成されているか？
5. 4の **ルート** が、*送信先*「0.0.0.0/0（IPv4の場合）」、*ターゲット*「igw-hoge123fuga（3で作成したインターネットゲートウェイのID）」になっているか？
6. 4の **サブネットの関連付け** が、2で作成したサブネットになっているか？

上記がEC2でサーバーを構築するのに最低限必要なVPC領域の作成となります。このチェックリストを基に作成したVPCを選択し、インスタンスを作成するようにしてください。

### 用語集

- VPC(Virtual Private Cloud): クラウド上のプライベートなネットワーク空間。
- サブネット: 分割されたVPCの領域。
- インターネットゲートウェイ: VPCのサブネットを、インターネットに接続する出入り口。
- ルートテーブル: サブネットとインターネットゲートウェイの間のルーター。
    - 設定1: VPC領域のCIDRブロックである「10.0.0.0/16」に含まれるIPアドレス宛のパケットであれば、VPC領域のルーターに接続されている相手への通信なので、VPC領域のルーター(つまり自分のローカル)にパケットを転送する。
    - 設定2: 0.0.0.0/0の範囲宛(全てのIPアドレス宛)のパケットはインターネットゲートウェイに転送する。※ これがないと、サブネットをインターネットに接続できない。


### 参考リンク

+ [AWS VPCによるネットワーク構築とEC2によるサーバー構築](https://qiita.com/shizuma/items/396ad15ff574717dfa1d)
+ [知識0から、AWSのEC2でウェブサーバーを構築するまで](https://qiita.com/shunsuke227ono/items/23dbf4f3bc663a2875f0)
withRouterでラップされたReactコンポーネントをenzymeでテストしたい

# 概要

通常のシンプルなStateless Functional Componentsの場合、[Shallow Rendering](http://airbnb.io/enzyme/docs/api/shallow.html)﻿で大丈夫だが、
[react-router](https://github.com/ReactTraining/react-router)の`withRouter()`でラップしていると、正しくレンダリングがされない問題があった。

```js
import React from 'react';
import {withRouter} from 'react-router';

export default withRouter(class TestComponent extends React.Component {
  ...
}
```

# 解決法

[Full DOM Rendering](http://airbnb.io/enzyme/docs/api/mount.html)をすることでテストが無事通りました。

```*.spec.js
import assert from 'power-assert';
import {mount} from 'enzyme';

...

describe('TestComponent', () => {
    it('.button', () => {
        const testComponent = mount(<TestComponent />);
        assert.equal(testComponent.find('.button').length, 1);
    });
});
```

```setup.js
require('babel-register')();

import {jsdom} from 'jsdom';

const exposedProperties = ['window', 'navigator', 'document'];

global.document = jsdom('');
global.window = document.defaultView;
Object.keys(document.defaultView).forEach(property => {
    if (typeof global[property] === 'undefined') {
        exposedProperties.push(property);
        global[property] = document.defaultView[property];
    }
});

global.navigator = {
    userAgent: 'node.js'
};
```

```package.json
"test": "mocha --require ./test/setup.js --compilers js:babel-register"
```

## Material-UIを使っている場合

Material-UIコンポーネントを使っている場合、以下のようなエラーが出ることがありました。

```
Warning: Failed context type: Required context `muiTheme` was not specified in `FlatButton`.
```

[Material-UI#v0.15.0](http://qiita.com/usagi-f/items/24418c50faa6a5931ba8)
テーマファイルの指定が必須になっているので、そこでコケているようです。

なので、こうする。

```*.spec.js
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';

...

const testComponent = mount(<MuiThemeProvider><TestComponent /></MuiThemeProvider>);
```

# 未解決問題

イベント発火のテストがうまくいってません。

Full DOM Rendering時に`.simulate()`がうまく動いてくれていない…？
findDOMNodeで、`TestUtils.Simulate`という代替案？も載っていたのですが、まだうまいこと動かせていません。

以下それっぽいissue（英語力が足りない）
https://github.com/airbnb/enzyme/issues/99
https://github.com/callemall/material-ui/issues/4200


## 参考
[enzyme+mocha+power-assertでReactコンポーネントのフルレンダリングテスト](https://blog.wadackel.me/2016/react-enzyme-mocha-power-assert/)
Github projectsとZenhub boardの機能と思想の比較

# Github projectsについての概要

- http://qiita.com/Yamotty/items/95bcd4743ab10da89db5 をご一読下さい

# カンバンとしての機能比較

Github projectとZenhub boardのカンバン機能比較

|  比較項目 | projects | board |
|  ------ | ------ | ------ |
|  価格（5名以上の場合） | 無料 | 月5ドル〜 |
|  工数見積 | ☓ | ◯ |
|  multi repository | ☓ | ◯ |
|  カンバン内でのissue/PR編集 | ☓ | ◯ |
|  Epic（テーマ）作成 | ☓ | ◯ |
|  note作成 | ◯ | ☓ |
|  issue close時のcardの自動移動 | ☓ | ◯ |
|  issueへの複数アサイン | ☓ | ◯ |
|  フィルタ機能 | ☓ | ◯ |

シンプルに機能だけを比較すると、zenhubが有料なだけに高機能で使いやすいイメージが有るが、両者は思想・ユースケースの異なるプロダクトだと思われる。

# 本質的な思想の違い

## Github projects

- projectは**「特定のテーマを進めるためのカンバン」**
- 必要なissueを取り出して進捗管理する
- 各projectは使い捨てであり作っては解散するもの。

## Zenhub board

- boardは**「repoを一つの大きなプロジェクトとみなした際のカンバン」**である。
- repoにある全てのissueをboardで管理する。issueはタスクに近い位置づけ。
- タスクの性質をわかりやすくするために、epicというテーマグルーピングがある

# 自チームの開発フローにフィットするのはどちらか？

- 両方ともに今後さらなる機能追加は期待できるだろうが、それ以前に上記の思想の違いがあるため、自チームのGithubの使い方、ひいては開発フローを俯瞰した上でどちらがフィットするのかを考える必要がある。
- 場合によっては共存することもあるかな、と考えている。
ImageMagick と GNU Parallel を使って異なるサイズのダミー画像100枚を1分で用意する

# 前提
* 「（異なるサイズの大量の）ダミー画像を用意して〜」と言われた
* Macを使っている
* homebrewを使っている

# 状況

* Aさん「テストするから、このサイズと、このサイズと..違う大きさのダミー画像100枚用意して〜。全部pngでね!」
* Bさん「わかりました。でもフォトショとか入れてないっす」
* Aさん「じゃあ、ググって画像生成するウェブサービス探して。」
* Bさん「わかりました。。」

# 対処概要

* 画像を自動生成します

1. homebrew で ImageMagick を入れます
2. homebrew で GNU Parallel を入れます
3. サイズリストを用意します（改行区切り）
4. コマンド実行します

# 手順
1. homebrew で ImageMagick を入れます

```
brew install imagemagick
```

2. homebrew で GNU Parallel を入れます

```
brew install parallel
```

3. 異なるサイズが改行区切りで書かれたファイルを用意します

```text:size_list.txt
100x100
200x100
300x100
400x100
100x200
100x200
100x300
1000x500
.
.
.
888x888
999x999
```

4. GNU Parallel と ImageMagick を組み合わせたコマンド実行します

```
parallel convert -size {} xc:yellow -pointsize 20 -draw \"text 0,20 \'{}\'\" {}.png < size_list.txt
```

出来上がりです。

```
ls

1000x500.png  100x100.png   100x200.png   100x300.png   200x100.png   300x100.png   400x100.png   ......   888x888.png   999x999.png
```

このようにダミーの画像100枚を1分で用意できました。
サンプルとしまして 200x100.png は以下のような感じになります。

![200x100.png](https://qiita-image-store.s3.amazonaws.com/0/109299/baaa8091-da1c-3f4e-4ab5-b8c5fcd9b677.png)

# 補足
ImageMagickの使い方はこちらを参考にしました
http://www.imagemagick.org/script/convert.php

GNU Parallelの使い方はこちらを参考にしました
http://bicycle1885.hatenablog.com/entry/2014/08/10/143612
[iOS10] Safari10.0 でviewportの挙動が変わったので検証してみた

詳しい仕様変更は[Safari 10.0 - Developer - Apple](https://developer.apple.com/library/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_10_0.html)を閲覧してください。

ここではviewportの検証を行います。

検証端末：iPhone 6 plus

※user-scalable=noは効かなくなったようです。
参考：[disable viewport zooming iOS 10 safari?](http://stackoverflow.com/questions/37808180/disable-viewport-zooming-ios-10-safari)

## パターン1

``` html
<meta name="viewport" content="width=320">
```

- window.innerWidth = 320
- htmlのwidth = 320

## パターン2

``` html
<meta name="viewport" content="width=320, maximum-scale=1">
```

- window.innerWidth = 414
- htmlのwidth = 320

？？？
viewportは414のままでなぜかhtmlだけが320になります。
つまり画面右側に余白がでます。

## パターン3

``` html
<meta name="viewport" content="width=320, initial-scale=1">
```

- window.innerWidth = 414
- htmlのwidth = 414

widthは無視されます。

## パターン4

``` html
<meta name="viewport" content="width=320, initial-scale=2">
```

- window.innerWidth = 320
- htmlのwidth = 320

？？？

initial-scaleが無視されている。

## パターン5

``` html
<meta name="viewport" content="initial-scale=2">
```

- window.innerWidth = 207
- htmlのwidth = 207

scaleが効いている。

## パターン6

``` html
<meta name="viewport" content="width=device-width">
```

- window.innerWidth = 414
- htmlのwidth = 414

## パターン7

``` html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

- window.innerWidth = 414
- htmlのwidth = 414


## パターン8

``` html
<meta name="viewport" content="width=device-width, initial-scale=2">
```

- window.innerWidth = 414
- htmlのwidth = 414

initial-scaleが無視されている。

## まとめ

`maximum-scale=1`を入れている場合は注意が必要です。
今回の検証から見るに、`maximum-scale`はscale 1=device-widthと設定されるが、
viewportにwidthを指定するとそれはhtmlにしか効かない挙動になります。
つまりwidth:320と指定した場合はscaleが「414/320」にならないと横幅いっぱいにならないようです。

また、`maximum-scale`と`minimum-scale`を指定してもピンチの制御は行えず、
`user-scalable=no`も効かなくなったので、`maximum-scale`と`minimum-scale`は使わないほうがよさそうです。
GoogleChromeのユーザーエージェントを変更して、スマホサイトを確認する：2016年9月

**今まで、`Emulation`というタブからユーザーエージェントを変更できましたが、`Network conditions`に変わったようです。**

---

１．`F12`キーを押して、デベロッパーツールを表示
　　`Network conditions`のタブがなければ、点点点をクリックして表示

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/42231/6e771901-75f2-e29b-d4c8-74c127be673a.jpeg)

２．デフォルトで User agent の `Select automatically` にチェックが入っているので、チェックを外せば、下にあるユーザーエージェントの変更が可能です。

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/42231/593880c3-c903-a3b1-fce4-8437ae153ab9.jpeg)
GKE Kubernetes ラベルを使ったフィルタリング

Kubernetesではリソースに対してラベルを付与することによりselectorやフィルタリングに利用することができる。
ラベルは以下のようにKey,Valueでオブジェクト(Pod,Replication Controllerなど）にアタッチする。

```
"labels": {
  "key1" : "value1",
  "key2" : "value2"
}
```

ラベルの例として、以下のようなものが公式ページに記載されている。リリースや環境などを区別するために用いることを想定されているようである。

```
"release" : "stable", "release" : "canary"
"environment" : "dev", "environment" : "qa", "environment" : "production"
"tier" : "frontend", "tier" : "backend", "tier" : "cache"
"partition" : "customerA", "partition" : "customerB"
"track" : "daily", "track" : "weekly"
```

ラベルは Label Selector を利用して特定の Pod を判別するために利用される。

### ラベルのアタッチ
マニフェストで定義する。
既に環境作ってたので既存のDeployment、Podに対してラベルを追加する。

```
$ kubectl get --show-labels=true deployments
NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       LABELS
gcp-cost                1         1         1            1           15d       name=gcp-cost-pods
task-processing-time    1         1         1            1           7d        name=task-processing-time-pods

$ kubectl edit  deployments/gcp-cost
```
以下のラベルを追加。

```
environment: dev
```
※task-processingにはenvironment:qaを追加。

deploymentにラベルが追加されていることを確認

```
$ kubectl get --show-labels=true deployments
gcp-cost                1         1         1            1           15d       environment=dev,name=gcp-cost-pods
task-processing-time    1         1         1            1           7d        environment=qa,name=task-processing-time-pods
```

注） templateのラベルを変更すると、既存のPodを落とし、新しいPod(ラベル付き）が作成されることを確認。

```
$ kubectl get --show-labels=true pods
gcp-cost-1823646609-u7s4z                1/1       Terminating   0          5m        name=gcp-cost-pods,pod-template-hash=1823646609
gcp-cost-3407718879-zrso2                1/1       Running       0          2s        environment=dev,name=gcp-cost-pods,pod-template-hash=3407718879
```

- environmentがdevと一致するpodのみ、一覧を出力する。

```
$ kubectl get pods -l "environment=dev"
NAME                        READY     STATUS    RESTARTS   AGE
gcp-cost-3407718879-zrso2   1/1       Running   0          7m
```

- environmentがdevと一致しないpodのみ、一覧を出力する。

```
$ kubectl get pods -l "environment!=dev"
NAME                                     READY     STATUS    RESTARTS   AGE
task-processing-time-1436137422-8fwba    1/1       Running   0          2m
```

- environmentがdevとqaのpod一覧を出力する。

```
$ kubectl get pods -l "environment in (dev,qa)"
NAME                                    READY     STATUS    RESTARTS   AGE
gcp-cost-3407718879-zrso2               1/1       Running   0          23m
task-processing-time-1436137422-8fwba   1/1       Running   0          3m
```

getだけではなくdeleteなどと組み合わせることが可能。environmentがdevのpodを全て削除するなど。
Azureの課金が一定額になったらアラートを飛ばす方法について

## 初めに
Azureは、通常では、使ったら使っただけ課金される従量課金制のサービスです。
よくある月額制のVPSなどでは、一か月に一度決まった利用料を支払えば他に気にする必要はありません。
それと比べるとAzureの場合はある程度使用した金額の監視出来たほうが精神衛生上良いと思われます。
ということで今回は、Azureの課金額を監視するためのサービスであるBilling Alertを紹介します。

## 注意
Billing Alertは、2016年9月16日現在プレビューのサービスになります。
そのため、SLAの担保やサポートが受けられないなどあるので使用する際はその点にご注意ください。

## プレビュー機能を有効にする
Billing Alertは、現在プレビューの機能です。
そのため、まず初めに機能を有効化します。
下記のURLにアクセスします。
https://account.windowsazure.com/PreviewFeatures
このURLは、現在使用を申請できるプレビュー機能が一覧で表示されるのでBilling Alertを選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/91f80682-511d-664c-9c8a-3b2042ec7968.png)

try it nowを選択すると下記のような画面が表示されるのでサブスクリプションを選択してチェックを選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/f42d182f-c0e5-fc8c-3e25-9ab3ee26b347.png)

これで少し待つとWelcomeメールが届くはずです。
それで機能が有効化は完了です。

## 監視設定をする
サービスが有効化出来たので早速監視設定をしてみましょう。
監視設定は、下記のURLから行います。
https://account.windowsazure.com/Subscriptions
URLにアクセスすると、下記のように所有しているサブスクリプションの一覧が表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/45d6599d-28b6-0dd9-b9ad-78ff6a32faa5.png)

表示されているサブスクリプションの中から、監視したいサブスクリプションを選択します。
サブスクリプションを選択すると、課金の詳細を表示するページに移動します。
そのページの上部にあるアラートの項目を選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/14abe1ea-569e-355c-8e1d-9c13582ce00a.png)

アラート画面にいどうすると、下記のような画面になります。
この画面のアラートの追加の項目を選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/0328d36e-11e7-5164-c09b-53ead0648175.png)

アラートの追加を選択すると、下記のような画面になるのでアラート対象とアラートメールの受信者を指定して保存を選択します。
アラート対象は、
* 請求合計
* 通貨クレジット
の二つになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/89295cb5-74db-00c8-e2b2-77842c4e826a.png)

下記のような画面になったら追加完了です。
これで、課金やクレジットの残りに応じてアラートメールが送られるようになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/6e1f70c4-e0ac-8977-998e-8adeb90bed2d.png)

## まとめ
この機能によって、Azureの課金監視ができるようになるので万が一ASEを止め忘れてものすごい量の課金請求が来るといったことを未然に防げるかもしれません。
インスタンスの消し忘れなどにも気づきやすく非常に便利なのでぜひこのサービスを使ってみてください。
Macでショートカットの作成

#MacでWindowsの「ショートカット」のようなものを使いたい
MacのWindowsのショートカットのような機能としてエイリアスがある。
##エイリアスの作成方法備忘録
Macでエイリアスを作成する方法のメモ
1. ファインダーでファイルやフォルダを選択してメニューバーのファイル＞エイリアスを作成
2. ファイルやフォルダを選択して「Command」＋「L」
3. 「Command」+「Option」を押しながらファイルやフォルダをD&D
4.  ターミナル上でコマンドにより作成
`$ alias エイリアス名='パスorコマンド名'`
Wordpress リライトルール


通常のパーマリンク設定では実現しない時に、このアドレスでアクセスした時に、このURLにアクセスするというようなリライト設定をする。


# 通常のリライト
こちらの場合管理画面上のパーマリンクの設定で保存をし直す必要がある

```functions.php
add_rewrite_rule('posttype/([^/]+)/([^/]+)/?$', 'index.php?category_name=$matches[1]', 'top');
```

# rewrite_rules_arrayで設定
複数のリダイレクト設定をする場合はこっちのが手っ取り早いかも
管理画面でのパーマリンク設定で保存をする必要はない。

```functions.php
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');

// ルールを追加するときはflush_rules()を忘れないように
function flushRules(){
	global $wp_rewrite;
   	$wp_rewrite->flush_rules();
}

// 新しいルールを追加
function wp_insertMyRewriteRules($rules)
{
	$newrules = array();
	$newrules['(project)/([^/]+)/?$'] = 'index.php?post_type=project&project_categoy=$matches[1]';
	return $newrules + $rules;
}

// 変数idを追加して、WordPressが認識できるようにする
function wp_insertMyRewriteQueryVars($vars)
{
    array_push($vars, 'id');
    return $vars;
}
```

下記の設定は特に変える必要はないみたい。

```functions.php
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');
```

下記の関数にルールを記述するとよいらしい。

```functions.php
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
```

リライトのルールの設定は基本的には正規表現を利用してリライトを指せる
() -> $matches[n] で引っ張れるのでまんま正規表現的に飛ばせる。

```functions.php
// 編集するのはこの部分
$newrules['(project)/([^/]+)/?$'] = 'index.php?post_type=project&project_categoy=$matches[1]';

// 条件を増やしたいときはそのまま増やす。
$newrules['(project)/([^/]+)/?$'] = 'index.php?post_type=project&project_categoy=$matches[1]';
$newrules['(company)/([^/]+)/?$'] = 'index.php?post_type= company& company_categoy=$matches[1]';

// 配列でやっているので連想配列的に書くのもOK
$newrules　= array(
  '(project)/([^/]+)/?$' => 'index.php?post_type=project&project_categoy=$matches[1]',
  '(company)/([^/]+)/?$' => 'index.php?post_type=company&company_categoy=$matches[1]',
);
```


# まとめ

wordpressで思った通りのPathにならなかった場合はこういうふうにでも一応Pathを通すことができる
できる限りは、defaultでやったほうが、今後のカスタマイズ性能上がるのだろうけどもね。
Animatorのパラメタ関連処理をラップする

アニメーターのパラメタ管理をするときに毎回同じようなコードを書いていたことに気づく...

Hashを保存したり、Animator.SetIntやGetIntしたり...

ということで以下のクラスを作ってみました。
HashIdのキャッシュやAnimatorのSetとGet処理を隠蔽しています
サポートしている型はAnimatorの仕様に従い、int float boolのみ



```csharp
using System;
using UnityEngine;

/// <summary>
/// アニメーターのパラメタ
/// </summary>
public class AnimatorParam<T> where T : struct
{
    /// <summary>パラメタ名</summary>
    public string ParamName { get; set; }

    /// <summary>値. Setterで自動的にAnimatorパラメタが更新されます.</summary>
    public T Value
    {
        get { return (T)_value; }
        set { _value = value; }
    }

    /// <summary>パラメタのHash値.</summary>
    public int HashId
    {
        get
        {
            if (!_hashId.HasValue)
            {
                _hashId = Animator.StringToHash(ParamName);
            }
            return _hashId.Value;
        }
    }

    private object _value
    {
        get
        {
            if (typeof(T) == typeof(int)) return _animator.GetInteger(HashId);
            if (typeof(T) == typeof(float)) return _animator.GetFloat(HashId);
            if (typeof(T) == typeof(bool)) return _animator.GetBool(HashId);
            throw new NotSupportedException("Animator Param not support " + typeof(T).Name);
        }

        set
        {
            if (value is int) _animator.SetInteger(HashId, (int)value);
            else if (value is float) _animator.SetFloat(HashId, (float)value);
            else if (value is bool) _animator.SetBool(HashId, (bool)value);
            else throw new NotSupportedException("Animator Param not support " + typeof(T).Name);
        }
    }

    private int? _hashId;
    private Animator _animator;

    public AnimatorParam(Animator animator, string paramName)
    {
        ParamName = paramName;
        _hashId = Animator.StringToHash(ParamName);
        _animator = animator;
    }

    public AnimatorParam(Animator animator, string paramName, T initialValue)
    {
        ParamName = paramName;
        _hashId = Animator.StringToHash(ParamName);
        _animator = animator;
        Value = initialValue;
    }
}

```
再学 Javascript 的闭包 closure


闭包就是指那些能够自由(独立)访问变量的函数.

```js
function init() {
  var name = "Mozilla"; // ① local variable in init
  function displayName() { //② it's a inner function, we call closure
    alert(name);// ③ use parent function variable
  }
  displayName();
}
init();
```

再看一个变种:

```js
function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

```

上面的代码执行结果完全一样, 写法区别就是 **父函数** 直接返回这个内部函数.
这个时候我们把 **myFunc** 就叫做 `闭包`, 它是一种特殊现象.有2部分组成, 函数和创建该函数的`环境`. 而所谓环境,就是在创建这个闭包时候的任何变量组成. 

在上面的例子中, **myFunc** 是一个闭包, 它是由 **displayName 函数** 和闭包创建时的 **Mozilla**字符串组成.

我们再来看看下面这个例子:

```js
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
//相当于
// function _(){
//   var x = 5
//   function(y){
//     return x + y
//   }
// }
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12
```

上面的`add5`和` add10`都是闭包, 他们共享系统的函数定义. 但是保存了不同的 **环境**.
本质上, `makeAdder` 是一个 **函数工厂** -- 创建将指定的值和它的参数求和的函数.

**上面的示例中创建了2个新的函数, 一个是将其参数和5求和, 一个是和10求和.**

上面是 **闭包** 的定义. 接着我们看看到底什么地方能用他, 有什么用.

闭包允许将函数与其操作的相关数据(环境)关联起来.  --> 面向对象即视感?
在面向对象编程中, 对象允许我们将某些数据(对象的属性)于一个或者多个方法关联.

所以, 一般来说, 可以使用只有一个方法的对象的地方, 都可以使用闭包.

在 web 开发,我们经常会遇到这样的情况,就是 DOM 的事件驱动, 我们会定义一系列的行为,然后将它绑定到某个 DOM 对象上.通常称为 **回调**, 也就是为了响应事件而执行的函数. 看看下面的这个例子:

先定义一些样式:

```css
body {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}
h2 {
  font-size: 1.2em;
}

```

接着我们为了修改 body 的 font size, 由于我们给其他的元素使用了相对大小的单位,所以其他元素也会调整.

```js
function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

```

这里, size12, size14, size16都是对象的函数将调整文字的大小. 作为回调我们将他们绑定到 dom 元素上.

```js
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
```

dom:

```
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>
```

模拟私有变量
MacのSQL*Plusで方向キーを有効にする

#MacのSQL*Plusで方向キーを有効にする方法

Macのoracle clientでSQL*Plusをインストールしたあと、方向キーを有効にするには
rlwrapをインストールする必要があるらしい。

##rlwrapをインストール

brewでrlwrapをインストール
`$ brew install rlwrap`

SQL*Plus起動時にrlwrap上で起動させるためにエイリアスを設定
`$ alias sqlplus='rlwrap -pRed sqlplus'`

エイリアスを毎回設定するのは面倒なので.bashrcに追加する
`$ cd ~`
`$ vim .bashrc`
上記aliasコマンドを追記し保存

.bash_profileから.bashrcを読み込ませる
`$ vim .bash_profile`
下記コマンドを追記し保存
`source ~/.bashrc`

.bash_profileを読み込ませて変更の反映
`$ source ~/.bash_profile`

完了