OmniAICreator/Qiita-1.07M huggingface dataset:
scoped enumで配列のindexを指定する

C++03においてEnumでIndexを指定したい場合、リンク先のような方法で良さそうです。
http://d.hatena.ne.jp/Horiuchi_H/20100806/1281090492

c++11ではscoped enumがあるので結構違います。
あとは、range-based forとstd::arrayが便利。

c++03からの改善点は
● for文が楽に
● enumの列挙子名のスコープが狭くなり、列挙子名が重複しにくくなる
● 要素数をテンプレート引数から消せる

現状の問題点としては
● 列挙子に初期化子を指定すると大体バグる
● IndexEnum::SIZEをindexに与えるとバグる(エラー処理書けばいいけど、端折ってます)
● SIZEが列挙子にない場合コンパイルが通らない
● SIZEが最後以外にあるとバグる
● SIZE派、Size派、Count派云々で、争いが起こる
● unscoped enumでもscoped enumでも使える
そんなに深刻な問題は無さそうではあるが、気になる

c++XXでは
● 列挙子に初期化子を指定出来ないenum
● 列挙型の要素数を取得するなんらかの方法
この辺りが出来ると嬉しいかも。
constexperとかテンプレートテクニックでなんとかなりませんかね(適当)

あとinitializer_list<T>を引数にしてArrayを初期化するのは良くわからなかったので、パスしてます。

**追記**
　そもそもinitializer_listでの初期化は、Enumの列挙子を並び替えたり、列挙子を減らすとバグる原因になるので実装しないで良いですね。
　コンパイラによっては(というかMSVCでは)autoに対応してないので、コンパイルが通らないっぽい。
その場合beginとendの戻り値の型を明示的に書けばよいです。

**さらに追記**
　関数の戻り値による型推論はC++1yからなので、記事のタグが怪しい感じですね。

```cpp
#include <iostream>
#include <array>

template<typename T, typename Enum>
class EnumArray
{
public:
	EnumArray(){}

    EnumArray(T init)
    {
        Array.fill(init);
    }

	~EnumArray(){}

	size_t size() const { return Array.size(); }
	const T& operator[](const Enum& index) const { return Array[(int)index]; }
	T& operator[](const Enum& index) { return Array[(int)index]; }

    auto begin() const
    {
        return Array.begin();
    }
    
    auto end() const
    {
        return Array.end();
    }

    auto begin()
    {
        return Array.begin();
    }
    
    auto end()
    {
        return Array.end();
    }
    

private:
    std::array<T,(int)Enum::SIZE> Array;
};

enum class IndexEnum
{
	A, B, C, D,
    SIZE
};

int main(int, char**)
{
    EnumArray<int,IndexEnum> intArray(0);
	intArray[IndexEnum::A] = 1;
	intArray[IndexEnum::C] = 3;
    
    for( auto it:intArray)
    {
        std::cout << it << std::endl;
    }
    
	return 0;
}
```
Scalaのlazy valが素晴らしい


たとえば、外部のURLにリクエストするような関数では、

```scala
def getJSON = {
	println("requesting...")
	val result = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
	println("request done")
	result
}

println(getJSON)
println(getJSON)
println(getJSON)
```

その関数を呼ぶたびにHTTPリクエストが発生していまう。

```
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
```

これを `def` から `lazy val` にすると

```scala
lazy val getJSON = {
	println("requesting...")
	val result = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
	println("request done")
	result
}

println(getJSON)
println(getJSON)
println(getJSON)
```

HTTPリクエストは1回だけになる

```
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
```

ちなみに、先のScalaコードから println を取り除けば1行になる。

```scala
lazy val getJSON = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
```


PHPのプロジェクトをScalaで書きなおしているが、PHPで書こうとすると static で変数を宣言して、値が NULL かどうかを判定するようなコードになるので、Scalaのlazy valはすばらしいと思った。

```php
<?php

function getJSON() {
	static $result;
	
	if ($result === null) {
		$result = file_get_contents("http://api.hostip.info/get_json.php?ip=8.8.8.8");
	}
	
	return $result;
}

var_dump(getJSON());
var_dump(getJSON());
var_dump(getJSON());
```
Chromeのデベロッパーツールで変更を保存する方法

1.デベロッパーツールのSourcesタブを選択
2.右クリックメニューからSave Asを選択
3.元のファイルを選択して上書き反映

※Elementsタブで編集中の場合は、一番右のファイル名をクリックすると該当するファイルがSourcesタブで開かれる

参考URL（英語動画）
Explore and Master Chrome DevTools > Chapter 2 "Advanced DOM and Styles"
http://discover-devtools.codeschool.com/
【今更ですが】itunes storeのランキング履歴取っていくツール公開します。

**まずリポジトリこちら(」・ω・)」うー！(/・ω・)/にゃー！**

analozy
https://github.com/YusukeKomatsu/analozy

**これ何？**

itunes storeのランキング履歴を集積するためのツールです。

作ってた当時、itunesのランキングが公式のだと情報少なすぎるし、そうじゃないと当日のしかなくて、過去にさかのぼって見れるサービスやツールがなかったので、その時に巷でバズりはじめられていたFuelPHPでなんか作ってみたかったんでそれで作ってみたものです。

**公開に至った理由**

* iOSアプリ最近作ってないんで。
* もうiOSユーザじゃないんで。
* 結構これ系のネタがググれば出るようになったので、ネタとして廃れてきてる。
* データ量がものすごく多くなるんで、個人で扱うのはちょっと...
* 個人だったら、もうAppannieとかでいいんじゃね？
* でも、企業とかでランキングの追跡したり、ライバル企業の動向を見るのには使える。

**機能**

* iTunesで一般公開されてるランキングデータを300件まで取得(設定で変えれます)
* アプリだけじゃなくて音楽とかそういうランキングも取得可能
* 過去にさかのぼってアプリの説明文とかアイコンとか見れる。
* 各国のランキング取得可能

**その他**

... 作り直したいなぁ、RubyとかPythonで... Goもありかな...
コメントに<title>って入れたらハマった

コメントに&lt;title>タグがそのまま出てきてdeleteもeditも機能しなくなったので自分で消した。

```
r = new XMLHttpRequest();
r.open ('POST', '/comments/ab513dcd3e12d68cfd05', false);
r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
r.send(
     "_method=delete&authenticity_token=g104/v62/giZvfPXIcmsVchHylxHarY2b94/905uB9U="
);
```
[Android] OSのバージョンごとに処理や表示を分ける方法

星の数ほどあるAndroid端末の全てに対応するのは非現実的だとしても、アプリはできるだけ多くの端末で動作させたいところです。

レイアウトの工夫やSupport Libraryを利用することである程度カバーできますが、どうしてもOSバージョンごとに処理を振り分けなければいけないケースもでてきます。

その方法をまとめます。

## リソース類（レイアウト、画像など）

各リソースのフォルダ名に `-v{バージョン番号}` を付加します。
[バージョン番号(APIレベル): wikipedia](http://ja.wikipedia.org/wiki/Android#.E3.83.90.E3.83.BC.E3.82.B8.E3.83.A7.E3.83.B3)
[Build.VERSION_CODES: Android Developers](http://developer.android.com/reference/android/os/Build.VERSION_CODES.html)

例.
下記のようにフォルダを用意してそれぞれに専用のレイアウトファイルを入れておくと、端末のバージョンに応じて、使用するレイアウトファイルが **自動的に**割り振られます。

| フォルダ名  | 適用されるOS（※）      |
|:-----------|-----------------:|
| layout     |Android 1.0〜2.0.1|
| layout-v7  |        2.1〜2.3.7|
| layout-v11 |             3.0〜|

（※）AndroidManifest.xml（AndroidStudioを使用しているときはbuild.gradle）で、指定した `minSdkVersion` より低いバージョンの端末にはそもそもインストールできません。

drawableなど、layout以外のリソースも同じ方法で振り分けられます。


## ソースコード（.java）
[参考: Android　ビルドバージョンで処理を分岐する](http://y-anz-m.blogspot.jp/2011/04/android.html)
ソースコード中で処理を分岐させたいときは、`Build` クラスをのSDK_INT, VERSION_CODEを使用します。

```java
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
  // ここはGINGERBREAD（Android 2.3）以降で実行される。
}

```

`Build.VERSION.SDK_INT >= 11` などと書いているサンプルも見かけますが、まあお好みで。（コードネームのほうがわかりづらいという意見もあると思いますが私はVERSION_CODE派です。あ、でもリソースフォルダはバージョン番号なので、そちらとの統一を考えると数字の方がいいかも知れませんね。）

## NewApiチェックによるエラーの回避

このようにバージョンごとに分岐させることで、古いバージョンに対応していないクラスやメソッドを新しいバージョンのみで使うことができますが、EclipseやAndroidStudioでエラーが発生するケースがあります。

AndroidManifest.xml の `minSdkVersion = 7` で

```java
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    getActionBar().setDisplayShowHomeEnabled(true);
}
```
とすると、Android 7〜10ではActionBarが使えないためIDE上でエラーとなるのです。実際にはif文の分岐により実行されませんが。

そこで、以下のように書き換えることで「この処理は11以降専用なんですよー」とコンパイラ（というか静的解析ツール Lint）に伝え、エラーを抑制します。

```java
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    setShowHomeEnable();
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setShowHomeEnable() {
    getActionBar().setDisplayShowHomeEnabled(true);
}

```

注意が必要なのは、TargeApiアノテーションはあくまでチェックツールLintのエラーを抑制しているだけで、 **アプリ実行時に11未満での実行を回避してくれるわけではない**ということです。
なので、if文による場合分けは外せません。場合分けしないと11未満でも実行されてExceptionが発生します。

冗長な書き方で嫌なんですけどね...これくらいよきに計らってくれよと言いたいです(^_^;)

以上
Git command lineでauto complete

Gitを使ってる時、ブランチ名が正確にわからずにわざわざgithubや`git branch`で一覧からコピペしたりでウンザリ。

そんな時に[autocomplete-git](http://code-worrier.com/blog/autocomplete-git/)。

超絶便利。
ローカルのブランチだけでなくリモートのブランチも補完してくれる。
もちろんgitのコマンド補完もできます。

インストールは簡単。

まずは実行ファイルを取ってくる。

```bash
curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash
```

`.bash_profile`に以下の行を追加。

```bash:.bash_profile
if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi
```

`.bash_profile`をロード。

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

オススメです。
SimpleAuthの使いかた


七音と五音ですね。
以前[SimpleAuthでサブドメインをまたぐ](http://qiita.com/yumura_shiho/items/25b7ed3afe0e77f27915)なんて記事を書いておいて何を今更という感じですが
そもそも導入部を書いてなかったので書いておきます。

SimpleAuthはFuelPHPインストール時に既に入っているパッケージなので、設定すれば動きます。

## 設定

 + fuel/package/auth/config より auth.php simpleauth.phpをコピー
 + fuel/app/config に貼り付け

```auth.php
return array(
	'driver' => 'Simpleauth',
	'verify_multiple_logins' => false,
	'salt' => 'YOUR_SALT_STRING',
	'iterations' => 10000,
);
```

```simpleauth.php

	'table_name' => 'users',

	'login_hash_salt' => 'kmwmtrhtr',

	'username_post_key' => 'username',

	'password_post_key' => 'password',
```

上記項目を環境に合わせて調整してください。
このケースではusersテーブルにユーザー情報を持ち、usernameカラムとpasswordカラムを用いてログインを行う設定になっています。

groupの使い方はまた別に。

usersテーブルについてですが、これについてはDBを作成する必要があります。
なにか便利な方法があったのかもしれませんが、私は全て手打ちでやってしまいました(´@ω@｀)
[公式リファレンス](http://fuelphp.jp/docs/1.7/packages/auth/simpleauth/intro.html)によれば
>少なくとも、 'username', 'password', 'email', 'last_login', 'login_hash', 'group', 'profile_fields' を含んでいる必要があります。

とのことでした。
username_post_keyの値はあくまで$_POSTのキーの名前なので、DBに直接の関係は無いみたいです。

## ビュー側

```login.php
		<?php echo Form::open(array('action'=>'login'),array(\Config::get('security.csrf_token_key') => \Security::fetch_token())) ?>
			<?php echo Form::input('username','') ?>
			<?php echo Form::input('password','') ?>
			<?php echo Form::input('send', 'ログイン', array('type'=>'submit')) ?>
			<p><?php echo Html::anchor('http://antn.info/forget','パスワードを忘れた方はこちら') ?>
		<?php echo Form::close() ?>
```

ここでinputの第一引数(name値)に指定されているのが上記でusername_post_keyなどに設定した文字列になっています。しかし関係有るのかこれ？
で、これを受け取るコントローラーが以下。

## コントローラー側

```hoge.php
	public function before(){
		parent::before();
		
		$post_methods = array(
			'login'
		);
		
		// root/Controller/Methodを指す
		$method = Uri::segment(2);
		
		// ログインチェック
		$auth_methods = array(
			'setting'
		);
		/*
		 * 認証が必要なメソッド且つログインしていない場合
		 * ログイン画面へ遷移
		 */
		if((empty($method) || in_array($method ,$auth_methods)) && !Auth::check()){
			Response::redirect('login');
		}
		
		// CSRFチェック
		if(Input::method() === 'POST'){
			if(!Security::check_token()){
				Response::redirect('error');
			}
		}
	}
```

上記ソースでは、「settingを開いた時にログインいていなければloginメソッドへ遷移」位のことが書かれています。もちろん、loginを開いた時は問題なくログイン画面が表示されます。
ここを誤って`$auth_methods=array('setting','login')`なんて書いてしまうと、リダイレクトループにハマる羽目になりますのでご注意を。

before()メソッドは、コントローラーの各メソッドにアクセスする前にかならず通過する場所です。
ここに認証を書いておくことで、例えばSimpleAuthを利用しない場合であっても簡単な認証を組むことが出来ます。

```hoge.php(続き)
	public function action_login()
	{
		$post = Input::post();
		if(!empty($post)){
			// ログイン処理
			$username = $post['username'];
			$password = $post['password'];
			$result_validate = '';
			if ($username !== null && $password !== null) {
				// ログイン認証を行う
				$auth = Auth::instance();
				if ($auth->login($username, $password)) {
					// ログイン成功
					Response::redirect('index');
				}
				$result_validate = "ログインに失敗しました。";
			}
		}
		$this->template->title="ログイン";
		$this->template->content = View::forge('hoge/login',$data);
	}
```

一先ずこれで簡単なログイン動作が完成ですヽ(´@ω@｀)ﾉ
長い記事は読む気がしないので、細かい設定や応用編はまた後に。
Nokogiri  + capybara + PhantomJS(poltergist)を使ってスクレイピング

静的ページであれば、nokogiriで普通にparseしてスクレイピングできますが( 参考：http://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/ )、jsを使っている動的ページでは勿論できず、、、

今回はそういう問題を解決すべく探していたところ、seleniumでやる方法は結構出てきたんですが、さすがに遅すぎる & ブラウザをインストールしておかないと駄目で何かと面倒だったので、capybara、poltergistで実装してみました。

###1.インストール

```Gemfile
gem 'nokogiri'
gem 'poltergeist'
gem 'capybara'
```

"poltergeist/PhantomJS"の説明とかは省きます。
※詳しく知りたい人はググってみてくださいw

それぞれをインストールします。
次にPhantomJSをインストールします。

- CentOSにPhantomJSをインストールする
http://konboi.hatenablog.com/entry/2013/07/05/173957


- phantomjsをインストールしてみる
http://nigohiroki.hatenablog.com/entry/2012/12/14/004915

###2.実装

```hoge.rb

require 'nokogiri'
require 'capybara'
require 'capybara/poltergeist'
class Hoge
    
  def self.scrape_include_js_contents
    #poltergistの設定
    Capybara.register_driver :poltergeist do |app|
      Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :timeout => 1000 }) #追加のオプションはググってくださいw
    end
    Capybara.default_selector = :xpath
    session = Capybara::Session.new(:poltergeist)
    #自由にUser-Agent設定してください。
    session.driver.headers = { 'User-Agent' => "Mozilla/5.0 (Macintosh; Intel Mac OS X)" } 
    session.visit "https://hoge.com"
    page = Nokogiri::HTML.parse(session.html)
  end 
end
```

ってな感じでできました。
実際にガシガシ使っていく場合は、moduleとして切り分けたりして実装してもらえれば良いかと思います（｀・ω・´）
会社にProxyを立てていて、その中にGitサーバーがたっていて、 AWS内のサーバーと連携させたいんだけど当然AWS側からは参照できないときに使えるTips。

会社にProxyを立てていて、その中にGitサーバーがたっていて、
AWS内のサーバーと連携させたいんだけど当然AWS側からは参照できないときに使えるTips。
# JenkinsをつかってProxy外のGitと同期をとる

ちょっと手間ですが、AWS内にJenkinsSlaveを構築することで、Jenkinsを仲介して（JenkinsのMaster-Slaveの関係をつかって）自動化することが可能です。


## 構成
Jenkins master (社内:Proxyない) --> Jenkins Slave (AWS VPC or Classic)


## 下準備1 Jenkins Master, Slave 設定

社内のJenkinsMasterから、AWS内のJenkinsSlaveサーバーにアクセスできるようにSSHの鍵設定、通常のJenkinsSlave用の設定を行い通常のJenkins　Job連携（JobAが終わったらJobBをキックする）が動くことを確認しておきます。

## 下準備2 Git repository の初回転送
下記を参考にJenkins Slave サーバーの/opt/git 以下に　同期させたいリポジトリを転送しておく
 事前に/opt/git を ssh user で rwx 権限を付けておくこと。

[Git サーバー - サーバー用の Git の取得](http://git-scm.com/book/ja/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E7%94%A8%E3%81%AE-Git-%E3%81%AE%E5%8F%96%E5%BE%97)


### ローカルPCで実施
```
$ git clone --bare my_project my_project.git
$ scp -r my_project.git user@git.example.com:/opt/git
```

### Jenkins Slave で実施 
```
$ cd /opt/git/my_project.git/
$ git init --bare --shared
Reinitialized existing shared Git repository in /opt/git/my_project.git/
```


## Jenkins の設定
いよいよJenkinsの設定ですが、２つジョブを作ります
各Jobで実行するインスタンスを指定することができるのでそれぞれMaster,Slaveを指定します。
Master側のJob１．Master側で社内Gitサーバーを監視、更新をPullして、Slave側にPushする、Job2をキック
Slave側のJob2.　自サーバー内のOpt/gitから　最新をPullして　望みの処理を実施する。

### Jenkins Master 側のJob例

```
#!/bin/bash -xe

#echo "## current dir:"
pwd
ls -al

git checkout $BRANCH_NAME
git branch -a
git pull

export http_proxy="http://proxy.XXXyourproxyserverXXX/";
export https_proxy="http://proxy.XXXyourproxyserverXXX/";
                  
git push ec2-user@XXXyour_jenkins_slave_server.com:/opt/git/$REPOSITORY.git
```



### Jenkins Slave側のJob例

以下では例として、chefポジトリの更新に反応して,
knife solo を実行させる簡単な例です。

```
#!/bin/bash +e

ls -al

echo "check already cloned?"
echo $REPOSITORY

if [ -d $REPOSITORY ]
then
  cd $REPOSITORY
  echo "##Do git checkout"
  git checkout $BRANCH_NAME
  echo "##Do git pull"
  git pull
else
  echo "## git clone"
  git clone /opt/git/$REPOSITORY.git
  cd $REPOSITORY
  echo "## git checkout"
  git checkout $BRANCH_NAME
  echo "## knife solo init"
  knife solo init .
fi

git branch -a
ls -al
cd $TARGET_DIR

echo '## start'
##berks install skipped 
chmod 755 ./echo_hosts.sh
./echo_hosts.sh | xargs -n 1 knife solo bootstrap
```




##改善の余地

Slave側のJobの記述方法は通常のJenkinsのGitPluginを活用したほうがきれいになるでしょう。
やってることが分かりやすく伝えるためにスクリプトにしています。
Scala: 正規表現でマッチするかどうか調べる方法



いろんな方法がある


```scala
"1234".matches("""\d{4}""")                       //> res0: Boolean = true

new scala.util.matching.Regex("""\d{4}""").findFirstIn("1234").nonEmpty
                                                  //> res1: Boolean = true

"""\d{4}""".r.findFirstIn("1234").nonEmpty        //> res2: Boolean = true


val dateP1 = """(\d\d\d\d)-(\d\d)-(\d\d)""".r     //> dateP1  : scala.util.matching.Regex = (\d\d\d\d)-(\d\d)-(\d\d)

"2011-07-15" match {
	case dateP1(year, month, day) => true
	case _ => false
}                                                 //> res3: Boolean = true


val dateP1(year, month, day) = "2011-07-15"       //> year  : String = 2011
                                                  //| month  : String = 07
                                                  //| day  : String = 15

dateP1.findAllIn("2011-07-15").matchData.foreach { m =>
	println(m.group(0))
	println(m.group(1))
	println(m.group(2))
	println(m.group(3))
}                                                 //> 2011-07-15
                                                  //| 2011
                                                  //| 07
                                                  //| 15

val dateP2 = new scala.util.matching.Regex("""(\d\d\d\d)-(\d\d)-(\d\d)""", "year", "month", "day")
                                                  //> dateP2  : scala.util.matching.Regex = (\d\d\d\d)-(\d\d)-(\d\d)

dateP2.findAllIn("2011-07-15").matchData.foreach { m =>
	println(m.group("year"))
	println(m.group("month"))
	println(m.group("day"))
}                                                 //> 2011
                                                  //| 07
                                                  //| 15

```
文字数制限のあるVARCHARへのINSERT/UPDATEをエラーでなく切り詰めに

テーブル設計において文字列データのサイズ設定は皆様等しくお悩みでしょうか。

容量ほぼ無制限のTEXTとか使ってしまえばいいんですが、データ量見積もりの都合上上限を設けておいた方が都合が良いこともあり、あまり根拠もなくVARCHAR(64)などとキリの良さ目の数字で文字数制限をかけていることもあるかと思います。

そんなカラムへの値の挿入・代入で忘れがちなこと。
**文字数オーバーの文字列の挿入・代入はエラーになります。** 切り詰められるだけと思っていた方多いのではないでしょうか。エラーになるのがSQL標準です。

それをアプリケーション側で防止しようとしたときに忘れがちなこと。
**文字数の数え方はDB製品とアプリ言語で結構違います。** 代表的なのがサロゲートペアを1文字に数えるか2文字に数えるか。まあルールの数は有限なのでがっちり完全な文字数制限処理を書くことも可能なのですが、そうするとDB知識にアプリがべったりですね。結局、設計としてアウトかと思われます。

キャストなら切り詰められる
==
文字数オーバーでINSERT/UPDATEはエラーになるのですが、TEXTからVARCHAR(n)へのキャストならエラーにならず切り詰めになります。

そこでINSERTならこう書けば安全になります。

```sql
INSERT INTO my_table (value) VALUES(CAST(? AS VARCHAR(64)));
```

無論ですが、挿入した値と取り出した値が切り詰めによって変化している可能性は考慮の上でプログラミングしなければなりません。
<実話>まだ座ってる？開発者に勧めるスタンディングデスクをする3つの理由と7つの効果

<h1>はじめに</h1>
これは一般論ではなく、[私のスタンディングデスク生活](http://azumaxlife.smile-systems.com/archives/1002)の記録です。自分のことだけ記録します。
<h1>きっかけは二大派閥</h1>
この二大派閥、おそらく目的はふたつで、健康のためか、単に面白いから。と軽く偏見持ってますがそんなところでしょう。派閥は下の2つ
1, バランスボール派
2, スタンディングデスク派

ちょっと健康体になろうと思っている中で、
軍師官兵衛で言うところの、毛利につくか、織田につくかという状況です。
中立(椅子に座る)は許されませんでした。
はじめは毛利(ボール)につくつもりでした。
<ul>
	<li>体幹が鍛えられる</li>
	<li>いろんな座り方ある</li>
	<li>なんか楽しそう</li>
</ul>
しかし、村重みたいに献上品（お小遣い）持ってない。
「あ、手元にはこ（筺）あるじゃん」ということで、
スタンディングデスクに決めました。
あとは、<a href="http://www.lifehacker.jp/2014/06/140608walking.html">最近のライフハッカー</a>にもあったけど、
まえまえから、「座るのは良くない」となんとなく言われてたので、
立ってみることにしました。

<h3>３つの理由
<ol type="1">
	<li>お金がない</li>
	<li>はこ（筺）があった</li>
	<li>座るのは体に良くない</li>
</ol>
</h3>
<h2>効果</h2>
始めたのが４月すぎだったので、だいたい２ヶ月くらい経ちました。
現在の効果は下の7つです。

<h3>良い効果
<ol>
	<li>腰が痛くなくなった</li>
	<li>顔を触らなくなったので前よりよくなった</li>
	<li>作業が捗る</li>
	<li>周りと話しやすくなった</li>
</ol>
</h3>
<h3>
悪い効果
<ol>
	<li>やっぱきつい</li>
	<li>なんか指痛い</li>
	<li>デュアルディスプレイできなくなった</li>
</ol>
</h3>
<h2>良い効果</h2>
<h3>腰が痛くなくなった</h3>
> まだ年取ってないのに、椅子から立ち上がると少しイタタタってなってました。
> それがなくなりました

<h3>顔を触らなくなったので前よりよくなった</h3>
>立ってると肘付けないし、腕を上に持っていくのがだるいからだと思う

<h3>作業が捗る</h3>
>ひとつは、前よりみんなにディスプレイ見られるし、変なことできない。
>もうひとつは、眠気がこない。結構ずっとフル稼働。ちょっとはコーディング早くなったかも

<h3>周りと話しやすくなった</h3>
>見渡せるので、人の状況を把握しやすくなった。
>ディスプレイ見られる代わりに、他の人のも見える。

<h2>悪い効果</h2>
<h3>やっぱきつい</h3>
>足がね。多分立ち方が悪いんだろう。まあ、時間的に半日くらい立ってるしね。

<h3>なんか指痛い</h3>
> 左手小指の爪の側面が、薬指の第一関節下にめり込んで怪我するようになった。
> 自分だけだろう。

<h3>デュアルディスプレイできなくなった</h3>
> １はこ１ディスプレイ、１はこキーボード。はこがない。

<h1>まとめ</h1>
健康体には「なりつつ」あるかもしれませんが、
肌が綺麗になっただけ。これからも頑張ります。

開発者•プログラマって、だいたい一日中パソコンと向き合ってて、
あんま話してない、と思ってる人はもう少ないかもしれませんが、
実際自分はそうじゃないです。

ブレストや打ち合わせ、コミュニケーションが特に重要。
それが終わったら、いかに短期間でコーディングするか。
上に書いた良い効果は私の状況にあっています。

案外プログラマでスタンディングデスクする人増えていると思うので、あなたもどうですか。
SELECT * FROM hoge WHERE id = '1' に潜む罠

一見して問題ないように見えるこのSQL
idがstring型であれば確かに問題は無いのですが、一般的にidはintで宣言されている事が多いと思います。
タイトルに書いたようなSQLのままであれば意図した通りidが1のレコードのみ取得出来るでしょうが、
次のようなSQLになった場合はどうでしょうか。

```sql:sql
SELECT * FROM hoge WHERE id = '1hoge'
```
結論として、このSQLではidが1のレコードが取得されます。

なぜそんな事が起きるのでしょうか。
次のSQLを実行すればわかると思います。

```sql:sql
SELECT CAST('1hoge' AS  SIGNED)
```
![スクリーンショット 2014-06-09 2.34.58.png](https://qiita-image-store.s3.amazonaws.com/0/35451/5f17132f-81cc-f27a-1a56-0c73cf539b64.png)
1hogeをintger型にキャストしています。
これと同じ事が最初のSQLでも同じ事が起きています。

id列はint型で、条件に指定した1hogeは文字列なので、暗黙の型変換をして
結果としてid = 1の形になり、idが1のレコードが出力されます。

他にも暗黙の型変換に潜む罠は多いようです。
参考にさせていただいた徳丸先生のサイトがあるので、こちらもどうぞ。
http://www.tokumaru.org/d/20090924.html
[PHP]MySQLへの接続


phpからデータベースにアクセスするには2通りの方法がある。

- DB固有の拡張モジュールを直接使う
- PDOのようなDBに依存しないライブラリを使う

初心者の自分は一旦深く考えず、PDOによる方法を選択した。

# 1.DB設定（接続準備）

```php
$dsn = 'mysql:host=000.000.000.000;dbname=hoge';
$username = 'hoge_usr';
$password = 'hoge_pass';
$options = array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$db = new PDO($dsn, $username, $password, $options);
```

- `host=`の後ろの、`000.000.000.000`は各自読み替えること
- `000.000.000.000`のところは、「ホスト名」or「IPアドレス」


# 2.SQL文実行
具体例見たほうが速いので。
## (例1)select文実行

```
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
    $stmt = $db->prepare('select rank, article_id, tweets from table_name',
        array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
} else {
    die("このアプリケーションは mysql でしか動作しません。代わりに \$stmt->fetchAll() を使用すべきです");
}
$stmt->execute(); //SQL文実行
$array = array();
while ($row = $stmt->fetch()) { //SQL文実行結果を上から1行ずつ$rowに代入
    $array[] = array('rank' => $row['rank'], 'article_id' => $row['article_id'], 'tweets' => $row['tweets']);
}
$stmt = null; //おまじない
```

- 2行目でSQL文記述
- `table_name`などSQL文は各自読み替えること
- `.`は文字列連結
- while文の中の変数名も各自読み替えること
- `$array`にはSQL文の実行結果（連想配列のインデックス配列）が格納される
- `$row`のkey（`rank`、`article_id`、`tweets`）にはDBのカラム名を書く

## (例2)update文実行
```
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
    $stmt = $db->prepare('update table_name set contents = ' . $contents . ', title = ' . $title . ' where ID = ' . 1,
        array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
} else {
    die("このアプリケーションは mysql でしか動作しません。代わりに \$stmt->fetchAll() を使用すべきです");
}
$stmt->execute(); //SQL文実行
$stmt = null; //おまじない
```

- 2行目でSQL文記述
- `table_name`などSQL文は各自読み替えること
- `.`は文字列連結
- update文で複数カラムを変更→`,`つなぎでOK
複数のTweenを組み合わせる


[サンプル](http://jsdo.it/matsui_q/yQyC)

#Tweenコンストラクタ
Tween　(target,Properties)

##propertiesの種類

| 引数 | 内容 |
|:-----------|:------------|
| loop | ループ処理 |
| useTicks      | 実行の長さをTick数にするかどうか |
| ifnoreGlobalPause | Tween.ifnoreGlobalPauseプロパティを決める |
| override | 他のtweenを削除 |
| paused | はじめにtweenを一時停止しておくか決める |
| position | 再生開始位置を決める |

#動きを変える
Tween.wait(待ち時間)

#まとめて書く

```js
Tween.get(target, {loop: true})
     .to({y:nHeight-40, rotation:360}, 1000, Ease.bounceOut)
     .wait(1000)
     .to({alpha:0}, 1000, Ease.circIn)
     .call(setAppearance);
```
webmailクライアントを試してみた

ubuntu 14.04で試してみた。

IlohaMail
=========

[IlohaMail](https://www.google.co.jp/search?q=IlohaMail&tbm=isch)を試してみた。

```bash:
$ sudo apt-get install -y ilohamail
$ cd /etc/apache2/sites-enabled
$ ln -s /etc/IlohaMail/apache.conf IlohaMail.conf
```

conf.phpがphpのsyntax errorになるので修正。

```diff:/etc/IlohaMail/conf.php
-$GPG_HOME_STR = "/var/cache/IlohaMail/gpg/%u.%h";\
+$GPG_HOME_STR = "/var/cache/IlohaMail/gpg/%u.%h";
```

http://IP/IlohaMail/ にアクセスするとログイン画面が表示される。
特徴はlocalhost以外にも接続ができる点。

```bash:アンインストール
$ sudo unlink /etc/apache2/sites-enabled/IlohaMail.conf
$ sudo /etc/init.d/apache2 restart
$ sudo apt-get purge ilohamail
$ sudo rm -rf /var/cache/IlohaMail
```


SquirrelMail
=======

[SquirrelMail](https://www.google.co.jp/search?q= SquirrelMail&tbm=isch)を試してみた。


```bash:
$ sudo apt-get install -y squirrelmail
$ cd /etc/apache2/sites-enabled
$ sudo ln -s /etc/squirrelmail/apache.conf squirrelmail.conf
```

http://IP/squirrelmail/ にアクセスするとログイン画面が表示される。
これは設置したサーバに存在するアカウントのID/Passを入力する。

## 文字化け対策

```diff:src/webmail.php
  $output = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\">\n".
            "<html><head>\n" .
            "<meta name=\"robots\" content=\"noindex,nofollow\">\n" .
+           "<meta charset=\"euc-jp\">\n" .
            "<title>$org_title</title>\n".
            "</head>";
```

roundcube
=========

ajax対応ということで[roundcube](https://www.google.co.jp/search?q= roundcube&tbm=isch)使ってみたかったがログイン直後`SERVICE CURRENTLY NOT AVAILABLE! Error No. [500]`で動かなかった。
DB接続関連？

```bash:
$ sudo ln -s /etc/roundcube/apache.conf roundcube.conf
```

```diff:/etc/roundcube/apache.conf
-#    Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/
-#    Alias /roundcube /var/lib/roundcube
+Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/
+Alias /roundcube /var/lib/roundcube
```

```bash:エラーログ
$ tail -f /var/log/roundcube/errors
```

```bash:db接続用コンフィグファイル
/etc/dbconfig-common/roundcube.conf
```

```bash:アンインストール
$ sudo apt-get purge roundcube roundcube-core
$ sudo apt-get autoremove -y
```
MacOS 上に Centos 6.5 環境を VirtualBox, packer, vagrant で構築する。

# 課題
MacOS 上に Centos 6.5 環境を VirtualBox, packer, vagrant で構築する。

# 構築環境

以下に設定のためのファイル一式を置いた。
  https://github.com/katoy/using-packer

# 説明

 操作欄の操作をすると、centos 6.5 が Virtuaxbox で動作するようになります。 
 ViatrulBox, vagrant, paker を事前に install しておく必要があります。  

  [VirtualBox](https://www.virtualbox.org/)
  [vagrant](http://www.vagrantup.com/)
  [packer](http://www.packer.io/)

## 環境

  Oracle VM VirtualBox Manager 4.3.12
  Vagrant 1.6.3
  Packer v0.6.0
  ruby 2.1.2
  Macos 10.9.3

# 操作

    $ cd centos
    $ packer validate centos-6.5.json                    # json の内容をチェックします。
    $ packer build -only=virtualbox-iso centos-6.5.json  # centos6.5 の iso を download し, Virtualbox 上で install します。
	                                                     # その結果を vagrant 用の box にします。
      
    $ cd ../vagrant                                      # vagrant  で 作成した box を利用できるようにします。
	$ vagrant box add CentOS-65 box/virtualbox/CentOS-6.5-x86_64-VirtualBox.box
 	$ vagrant init CentOS-65
	$ vagrant up
	$ vagrant ssh
	  exit
	$ vagrant status
	$ vagrant halt

vagrant/Vagrantfile-001 を使って provison すろと、 httpd, php, postgres が稼働する環境になります。  
プラウザで  http://192.168.33.10/ や http://192.168.33.10/info.php にアクセスしてください。

# 参考
- http://jitsu102.hatenablog.com/entry/2014/03/16/234808
  Packer で Vagrant 用仮想マシン (base box) を作成する (2014-03-16)

- https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/ch-kickstart2.html
  第32章 キックスタートインストール

- http://qiita.com/shin1x1/items/3288d9de7f04192b6ad8
  Vagrant体験入門ハンズオン手順 - 2014/04/24 DevLove関西

- http://www.1x1.jp/blog/2014/04/vagrant-handson-in-devlove-kansai.html
  Vagrant体験入門ハンズオンの資料を公開します
  ＞＞   http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box

- http://qiita.com/hmukaida/items/23bf728ac08c8fa31f5c
  Vagrant+CentOS6.5+Apache2+PHP5.3+PostgreSQL9.3 on Mac の環境を構築する (上の続き)

- http://shin1x1.github.io/vagrantx/
  the Vagrant GUI client for Mac OS X
[PHP]POSTメソッドで値を投げる＆投げた値を取得


# POSTメソッドで値を投げる
```php
<form method="POST" action="hogehoge.php">
  <table>
    <tr>
      <th>rank</th>
      <th>artcle_id</th>
    </tr>
    <?php for ($i = 1; $i < 6; $i++) { ?>
    <tr>
      <td><?php echo $i; ?></td>
      <td><input type="text" name="<?php echo "article_id_" . $i ?>"</td>
    </tr>
    <?php } ?>
  </table>
  <input type="submit" value="変更">
</form>
```

- formタグでinputタグたちを囲むべし
- formタグのmethod属性でHTTPメソッドを指定
- formタグのaction属性で送信先プログラムのURIを指定
- inputタグのtype属性をtextにするとテキストボックス→テキスト入力欄
- inputタグのname属性で書いた名前を用いて、後で値を受け取る
- inputタグのtype属性をsubmitにすると、formタグで囲んだ内容を投げられる（←ボタン）
- valueに書いた値がボタンに書かれる

# 投げた値を取得
```php
$_POST[name]
```
nameのところは、上記「inputタグのname属性」に書いた名前に各自置き換えること。
上記の例では、

```php
$_POST[$article_id_1]
$_POST[$article_id_2]
$_POST[$article_id_3]
$_POST[$article_id_4]
$_POST[$article_id_5]
```

とすることで、それぞれのテキストボックスに書いた文字列を取得できる。
[PHP]Twitterのツイート数を取得する方法


# 概要
## 1.tweet数（を含む文字列）を取得
### curlを使ってHTTPリクエストを投げる方法
- curl_init()：初期化（準備）
- curl_setopt()：オプションの設定
- curl_exec()：実行
- curl_close()：セッション終了

### HTTPリクエストに使うURLはTwitterのAPI
- `http://urls.api.twitter.com/1/urls/count.json?url=http://foo.bar.jp`

(注1)
`http://foo.bar.jp`の部分は適宜読み替えること。
(注2)
FBいいね数は`http://graph.facebook.com/http://foo.bar.jp`で取得可能。

## 2.取得した文字列からtweet数のみ抜き出す
### preg_replaceを使って文字列置換
- 正規表現使う
- 第1引数：pattern。変換前。
- 第2引数：replacement。変換後。
- 第3引数：置換させる文字列。


# 実際に書いたコード


```php
// tweet数（を含む文字列）を取得
$ch = curl_init(); // 初期化
curl_setopt($ch, CURLOPT_URL, "http://urls.api.twitter.com/1/urls/count.json?url=http://foo.bar.jp"); // URLをセット
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // curl_exec()の結果を文字列で返す
$c = curl_exec($ch); // 実行
curl_close($ch); // セッション終了

// 取得した文字列からtweet数のみ抜き出す
$pattern = '/(\D+):(\d+),(.+)/';
$replacement = '$2';
$c = preg_replace($pattern, $replacement, $c);
```

前半部分（HTTPリクエスト投げる部分）

- 上記ソースでは、HTTPリクエストにGETメソッドを利用。
- `curl_exec()`の行の`$c`には連想配列を表す「文字列」が入っている。
- (`$c`の中身：`{"count":226,"url":"http://foo.bar.jp/"}`)
- 最終行の`$c`には「226」が入っている。

後半部分（正規表現使って文字列置換）

- `$pattern`に代入する値は必ず`'/`と`/'`の間に書く。（おまじない）
- `(\D+)`には`{"count"`が入っている。←「`\D`は数値以外」「`+`は1文字以上」
- `(\d+)`には`226`が入っている。←「`\d+`は1文字以上の数値」
- `(.+)`には`"url":"http://foo.bar.jp/"}`が入っている。←「`.+`は任意の1文字以上の文字列」
- `replacement`の`$2`は真ん中の`(\d+)`を表す。
- `$1`は`(\D+)`、`$3`は`(.+)`を表す。
[PHP]リダイレクトして別ファイルを呼び出す


phpでリダイレクトをするには以下の2行を書けば良い。

```
<?php
header('Location: http://foo.bar.jp/hogehoge.php');
exit();
?>
```

(注)header()内のスペースの入れ方は上の通りにすること。
[PHP]多次元連想配列の扱い


本記事では、連想配列のインデックス配列を「多次元連想配列」と呼ぶことにする。


# 多次元連想配列に値を代入
```php
$array[] = array('ID'=>7, 'title'=>'多次元配列の扱い');
$array[] = array('ID'=>6, 'title'=>'画像圧縮と軽量化のすすめ');
$array[] = array('ID'=>5, 'title'=>'初心者のためのgitコマンド');
```

# 多次元連想配列から値を取得
```php
foreach ($array as $value) { //3回繰り返し
  echo $value['ID'];    // 7 → 6 → 5
  echo $value['title']; // 多次元配列の扱い →（略）
}
```

連想配列の連想配列から値を取得したい場合はforeach文のネスト。

```php
foreach ($array as $key1 => $value1) {
  foreach ($value1 as $key2 => $value2) {
    print $value2 . ", "; //「.」は文字列連結
  }
}

```

参照URL：http://web-dou.com/php/array2.html
とある集計プログラムを速くできなかったorz

某所の問題

某施設の時間あたり利用者数aがn個与えられるので
指定された範囲（s個目〜t個目）の合計利用者数をm回算出するだけ。
利用者数aは0〜20000
nは1〜100000
mも1〜100000

データは以下が標準入力で与えられる

> n m
> a1
> a2
> ...
> an
> s1 t1
> s2 t2
> ...
> sm tm

以下がコード。二分木作るより配列をrangeで抜いてsumったほうが(`@an[(s-1)..(t-1)].inject(&:+)`)速いんだけどなんで。

```rb
#! /usr/bin/env ruby

class Node
  attr_accessor :left, :right, :begin, :end, :sum
  def initialize(i,j,x)
    @begin=i
    @end=j
    @sum=x
  end
end

class Count
  def initialize(n,m)
    @n = n
    @m = m
    @an = []

    @summarized = false
  end

  def add(x)
    @an << x
  end

  # ナイーブ実装
  def psum(s,t)
    @an[(s-1)..(t-1)].inject(&:+)
  end

  # 二分探索
  def sum(s,t)
    s-=1
    t-=1
    pre_sum unless @summarized
    # "%d %d" % [s,t]
    return @an[s] if s==t
    return r_find(s,t)
  end

  private 

  def r_find(s,t)
    #p "%d %d" % [s,t]
    if @memo.begin == s && @memo.end == t
      return @memo.sum
    elsif s == t
      return @an[s]
    else
      med = (s + t) / 2
      return r_find(s, med) + r_find(med+1, t)
    end
  end

  # 二分木作る
  def pre_sum
    @summarized = true
    pre_sum_1(@an)
  end

  def pre_sum_1(a)
    i = 0
    tmp = []
    a.each_slice(2) do |x|
      if x.size > 1
        tmp << Node.new(i,i+1,x[0]+x[1])
      else
        tmp << Node.new(i,i,x[0])
      end
      i += 2
    end
    @memo = r_pre_sum(tmp)
  end

  def r_pre_sum(x)
    if x.size > 1
      tmp = []
      x.each_slice(2) do |x|
        if x.size > 1
          n = Node.new(x[0].begin,x[1].end,x[0].sum+x[1].sum)
          n.left = x[0]
          n.right = x[1]
        else
          n = x[0]
        end
        tmp << n
      end
      return r_pre_sum(tmp)
    else
      x[0]
    end
  end

end


if $0 == __FILE__

  def i_gets
    gets.split.map(&:to_i)
  end

  n, m = i_gets

  counter = Count.new(n,m)

  n.times do
    counter.add(i_gets[0])
  end

  m.times do
    puts counter.sum(*i_gets)
  end
end

__END__
5 3
6
0
1
3
12
1 3
4 5
2 2

```

とりあえず俺は課題の変数名とコードの変数名を合わせたらいいと思った。
ちょっとした物理演算の落とし穴

![140609_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/99a0309f-1a2d-52e8-6401-8a0f1a0c4165.jpeg)

視点方向の違いにおける移動量の違いもなくなり、キャラクターを移動してテストしていたある日のこと。

![140609_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/f635b0d5-e817-11e1-79e7-369e4be83adc.jpeg)

あれ、よそ見してる間にキャラクターどこいった？
　  
　  
　  
　  
　
![140609_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/dcf5f428-5dff-ff2f-34cb-d19aac91a49a.jpeg)

### *！？*
　  
　  
　  
・・・どういうことか結論から書いてしまうと、
向いている方向が分かるようにキャラクターに新規でつけた目とキャラクター自身が
特定の方向(具体的には重力のかかる下向き)を向きながら移動することで

1. 目と体が物理演算で押し出しあう。
2. 目は体オブジェクトの子関係なので相対位置を変えられない。
3. 結果として体が上に押し出される。
4. 目が体の位置に対応して移動する。
5. 1に戻る。

という **ドラゴンボールの空中戦のごとくパンチキックの殴り合いをしながら** 
**空の彼方へ消えていく破目**になったのである・・・！ ~~この始末☆~~


今回の対処法は以下の通りである。
![140609_04.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/99cca65c-69f1-9232-c309-1915cf3534ce.jpeg)


基本中の基本だが新規追加した後の保持コンポーネントの状態には注意である・・・。
Alfred でラクに Swift のドキュメント検索する設定


## Alfred の Preferences 開き、Features > Web Search > Add Custom Search 選択

![Alfred_Preferences.png](https://qiita-image-store.s3.amazonaws.com/0/4497/518127aa-a9e6-c9bf-fd19-56202676e727.png "Alfred_Preferences.png")

## 以下のような設定を行う

![スクリーンショット_2014_06_09_2_25.png](https://qiita-image-store.s3.amazonaws.com/0/4497/eb275c7f-3a7d-013f-b45a-c4c7573bc51b.png "スクリーンショット_2014_06_09_2_25.png")

### Search URL

`https://www.google.co.jp/#q=site:https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language+{query}`

### Title

`search Swift document` とか適当に。

### Keyword

`s` など。他と被らなくて短いものなら良いんじゃないでしょうか。

### Icon

[Apple から拝借](https://devimages.apple.com.edgekey.net/swift/images/swift-hero_2x.png) して設定すると良い感じです。

## Enjoy!

Alfred 呼び出して `s {keyword}` で Apple の公式ドキュメント内検索ができるようになりましたね！

`s regex` で何もヒットしないのは仕様です！ X(
boto + gspreadでAWSのデータをGoogleSpreadsheetに入れる

botoでAWSのデータを取り、gspreadでGoogleDriveのspreadsheetに保存する。


## 環境
|     使用環境     |     バージョン     |
:--------|:---------|
|     OSX     |     10.9.3     |
|     Python     |     2.7.6     |
|     boto     |     2.28.0     |
|     gspread     |     0.2.1     |

## 準備
Pythonモジュールboto,gspredをインストール

```$ pip install boto gspread
```


### gspread
>Google Spreadsheetを操作する為のpythonモジュール
https://github.com/burnash/gspread
gspread API Reference
http://burnash.github.io/gspread/

###boto
>AWSの操作、情報取得等を行えるpythonモジュール
https://github.com/boto/boto
boto API Reference
http://boto.readthedocs.org/en/latest/ref/ec2.html



## サンプルスクリプト
起動中のEC2インスタンスのインスタンスタイプから、
1時間、日、月毎の費用を1台ずつGoogleDriveのspreadsheetに記録するスクリプト
https://github.com/gacha-ru/scripts/tree/master/python/ec2_itype

※READMEにはスクリプトの使用方法しか書いてません。
　各モジュールについてはAPI Reference参照。
　書き方等、見辛かったりわかりにくい箇所がありましたらコメントいただけると幸いです。

※GoogleOAuthの変更(2015/5~)により、対象のシートに"client_email"のメールアドレス(account.jsonの"client_email")を
 共有設定で「編集者」以上の権限で追加しておく必要があります。(2015/11/26 追記)

```例：account.json
{
  "private_key_id": "tekitounaid",
  "private_key": "-----BEGIN PRIVATE KEY----- 〜略〜 \n-----END PRIVATE KEY-----\n",
  "client_email": "tekitou@developer.gserviceaccount.com",
  "client_id": "tekitou.apps.googleusercontent.com",
  "type": "service_account"
}
```

## 参考
Raspberry Pi で CPU 温度取得
http://u-tamax.jp/2013/09/raspberry-pi-%E3%81%A7-cpu-%E6%B8%A9%E5%BA%A6%E5%8F%96%E5%BE%97/

## まとめ
GoogleDriveのspreadsheetをデータベースのように使うことで、可視化、共有を楽にできる。
「あのアカウントでどんなインスタンスを何台動かしてたっけ？」ということは多々あるので、
すぐに見れるようにするととても楽になる。

※Googleアカウントの管理とスプレッドシートの権限設定には十分注意する。
cocos2d-x Flash(.swf)ファイルを変換して動かす方法


GAF Converter を使ってやってみたメモ。

## 環境
・MacOS X 10.9.3
・Xcode 5.1.1
・cocos2d-x v3.1.1
・GAF Converter v3.6

## What's "GAF Converter"?
公式:http://gafmedia.com/

.swfをcocos2d-x上で動作可能な、
.gafとテクスチャアトラス化した.pngに変換して出力できるツール


## How To Use

####1.GAF ConverterをDLする。
http://gafmedia.com/downloads
通常のデスクトップアプリと同様にインストール。


####2.swfファイルを変換する
GAF Converterを起動して、変換したい.swfファイルをドラッグドロップ。
変換が終わると、プレビューとテクスチャアトラス化された画像が確認できる。
.swfから同名の.gafと.pngがzipに圧縮されて指定したフォルダに出力される。

####3.cocos2d-xプロジェクトにライブラリ導入
http://gafmedia.com/downloads から今回はCocos2D-X v3 をDL。
解凍したフォルダをそのまま(Cocos2dxGAFPlayer-release-cocos2dx-3)
/projectName/cocos2d/external/ 配下にコピーする

####4.Xcodeで設定
Xcodeでプロジェクトを開いて
ProjectName->Build Phases->Target Dependencies
追加(+)を押して、gafplayer(GAFPlayer) を追加。

ProjectName->Build Phases->Link Binary With Libraries
追加(+)を押して、libgafplayer.a を追加。

ProjectName->Build Settings->Header Search Path
下記、2つのパスを追加
/projectName/cocos2d/external/Cocos2dxGAFPlayer-release-cocos2dx-3/Library
/projectName/cocos2d/external/Cocos2dxGAFPlayer-release-cocos2dx-3/Library/Sources

で、ビルドが通るようになる。

####5.コード書く
※2で生成した、.gaf .png をプロジェクトのResourcesフォルダに追加しておく


```
#include <GAFAnimatedObject.h>
#include <GAFPrecompiled.h>
```
2つをインクルードする

```
Size size = Director::getInstance()->getVisibleSize();
auto animation = GAFAnimatedObject::createAndRun("anime.gaf");
animation->setPosition(size.width/2, size.height/2);
addChild(animation);
```
.gafファイル(anime.gaf)を指定して実行。

## その他
GAF Library API Reference:http://gafmedia.com/docs/cocos2dx_v3/index.html
GitLab API (gitlab gem)

[GitLab API](https://github.com/gitlabhq/gitlabhq/tree/master/doc/api)には [gitlab gem](https://github.com/NARKOZ/gitlab) があり、簡単に使う事ができます。
以下のコードは、 あるグループに所属する全員の レポジトリーの一覧を表示し、そのリポジトリをアクセスするために自分のアカウントを管理者として登録し、全リポジトリーを clone するコードです。
`PRIVATE_TOKEN` は管理者(root)アカウントの `PRIVATE_TOKEN` を指定して下さい。

```rb
#!/usr/bin/env ruby
require 'gitlab'

GUEST_LEVEL       = 10
MASTER_LEVEL      = 40
GITLAB_SERVER_URL = 'http://GITLAB_SERVER'
GITLAB_API_URL    = "#{GITLAB_SERVER_URL}/api/v3"
PRIVATE_TOKEN     = 'xxxXXXXXXXXXXxxXXXXn'
GROUP_NAME        = 'student'
MY_NAME           = 'yuumi3'


def get_group_members(gitlab_root, group_id)
  gitlab_root.group_members(group_id).select{|e| e.access_level == GUEST_LEVEL}.map(&:username)
end

def add_member_to_projects(gitlab_member, user_id)
  gitlab_member.projects.each do |project|
    unless gitlab_member.team_members(project.id).find {|m| m.id == user_id}
      gitlab_member.add_team_member(project.id, user_id, MASTER_LEVEL)
      puts " add users to #{project.path_with_namespace}"
    end
    
  end
end

def list_all_projects(gitlab_member)
  gitlab_member.projects.each do |project|
    puts "  #{project.path_with_namespace}"
  end
end

def clone_all_projects(gitlab_member)
  gitlab_member.projects.each do |project|
    unless File.exists?(project.path_with_namespace)
      cmd = "git clone git@#{GITLAB_SERVER_URL}:#{project.path_with_namespace} #{project.path_with_namespace}"
      puts "  #{cmd}"
      system cmd
    end
  end
end


gitlab_root = Gitlab.client(endpoint: GITLAB_API_URL, private_token: PRIVATE_TOKEN)
username_to_id  = Hash[*gitlab_root.users.map {|u| [u.username, u.id]}.flatten]
groupname_to_id = Hash[*gitlab_root.groups.map {|u| [u.name, u.id]}.flatten]

members = get_group_members(gitlab_root, groupname_to_id[GROUP_NAME])

# 生徒のrepository一覧
members.each do |member|
  gitlab_member = Gitlab.client(endpoint: GITLAB_API_URL, private_token: PRIVATE_TOKEN, sudo: member)
  list_all_projects(gitlab_member)
end

# 生徒のrepositoryに私を管理者として追加
members.each do |member|
  gitlab_member = Gitlab.client(endpoint: GITLAB_API_URL, private_token: PRIVATE_TOKEN, sudo: member)
  add_member_to_projects(gitlab_member, username_to_id[MY_NAME])
end

# 生徒のrepositoryをclone
members.each do |member|
  gitlab_member = Gitlab.client(endpoint: GITLAB_API_URL, private_token: PRIVATE_TOKEN, sudo: member)
  clone_all_projects(gitlab_member)
end
```

Examples: http://narkoz.github.io/gitlab/usage
Original: http://d.hatena.ne.jp/yuum3/20140529/1401330812
Unityの移動量の変化について

Unityにおいて一人称3Dゲームとしてキャラクターを動かす場合、
便利なコンポーネントが用意されている。   
CharacterのFPS Input Controllerだ。  
これはコンポーネントを組み込んだキャラクターをカメラの視点方向に合わせて
WASDキーによる移動ができるようになるというものだ。  
![140608_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/405e8827-a24f-ed8a-dff4-dfeca930f141.jpeg)
  
上記の画像で言うと
Wキーで青方向前方に、Sキーで青方向後方に、
ADキーでそれぞれ赤方向左右に移動できる。
  
・・・と、ここまでだけなら非常に便利なコンポーネントなのだが
これにはひとつ注意すべきことがある。  
    
それは **忠実すぎるほど向いてる方向に合わせて移動する** ということだ。  
![140608_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/438ab2ec-6fce-04aa-be45-61ac1b5fa7bc.jpeg)
  
これはどういうことかというと、上画像のように視点先が平行であれば特に問題ないのだが
下の地面を見ながらWキーで移動すると **地面にめりこむような移動を行おうとする。**   
実際は物理演算のお陰で地面にめり込むことはないのだが
その分前方向への移動量が下画像のように黄色の分だけになってしまう。  
![140608_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/23aca0df-0884-acdc-32e2-5693e4982e6f.jpeg)  

地面の上を走る分にはわかりづらいが、ジャンプして移動などすると非常にわかりやすい。  
      
また、マウスによるキャラクターの視点先移動を使用せず
視点固定のままでFPS Input Controllerを使用した場合は症状が出ないため気づきにくい。  

対策についてはFPS Input Controller.jsの中のソースをいじるしかない。
初期コードはjavascriptなので各自自分の使う種類のコードに自己変換すること。  

```js
// 視点の方向角に移動量(WASD)をかけることでXYZのそれぞれの移動量を算出
motor.inputMoveDirection = transform.rotation * directionVector;
```

初期状態では上記のような感じだが、ここを以下のようにする。  

```js
// 画面の中心を割り出し、そこから奥へ光線を飛ばす。
var centerPoint = Vector3(Screen.width/2, Screen.height/2, 0);
var ray = Camera.main.ScreenPointToRay(centerPoint);
// rayの変数に格納した視点先への角度ベクトルを
// yの方向ベクトルを0にすることでXZだけの水平の値にする。
var rot = Vector3(ray.direction.x, 0, ray.direction.z);
// そのままだと使えないので正規化(合算移動値が1になるように修正)する。
rot.Normalize();

// 上下角を水平にした視点先角度をクォータニオンに変換
var resultRot = Quaternion.LookRotation(rot);
// 視点方向に左右されない正しい移動量を代入
motor.inputMoveDirection = resultRot * directionVector;
```

![140608_04.jpg](https://qiita-image-store.s3.amazonaws.com/0/46039/99625562-6ea5-60eb-80e0-bc0569819eef.jpeg)


上記の画像は元の視点先角度(黄色線)を水平に修正したもの(赤線)  
  
宇宙空間や空中のようにどの方向にも進める場合は変更の必要はないが
陸の上を動く場合は注意が必要である。
RPMパッケージのCHANGELOGを確認する


# 確認方法

CHANGELOGの確認方法（YUMでインストールしたものも含まれます）

```
rpm -q --changelog パッケージ名 | head -n 30
```

OpenSSLの例：

```
rpm -q --changelog openssl | head -n 30
```

# 経緯

なんでパッケージのCHANGELOGの確認方法なんか調べていたのか。

[Heartbleed](http://heartbleed.com/)バグに引き続き、先日またOpenSSLに[CCS](http://jvn.jp/jp/JVN61247051/)バグが発見されたため緊急対応を行いました。
AWSのサーバーと[DigitalOcean](https://www.digitalocean.com/?refcode=1253632a31d5)のサーバーの対応が必要でした。

**openssl-1.0.1h** がfixedバージョンでありAWSの方はこのバージョンをインストールできました。

```
* 木  6月 05 2014 Ben Cressey <bcressey@amazon.com>
- rebase to upstream 1.0.1h

* 火  6月 03 2014 Ben Cressey <bcressey@amazon.com>
- add upstream fixes

* 水  4月 09 2014 Cristian Gafton <gafton@amazon.com>
- rebase to upstream v1.0.1g

* 月  4月 07 2014 Ben Cressey <bcressey@amazon.com>
- use dlopen with libssl for FIPS verification
```

[DigitalOcean](https://www.digitalocean.com/?refcode=1253632a31d5)の方はというと、公式リポジトリにあるのは **openssl-1.0.1e-16.14** でした。
おや？と思い、とりあえず更新をインストールしてからCHANGELOGを確認した結果がこちら↓

```
* 月  6月 02 2014 Tomáš Mráz <tmraz@redhat.com> 1.0.1e-16.14
- fix CVE-2010-5298 - possible use of memory after free
- fix CVE-2014-0195 - buffer overflow via invalid DTLS fragment
- fix CVE-2014-0198 - possible NULL pointer dereference
- fix CVE-2014-0221 - DoS from invalid DTLS handshake packet
- fix CVE-2014-0224 - SSL/TLS MITM vulnerability
- fix CVE-2014-3470 - client-side DoS when using anonymous ECDH

* 月  4月 07 2014 Tomáš Mráz <tmraz@redhat.com> 1.0.1e-16.7
- fix CVE-2014-0160 - information disclosure in TLS heartbeat extension

* 火  1月 07 2014 Tomáš Mráz <tmraz@redhat.com> 1.0.1e-16.4
- fix CVE-2013-4353 - Invalid TLS handshake crash
```

バージョン番号は違うけどきちんとパッチは当たっているようです。
google先生で、```CVE-2014-0224``` を検索して内容を確認したところやはりこれで問題ないようです。

# 結論

ソフトウェアのベースが同じでも管理が異なれば必ずしもバージョン番号が一致するとは限りません。
AWSのようにリポジトリを自社で管理しているような場合は特にですね。

セキュリティー対策のためのパッケージアップデートは必須の作業ですが、
アップデートしたパッケージが正しく問題を解決するバージョンであるかを正確に確認することも
併せて重要な作業だとおもいます。

サーバーをセキュアに保つためにも更新後のCHANGELOGを確認する癖は身に付けておくべきですね。
（と、自分に言い聞かせているｗｗ）

参考：
http://blog.jicoman.info/2014/04/openssl_heartbleed/

# おまけ

古いキャッシュを掃除してから更新するのが正しいお作法のようです。



```
sudo yum check-update ;
sudo yum clean all ;
sudo yum update openssl ;
```
変数のconst宣言

変数のconst宣言

C++メモ

###変数 と const宣言
```c++
const int val=100; // データ(const)
val         = 100; // Error
```

###ポインタ変数 と const宣言
```c++
  int        val0 = 100;
  int        val1 = 200;
  const int *pval = &val0; // ポインタ(非const),データ(const)
  // int const *pval = &val0; // （↑↑↑同じ意味↑↑）

  cout << *pval << endl; // 100

  // *pval = 300; // Error
  pval  = &val1;  // OK

  cout <<  val0 << endl; // 100
  cout << *pval << endl; // 200
```

```c++
  int         val0 = 100;
  int         val1 = 200;
  int * const pval = &val0;  // ポインタ(const),データ(非const)

  cout << *pval << endl; // 100

  *pval = val1;     // OK
  // pval  = &val1; // Error

  cout <<  val0 << endl; // 200
  cout <<  val1 << endl; // 200
  cout << *pval << endl; // 200
```

```c++
  int         val0 = 100;
  int         val1 = 200;
  const int * const pval = &val0; // ポインタ(const),データ(const)

  cout << *pval << endl; // 100

  // *pval = val1;   // Error
  //  pval = &val1;  // Error

  cout <<  val0 << endl; // 100
  cout <<  val1 << endl; // 200
  cout << *pval << endl; // 100
```

###参照変数 と const宣言
```c++
  int        val0 = 100;
  const int &rval = val0; // 参照(const), データ(非const)
  // int const  &rval = val0;  // (↑↑↑同じ意味↑↑）

  cout << val0 << endl; // 100

  //rVal = 300; // Error
  val0 = 400; // OK

  cout << val0 << endl; // 400 
  cout << rval << endl; // 400
```
In App Billing V3の実購入テストで「購入しようとしたアイテムが見つかりませんでした。」が表示される場合の対応方法


Androidのアプリ内課金で、今まで問題なかった購入テストがいつのタイミングなのか「購入しようとしたアイテムが見つかりませんでした。」と表示されるようになっていました。

![0b2680f5-3a52-db4d-7945-47fe7a11d479.png](https://qiita-image-store.s3.amazonaws.com/0/4593/354c7056-ea5f-c7b4-a31d-b6517cf1b39d.png "0b2680f5-3a52-db4d-7945-47fe7a11d479.png")


## 原因

結論からいうと、「Google PlayでAPKがドラフト版状態にあるとテストが出来ない！」ということでした。

Androidの公式ドキュメントでもそのような記載を見つけました。

>Draft Apps are No Longer Supported
http://developer.android.com/google/play/billing/billing_testing.html#draft_apps

## 対応法

対応方法はAPKをベータ版かアルファ版に移行して、公開できるようにメタ情報やスクリーンショット、価格などをすべて埋めて公開します。

ベータ版の公開方法については下記がとても詳しいです。

> Google playでのベータ版配布機能について
http://qiita.com/kaa/items/3904845d225d40f9a6ef

公開にする際は製品版にAPKが上がっていると、Google Playに一般公開されてしまうので注意が必要です。確実にベータ版などに移行されているのを確認してからにしましょう。

---

さていったい、この仕様変更はいつ頃からなのでしょうか。
2014年5月の上旬は間違いなく購入テストが可能だったんですよね。

この原因がわからずかなりの時間を費やしてしまいました。はじめからAndroidの公式ドキュメントに目を通しておけばこんなことにならない
ものを。。

もし同じような悩みの人がございましたら、参考にしていただけると幸いです。
WordPressの日本語オンラインヘルプ(Codex)の編集の始め方メモ

#Codexって？
WordPressの公式マニュアルの名称。

- [英語版](http://codex.wordpress.org/)
- [日本語版](http://wpdocs.sourceforge.jp/)

アカウントを取得すれば、誰でも編集することが可能。

#準備
##日本語版のアカウントを取得する 
[こちら](http://wpdocs.sourceforge.jp/Codex:WordPress_Codex_%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%89%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6#.E3.83.AD.E3.82.B0.E3.82.A4.E3.83.B3.E3.82.A2.E3.82.AB.E3.82.A6.E3.83.B3.E3.83.88.E5.8F.96.E5.BE.97.E6.96.B9.E6.B3.95)に記載されているメールアドレス宛にメールを送って、アカウントを作ってもらう。
ちなみに、こちらの登録作業は人力でやられているようなので、メールを送ってから登録されるまでには、それなりに時間がかかる場合があるようです。ご注意を。

##英語版のアカウントを取得する
[こちら](https://wordpress.org/support/register.php)のフォームから、登録を行います。こちらは、上記の日本語版とは異なりコンピュータ処理により発行されているので、基本的にはすぐ取得することができるようです。

#編集

基本はWikiなので、編集画面を開いてテキスト編集して、プレビューして、保存すればOK。（このとき **編集内容の要約** を忘れずに書く事！）

もっと詳しい情報は、[こちら](http://wpdocs.sourceforge.jp/%E3%83%98%E3%83%AB%E3%83%97:%E7%B7%A8%E9%9B%86%E6%A1%88%E5%86%85#.E7.B7.A8.E9.9B.86.E6.96.B9.E6.B3.95)

#何から手を付けて良いものやら…

1. Codexのページの中で、カテゴリが[未翻訳](http://wpdocs.osdn.jp/%E3%82%AB%E3%83%86%E3%82%B4%E3%83%AA:%E6%9C%AA%E7%BF%BB%E8%A8%B3)となっているものの中から、自分でもわかりそうな部分を探す。
2. 編集画面にして、1セクション、最低1文でも良いので翻訳して、保存する。（このとき **編集内容の要約** を忘れずに書く事！）

#ステップアップ

既存のページを部分的に翻訳していくのに慣れたら、次のレベルへステップアップしてみましょう。

## 【ちょっとムズい】英語版にあって日本語版にないページを新規作成する
## 【かなりムズい】英語版のページが、日本語版のページより新しくなっているので、合わせる
## 【激ムズ】翻訳途中のページの、英語版がより新しい版になっている
基本的に、翻訳途中のページは扱いずらいので、なんとか頑張って一旦全部翻訳した、という状態にするように頑張るべきなのかなと思います。


#用語集

翻訳時の表記（サーバー？サーバ？）で迷った時には、下記を参考にしましょう。

* [Glossary for Japanese translation of Development](https://translate.wordpress.org/projects/wp/dev/ja/default/glossary)

#参考リンク
* http://www.tama200x.com/blog/?p=2260
WebブラウザーでGroongaを試してみた

## はじめに

最近、ブラウザー上でGroongaを試せるようになりました。
（Groongaとは、国産の参照ロックフリーな全文検索エンジンです）

Groonga - カラムストア機能付き全文検索エンジン
http://groonga.org/ja/

<blockquote class="twitter-tweet" lang="ja"><p>ブラウザー上でGroongaを試せるWebアプリケーションを作ったよー <a href="http://t.co/LGBkXQ57fd">http://t.co/LGBkXQ57fd</a> だれか、デザインを、頼む。。。 ソース: <a href="https://t.co/rmcFaZoXW1">https://t.co/rmcFaZoXW1</a></p>&mdash; す (@ktou) <a href="https://twitter.com/ktou/statuses/475289493868527616">2014, 6月 7</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

Try Groonga
http://try-groonga.herokuapp.com/

ソースコード
https://github.com/groonga/heroku-try-groonga

Heroku上で動いているようなので、GroongaをHerokuで動かせるんですね。
ユーザーインターフェイスにはJQueryTerminalを使っているようです。

JQuery Terminal Emulator Plugin
http://terminal.jcubic.pl/

## 実際にやってみる

早速、Groongaのチュートリアルを見ながら試してみることにします。

[4. チュートリアル - Groongaドキュメント](http://groonga.org/ja/docs/tutorial.html)

Webページを開いた時点で対話モードに入っていて、データベースは作成済みなので、
「4.1.4. 主なコマンド」あたりから実行してみます。

[4.1.4. 主なコマンド - Groongaドキュメント](http://groonga.org/ja/docs/tutorial/introduction.html#basic-commands)

まずは`status`コマンドを実行してみます。

![try-groonga-status.png](https://qiita-image-store.s3.amazonaws.com/0/17743/e30aa0a9-8c54-4ad5-26e0-13185afa62c7.png)

JSON形式で、バージョン番号などが表示されました。
最初の配列がHEADERで、次のオブジェクトがBODYですね。

* HEADER

        [
          0,
          1402204651.05869,
          0.000166893005371094
        ],

* BODY

        {
          "alloc_count": 138,
          "starttime": 1402204651,
          "uptime": 0,
          "version": "4.0.2",
          "n_queries": 0,
          "cache_hit_rate": 0,
          "command_version": 1,
          "default_command_version": 1,
          "max_command_version": 2
        }

出力形式の詳細はドキュメントに書いてあります。

[8.3.2. 出力形式 - Groongaドキュメント](http://groonga.org/ja/docs/reference/command/output_format.html)

次に、`table_list`コマンドを実行してみます。

![try-groonga-table_list.png](https://qiita-image-store.s3.amazonaws.com/0/17743/eba00996-cc20-9246-0d94-649912dbc54d.png)

画面が見切れてしまいましたが、PageUp/PageDownキーでスクロールできます。

※2014/07/20追記: ユーザーさんの[pull request](https://github.com/groonga/heroku-try-groonga/pull/1)により、マウスホイールでのスクロールがサポートされました！

## おわりに

こんな感じで、気軽にチュートリアルなどを試すことができます。
私は普段、Ruby経由（Rroonga）やSQL経由（Mroonga）でGroongaを
使っているので、コマンドでの操作は逆に新鮮で楽しかったです。

それでは、ぐるーん、ｶﾞｯ（挨拶