OmniAICreator/Qiita-1.07M huggingface dataset:
enzymeでReactのテストをしてみた

## enzymeとは

airbnbが開発したReactのテストを行うためのライブラリです。
[https://github.com/airbnb/enzyme](https://github.com/airbnb/enzyme)

なんとこのライブラリ、Reactのドキュメントに 「airbnbの作ったやつがあってこっちの方が簡単だよ」 的なことが書いてあるんですよ（冒頭のNoteの部分）
=> [Test Utilities](https://facebook.github.io/react/docs/test-utils.html)

特徴は `react-addons-test-utils` 等を使わずに簡潔に __shallow render__ と __assert__ が出来るといったところです。

shallow render はテスト対象のcomponentのみを実際に走らせてrenderし、
入れ子になっているcomponentについてはmockを代わりにrenderする仕組みのようです。

assertについてはjQueryのようなセレクタを使ってReactのcomponentツリーを検索出来るところが特徴です。

[Installation](https://github.com/airbnb/enzyme#installation) のセクションを読めばすぐに導入できます。

## 試してみた

jestと併用して試してみました。

```js
import React from "react"; // 直接使わないけどこれがないとエラーしました
import { shallow } from "enzyme";
jest.unmock("../components/hoge");
import Hoge from "../components/hoge";
import Foo from "../components/foo";

describe("Hoge", () => {
  it("render foo", () => {
    const wrapper = shallow(<Hoge />); // ShallowWrapperというオブジェクトが返る
    // findするとここでもShallowWrapperが返り、Fooが存在する数がlengthに入っている
    expect(wrapper.find(Foo).length).toBe(1); 
    // jquery的なクラス名の検索も出来る
    expect(wrapper.find(".bar").length).toBe(1);
  });
});
```

findに失敗してもとにかく `ShallowWrapper` が返り、lengthで存在確認をするのはjQuery感がありますね。
たまにcomponentクラスをfindに渡しても検索に失敗することがあったので、文字列で `"Foo"` などと渡してみると成功しました。
この成功時と失敗時の実装の違いはまだ特定できていません。

```js
// これがうまくいかないときは
expect(wrapper.find(Foo).length).toBe(1);
// これで通った
expect(wrapper.find("Foo").length).toBe(1);
```

ただ、いちいちテスト対象ではないFooをimportするのもめんどいし、全部文字列検索でいいかなと思いました。

## Shallow WrapperオブジェクトのAPI

色々あるので便利に使えそうです
[https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md](https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md)

## まとめ

facebookの用意したテストライブラリより簡潔に書けて、assertも簡単に出来るのでおすすめです。
しばらくはこれを使おうと思います。

## 追記

2016-11-01 `react-addons-test-utils` をテストファイルでimportしていなかったので `devDependencies` からも削除したところテスト実行時にエラーしてしまいました。enzymeが内部で使っているので `devDependencies` に入れておく必要があるみたいです。
Heroku 運用検討

*この記事は編集中で、随時更新しています。

本記事では、WebサービスをHerokuで運用するときの運用コストなどを、サービス運営者向けにまとめています。

# サービス体系/料金プラン

Herokuでは、Dynoと呼ばれる単位ごとに料金を従量課金制で支払うことになっています。1 Dynoとは、説明は省略しますがざっくり言うと「サーバー1台分」のようなものだと思ってください。なので、例えばひとつのwebサービスを運用しようと思うなら、最低でもサーバー1台必要なので、1 Dyno分の料金をその使用量に応じて支払うと言うことになります。以下に、現行のDyno1台に対して1ヶ月まるまる使用したときにかかる料金(表内では/dyno/monthと記載しています)とDynoの性能を、料金プランごとにまとめました。日割りでかかかる料金は各値を30で割ったくらいの値になります。

||Free|Hobby|Standard (1xと2xがある)|performance (MとLがある)|
|:--|:--|:--|:--|:--|
|料金|無料|$7/dyno/month|1x: \$25/dyno/month<br>2x: $50/dyno/month|M: \$250/dyno/month<br>L: $500/dyno/month|
|プロセスタイプ|2個|10個|制限なし|制限なし
|常時起動|30分間アクセスがないとsleep|O|O|O|
|スケールアウト|X|X|O|O|
|メモリ(RAM)|512MB|512MB|1x: 512MB<br>2x: 1GB|M: 2.5GB<br>L: 14GB
([ref][Heroku/pricing])

* Standard 1xまでは、1 Dynoに割り当てられるメモリは512MB

## 無料枠は全アプリケーション合計で月1000時間まで

現在(2016/06/01-)の料金体系では、Freeプランだと**1アカウントあたりすべてのアプリケーションやアドオンを含めて**1000時間までが無料枠となります(<a href=#free>ref</a>)。なので、例えば開発環境用と本番環境用で2つDynoを稼働していて、さらにnewrelicのアドオンを使用していると、その3つの使用時間の合計が1000時間になるまでが無料となります。よって、例えばwebアプリケーションを運用していてひと月常時稼働させようとすると、まず本番環境用のDynoだけで

* 24時間 x 30(日) = 720時間

ぶんを消費します。またFreeプランで常時稼働するためには上記の表にある30分sleep制限を回避するスクリプトなどを含める必要があるので、それもHerokuで設定するとすると(もちろん自前でも設定できます)**Freeプランで常時稼働サービスを作るとするとざっくり1環境分までなら運用可能**ということになります。

# アドオンの料金プラン
Herokuでは通常の料金プランで利用できるサービスに加えてアドオンを追加することでサービスの機能を拡張することができます。アドオンには有料のものと無料のものがありますが、運用の際に導入を検討する可能性が高そうなアドオンの概要と料金プランを以下にまとめます。

## SSL

Herokuで公開したアプリケーションには、デフォルトで`https://xxxxx.herokuapp.com/`というURLが割り当てられ、そこからアプリケーションにアクセスします。このURLは先頭が(`http`でなく)`https`となっていますが、これは説明は省略しますがざっくり言うと「安全な」通信が行なわれるということを意味します。しかし実際にサービスを運用するときには、このデフォルトのURLではなく独自に他サービスで取得したドメインを使うのが普通です。Herokuでは独自のドメインさえ持っていれば、どの料金プランでも無料でデフォルトのURLから独自の`http`で始まるURLに置き換えて公開することが可能ですが、SSLアドオンを利用することで、**Hobby以上の有料プランであれば`https`で始まる独自URLも無料で設定することができます** (<a href=#ssl>ref</a>)。



# 開発者向け
* Herokuへのデプロイはslug 200 MGまで
    * .slugignoreにデプロイ対象外ファイルを指定できる
* レスポンスは30秒タイムアウト(変更不可能)
* Pumaウェブサーバー&Railsアプリケーションをデプロイするときの設定関連の参考ページ
    * https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server



# 履歴
<a name=ssl /> [2016/09/22] 全有料プランでSSL利用が無料に。[SSL Is Now Included on All Paid Dynos](https://blog.heroku.com/ssl-is-now-included-on-all-paid-dynos)
<a name=free />[2016/06/01] 無料枠が全アプリケーション合計で月1000時間までに変更。[Announcing Heroku Free SSL Beta and Flexible Dyno Hours](https://blog.heroku.com/announcing_heroku_free_ssl_beta_and_flexible_dyno_hours)

[Heroku/pricing]: https://www.heroku.com/pricing
他サーバーへのファイルコピー

サーバーのバックアップ設定をしたときのメモ

### 環境
CentOS7

ファイルのコピーには`scp`,`rsync`コマンドを使う

```bash
scp file_or_direcotry username@servername.com:upload_direcotry/
```
鍵認証の場合は鍵ファイルを指定すればよいが、
パスワード認証の場合はパスワード入力が自動化しにくい。
`sshpass`を使うとお手軽

```bash
sshpass -p 'passwooooooooord' scp file_or_direcotry username@servername.com:upload_direcotry/
```
MacにAWS DynamoDB localを入れてRails runnerからアクセスしてみる

DynamoDBがローカルで実行できるらしいので開発用に試してみた。

# ダウンロード・展開
```terminal
wget http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.zip #ダウンロード
unzip dynamodb_local_latest.zip #展開
```

# 起動
```terminal
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb #デフォルトだとPort8000で起動
```

# 接続

```terminal
# aws cliがインストールされていれば、endpointを指定するだけで使える
local$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "test"
    ]
}

```

# Railsから使う
runnerでやってみた。
※Rails 4.2.6

```ruby:Gemfile
#SDKをGemで追加
gem 'aws-sdk'
```

```ruby:lib/tasks/dynamo.rb
gem 'aws-sdk-core'

class Tasks::Dynamo
  def self.execute
    dynamo = Aws::DynamoDB::Client.new(
        endpoint: 'http://localhost:8000' #ローカルに対して
    )

    options = {
        table_name: "products",
        attribute_definitions: [
            {
                attribute_name: "product_code",
                attribute_type: "S"
            }
        ],
        key_schema: [
            {
                attribute_name: "product_code",
                key_type: "HASH"
            }
        ],
        provisioned_throughput: {
            read_capacity_units:  1,
            write_capacity_units:  1
        }
    }

    dynamo.create_table(options) #Table作成

    p dynamo.describe_table({table_name: "products"}) #テーブル情報取得
  end
end
```

```terminal
local$ rails runner "Tasks::Dynamo.execute"
Running via Spring preloader in process 6438
#<struct Aws::DynamoDB::Types::DescribeTableOutput table=#<struct Aws::DynamoDB::Types::TableDescription attribute_definitions=[#<struct Aws::DynamoDB::Types::AttributeDefinition attribute_name="product_code", attribute_type="S">], table_name="products", key_schema=[#<struct Aws::DynamoDB::Types::KeySchemaElement attribute_name="product_code", key_type="HASH">], table_status="ACTIVE", creation_date_time=2016-10-31 08:20:37 +0000, provisioned_throughput=#<struct Aws::DynamoDB::Types::ProvisionedThroughputDescription last_increase_date_time=1970-01-01 00:00:00 +0000, last_decrease_date_time=1970-01-01 00:00:00 +0000, number_of_decreases_today=0, read_capacity_units=1, write_capacity_units=1>, table_size_bytes=0, item_count=0, table_arn="arn:aws:dynamodb:ddblocal:000000000000:table/products", local_secondary_indexes=nil, global_secondary_indexes=nil, stream_specification=nil, latest_stream_label=nil, latest_stream_arn=nil>>

```
無事表示された。
GitHub カンニング・ペーパー > 気になった事項 (訳について)

GitHub カンニング・ペーパー を読んでいて気になった事項。

こういう指摘の方法が不明。
pull requestすることになるのだろうか。
Qiitaの編集リクエスト機能があれば便利なのに。

少数の人が見る資料なら看過するところだが、非常に多くの人が目を通す資料となると、一見で見つかるような違和感は少ない方がいいように思われる。

### 空白の無視

https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.ja.md#%E7%A9%BA%E7%99%BD%E3%81%AE%E7%84%A1%E8%A6%96

> GitHub上で差分ページを表示している時、そのURLに?w=1を加えると、<font color=red>空白の変化によるできた差分</font>は表示されなくなり、コード上の変化だけを参照することができる。

１文字による違和感「による」「により」。違和感がないのは以下だろう。

> GitHub上で差分ページを表示している時、そのURLに?w=1を加えると、<font color=red>空白の変化によりできた差分</font>は表示されなくなり、コード上の変化だけを参照することができる。

### ブランチ同士の比較

https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.ja.md#ブランチ同士の比較

> https://github.com/{user}/{repo}/compare/{range}
>{range}をmaster...4-1-stableに変更する。
>
>例えば:
>
>https://github.com/rails/rails/compare/master...4-1-stable

上記が読みにくいのは、フォーマットが明示された後に「に変更する」という部分。
「に変更する」主体は何なのか (システムなのか, ユーザなのか?)が読みにくい。

原文は以下なので、上記の訳になるのは仕方がないかもしれない。

https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.md#comparing-branches

> https://github.com/{user}/{repo}/compare/{range}
> Where {range} = master...4-1-stable
>
>For example:
>
>https://github.com/rails/rails/compare/master...4-1-stable

ここで伝えたいことは以下だと思う。

> https://github.com/{user}/{repo}/compare/{range}
>
>For example:
> Where {range} = master...4-1-stable
>
>https://github.com/rails/rails/compare/master...4-1-stable

この場合、日本語はこのようになる。

> https://github.com/{user}/{repo}/compare/{range}
>
>例えば:
>{range}をmaster...4-1-stableにすると以下となる。
>
>https://github.com/rails/rails/compare/master...4-1-stable

### ブランチ同士の比較

https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.ja.md#ブランチ同士の比較

> {range}には以下のように変更することもできる:

は以下が読みやすいだろう。

> {range}は以下のようにすることもできる:

### フォークされたリポジトリ間でのブランチ比較

> Gists can be treated as a repository so they can be cloned like any other:

上記の対応訳が以下になっている。

> 簡単なものとはいえ、Gitリポジトリとして機能するため、以下のようにすれば普通のGitリポジトリと同じようにクローンすることができる:

主語(Gist)が省略されていたり、修飾節(「簡単なものとはいえ、」)が付加されていたりする。
また、英語に合わせて文章を長く訳しているため読みにくい。

自分だったら以下のように訳すだろう。

> Gistはリポジトリのように扱うことができる。そのため、他のgitリポジトリと同様にcloneできる。


### フォークされたリポジトリ間でのブランチ比較

> This means you also can modify and push updates to Gists:

なぜか英語の文章がそのまま残っている。

自分だったら以下のように訳すだろう。

> つまり、Gistsに対して修正や更新のプッシュもできる。


ここまで。

今後は英語版を読み進めることにした。

CSSのeasing関数のgithub(ページは失念)でも見たように、日本人がいない中での日本語訳かもしれない。
和訳サービスを利用したのだろうか?
serverlessとlambdaで時刻に正確なbotをパッと作る


表題の通りです。

## なんで今更自前でbot作るんだよ

最近はある程度の定型発言をするだけなら[便利なサービス](http://twittbot.net)があります。



私の大好きなbotの一つである[田舎の昼のサイレンbot](https://twitter.com/noon_siren_bot)もtwittbotを利用して運用されています。

ですが上記のサイレンbotはサイレンという __ちょうど__ を伝えるべきであるのに大体は12:04くらいにサイレンが鳴ります（多分サーバの時計が微妙にずれてるとかだとは思います）。このことが許せないので自分で12時ちょうどに発言するbotを作りました。
（サイレンbot自体は大好きです、大切なことなので二度言います）


## 成果物
同じサイレンじゃつまらないかなと思ったので別のを作りました。[12時に鳴くルビィちゃんbot @noon_pigii_bot](https://twitter.com/noon_pigii_bot) です。12時ちょうどにピギィと鳴きます。多少のズレは許してください。

ルビィちゃんかわいいですよね。


ソースも置いておきます。
https://github.com/celeron1ghz/twitter-bot-pigii

## 実装
最近の世の中は便利で、こういうちょっとしたスクリプトを動かすのに良いlambdaと言うサービスがありますのでちゃっちゃと作ります。


### serverless
ちょっと前に正式版になった [serverless](https://serverless.com) を使います。
使い方はほんと簡単で

1. `Administrator Access`権限があるユーザのkeyとsecretを `~/.aws/credentials` なり `.envrc` なりに設定する
2. `sls create -t aws-nodejs`
3. `sls deploy`

だけでHello Worldは動いてしまいます。すごい。ほんとロジックを書くことに集中できる感じです。
設定に書けばscheduled eventも設定してくれる、ちょうべんり。

### scheduled eventがズレる問題
今回悩んだのはscheduled eventは指定時間ちょうどに発火してくれることを保証していないということです。なので2分前に起動してちょうどになるまでsleepするという泥臭い方法を取りました。今のところはscheduled eventsの発火は遅れても1分くらいなので大丈夫かなという感じですが、lambdaはタイムアウトの最大が5分なので遅れが広がるようなら要調整。まぁ詳しくはソースをみてください。

忘れちゃいけないのはscheduled eventsの時刻はUTCなのでcronの指定は9時間ずらすことくらいでしょうか。


## まとめ
lambdaは月ごとに無料枠が湧いてくるサービスなので、serverlessも便利ですし、もっとこういうクソみたいなコードをたくさん書くべきだと思います。
awspecでEC2のIAM Roleをテストする


awspecでEC2に割り当てられているIAM Roleをテストしたいときの話です。

https://github.com/k1LoW/awspec/blob/master/doc/resource_types.md#ec2

ここを見ると、`its(:iam_instance_profile)`というのがあります。例えばEC2-Roleというロールが割り当てられるていることをテストしたいとき、これを使って、

```
describe ec2('instance_name') do
  its(:iam_instance_profile) { should match /EC2-Role$/ }
end
```

とやると、

```
  1) ec2 'instance_name' iam_instance_profile should match /EC2-Role$/
     Failure/Error: its(:iam_instance_profile) { should match /EC2-Role$/ }

       expected #<struct Aws::EC2::Types::IamInstanceProfile arn="arn:aws:iam::xxxxxxxxxxx:instance-profile/EC2-Role", id="AIPAXXXXXXXXXXXXXX"> to match /EC2-Role$/
       Diff:
       @@ -1,2 +1,2 @@
       -/EC2-Role$/
       +"#<struct Aws::EC2::Types::IamInstanceProfile arn=\"arn:aws:iam::xxxxxxxxxxxxx:instance-profile/EC2-Role\", id=\"AIPAXXXXXXXXXXXXXX\">"
```

こんなエラーになり正しく動きません。
`its(:iam_instance_profile)`は`Aws::EC2::Types::IamInstanceProfile`を返すみたいなので、そのまま文字列比較はできないようです。

正しい書き方は分かりませんが、[ここ](https://github.com/k1LoW/awspec/blob/master/doc/resource_types.md#unlock-advanced-use-2)を見ると、[Aws::EC2::Instance](http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Instance.html)のリソースが使えるとのことなので、

```
describe ec2('instance_name') do
  its('iam_instance_profile.arn') { should match /EC2-Role$/ }
end
```

と書けばテストできました。

```
ec2 'instance_name'
  iam_instance_profile.arn
    should match /EC2-Role$/
```
ArduinoIDEのシリアルプロッタで2個以上のデータを表示させる

# ArduinoIDEのシリアルプロッタってご存じですか？
Arduino 1.6.6 あたりでつかされた機能だそうで、数字をシリアルで流すと、そのグラフを書いてくれる機能です。グラフのスケールもある程度自動的に変更してくれるので、とりあえずセンサーで計測した数字をリアルタイムに見たいって時にとても便利！

こんな感じにグラフが表示されます。
![シリアルプロット１つ.png](https://qiita-image-store.s3.amazonaws.com/0/77002/ab0f5292-4cdb-e0b4-b815-bc0ad7eb83ea.png)

# 1個のデータのグラフを書く方法

簡単でシリアル通信で「数字（改行）」を送るだけです。たとえばこんなスケッチです。
このスケッチで、先のグラフを描いています。

```C++:serial-plot1.ino
double angle = 0;

void setup() {
  Serial.begin(250000);
}

void loop() {
  angle++;
  Serial.print(sin(angle / 180 * PI));
  Serial.println("");
  delay(50);
}
```

Arduino UNOに書き込んで、「ツール」→「シリアルプロッタ」を選択します。
![serialプロッタ.png](https://qiita-image-store.s3.amazonaws.com/0/77002/567f7542-c6dd-e30e-58d9-7796b262361c.png)

![シリアルプロット１つ.png](https://qiita-image-store.s3.amazonaws.com/0/77002/ab0f5292-4cdb-e0b4-b815-bc0ad7eb83ea.png)

# 2個のデータのグラフを書く方法
```C++:serial-plot2.ino
double angle = 0;

void setup() {
  Serial.begin(250000);
}

void loop() {
  angle++;
  Serial.print(sin(angle / 180 * PI));
  Serial.print(",");
  Serial.print(sin(angle + 30 / 180 * PI));
  Serial.println("");
  delay(50);
}
```

こんな感じで、カンマ区切りでデータを送信すると・・・
![シリアルプロット２つ.png](https://qiita-image-store.s3.amazonaws.com/0/77002/42f5d372-60e0-fe86-d4dd-a20a2a0b8f19.png)

2つのグラフが同時に書けます。
右上にある凡例？は左から順に色が割り振られています。
第1項目：青
第2項目：オレンジ


# もうおわかりでしょうが、3個のデータのグラフを書く方法
```C++:serial-plot3.ino
double angle = 0;

void setup() {
  Serial.begin(250000);
}

void loop() {
  angle++;
  Serial.print(sin(angle / 180 * PI));
  Serial.print(",");
  Serial.print(sin(angle + 30 / 180 * PI));
  Serial.print(",");
  Serial.print(2 * cos(angle  / 180 * PI));
  Serial.println("");
  delay(50);
}
```
![シリアルプロット３つ.png](https://qiita-image-store.s3.amazonaws.com/0/77002/1c26a2c6-fb5d-bfaa-10ee-cf9eae00a2ae.png)

こんな感じで、3つめの項目が赤色でプロットされています。

Y軸のスケールが一つしかないことに注意が必要ですが（1万付近をウロチョロするデータと、0付近をウロチョロするデータを一緒に書くと直線にしか見えないとか・・・）、簡単にセンサーの値を確認することができたりしますので是非活用してはいかがでしょうか。

最後まで読んでいただき、ありがとうございました。
PHP 電卓作成

■入力画面

```php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xm1ns="http://www.w3.org/1999/xhtml">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript">


	<title>PHP入門</title>

</head>
<body>

	<form action="test05_output.php" method="post">
		<p>
			<textarea rows="1" cols="2" name="area1"></textarea>
			+<input type="radio" name="calculate" value="plus"> -<input
				type="radio" name="calculate" value="minus"> ÷<input type="radio"
					name="calculate" value="divide"> ×<input type="radio"
						name="calculate" value="multiply">

			<textarea rows="1" cols="2" name="area2"></textarea>

		</p>

		<input type="submit" value="送信">

</body>
</html>
```

■結果画面

```php
<?php
$area1 = $_POST ["area1"];
$area2 = $_POST ["area2"];
$calculation = $_POST ["calculate"];
switch ($calculation) {
	case "plus" :
		$calculation = $area1 + $area2;
		break;
	case "minus" :
		$calculation = $area1 - $area2;
		break;
	case "divide" :
		$calculation = $area1 / $area2;
		break;
	default :
		$calculation = $area1 * $area2;
		break;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xm1ns="http://www.w3.org/1999/xhtml">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript">


	<title>PHP入門</title>

</head>
<body>
<?php echo $calculation;?>

</body>
</html>
```

■実行結果
![電卓input.png](https://qiita-image-store.s3.amazonaws.com/0/95187/fc68b06e-14d9-43d9-800a-bdb3edfe4459.png)
![電卓output.png](https://qiita-image-store.s3.amazonaws.com/0/95187/6a2ef128-c1cd-28c4-a42b-07f084d6c0c7.png)
Laravel Blade拡張

# はじめに

+ Laravel5.3

Bladeの拡張メソッドの追加方法
デフォルトで用意されている下記のようなメソッドは簡単位追加することが可能。

```
@if(true)
@elseif
@endif
```

公式ドキュメントを見ると```directive```メソッドと呼ばれるもので拡張を行うとある。

https://readouble.com/laravel/5.3/ja/blade.html#extending-blade

公式の拡張例では下記のようなコードとなっておりBladeテンプレート内で```@datetime($datetime)```のような形で渡すことで```'m/d/Y H:i'```のようなフォーマットにしてくれるメソッドを追加している。

```
次の例は@datetime($var)ディレクティブを作成し、渡されるDateTimeインスタンスの$varをフォーマットします。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * サービスの初期起動後に登録する
     *
     * @return void
     */
    public function boot()
    {
        Blade::directive('datetime', function($expression) {
            return "<?php echo $expression->format('m/d/Y H:i'); ?>";
        });
    }

    /**
     * コンテナへ結合を登録する
     *
     * @return void
     */
    public function register()
    {
        //
    }
}
```

他にも条件式のようなメソッドを追加することも可能で実際に```@if```の中身をみてみると

```:Illuminate\View\Compilers\BladeCompiler
    /**
     * Compile the if statements into valid PHP.
     *
     * @param  string  $expression
     * @return string
     */
    protected function compileIf($expression)
    {
        return "<?php if{$expression}: ?>";
    }
```

このようになっており、条件式を渡すだけとなっている。

# ログイン状況返却の追加

これを自分だけの条件式にすることも可能で例えばログイン状況やログイン名について返却したい場合下記のように追加することが可能となっている。
このメソッド時代はViewが呼ばれる前に追加しておけばBlade内で参照することが可能で、今回のようなAuthを使用する場合は共通コントローラに記載することが可能となっている。

```
        Blade::directive('ifauth', function() {
            return "<?php if(\Auth::check()): ?>";
        });

        Blade::directive('authname', function() {
            return "<?php echo \Auth::user()->name; ?>";
        });
```

これをBladeで呼び出す場合

```
@ifauth
  @authname
@else
  ゲスト
@endif
```
というように呼び出すことが可能。
ちなみに```@else```や```@endif```は特に追加する必要はなく共通して使用することが可能。
これは単純にphpのelseとendifを使用しているため。

```:Illuminate\View\Compilers\BladeCompiler

    protected function compileElse($expression)
    {
        return '<?php else: ?>';
    }

    protected function compileEndif($expression)
    {
        return '<?php endif; ?>';
    }
```

# まとめ
Bladeテンプレートにはできるだけロジックは書かない方が綺麗なソースになりそう。
共通な処理はできるだけメソッド化して呼び出すのが読みやすいソースを作ることになる。

# 参考
https://readouble.com/laravel/5.3/ja/blade.html#extending-blade
ShoCard の TRAVEL IDENTITY OF THE FUTURE メモ

TRAVEL IDENTITY OF THE FUTURE https://shocard.com/downloads/ の資料のメモです。

# Traveler Experience Overview

## Registration Detail Flow
1. 旅行者が旅行者用アプリをインストールすると、デバイスに鍵ペアと ShocardID が作成される
1. パスポートを写真に撮ってスキャンする
2. 顔写真を撮る
1. これらをシール化(ハッシュ化・署名・結合)してブロックチェーンに記録する
1. 旅行者アプリからエージェントに、パスポート情報と顔写真情報を QR コードで渡す
1. エージェント A はパスポートとパスポート情報、顔と顔写真を比較する
1. エージェント A は airline server に証明書とトラベルトークン作成のリクエストを送る
1. airline server は証明書とトラベルトークンを作成して、ShocardID と顔写真と共にブロックチェーンに記録する

## Verification Defail Flow
1. 旅行者は旅行者用アプリで新しいQRコードを作成する
    - EnvelopeID (ShoStore server にある secure envelope を指し示す)
    - 共通鍵 (secure envelope のために作られた)
1. envelop からデータを取得し、共通鍵を使用して復号する
1. データを元に検証する
1. 旅行者の顔と顔写真を照らし合わせて検証する

# ShoCard Specific Terminology

## Enveloping
- 二者間でプライベートデータが共有されていることを示す
- 互いに暗号化・署名されていることを意味する
- Envelope は To と From のキーのセットと、ハッシュ化・署名化されたデータを使う
    - From の秘密鍵でハッシュしたものを署名
    - To の公開鍵で暗号化
- Envelope はデータ交換の手段を提供する
    - From からのものかを証明されている
    - To にしか読めない
- もし Envelope を作成した時に To が分からない場合は、To の公開鍵で暗号化する代わりに、共通鍵で暗号化が可能
    - その場合は envelope を見せるときに、From は To に共通鍵を渡す必要がある
- To と From の両方が、同じ鍵を使って構築することも可能
    - 片方が、もう片方に、いくつかのデータを後で渡したいと思っている場合
    - この場合、片方がデータを保持しているときは、もう片方はデータの参照や変更はできない

## Sealing
- Sealing はデータセットのハッシュと、秘密鍵を使った署名で、ブロックチェーンに書き込まれる
- これは後で検証するためのデータとしての記録を提供する
    - もしこのデータが変更されたら、ハッシュはマッチしない
- Sealed Record はネームとバリューのフィールドを含み、バリューはハッシュ化・署名されている
- 解釈: 自分を示すもの

## Certification
- B が A からプライベートデータを受け取るとき、データの正確性を検証し、検証されたことを示すレコードを書き込むこと
- Certification Record にはブロックチェーン上の A の Seal へのリファレンスと、検証・証明された特定のフィールドが含まれる
- 後で証明者は、Seal でデータを比較することによって、ユーザデータが同一であることを確認できる
- また、A の Seal データ以上の追加データを Certification Record に書き込むことが可能
    - 例えば、rating, status, biometrics, token
- 解釈: 自分を示す Seal を証明するもの

## Public key repository
- ShoCardID と公開鍵を紐付けて登録する
- 公開鍵は ShoCard service を通じてShareされる
- ShoCard service においては、公開鍵のShareに制限を課すかもしれない

## Share
- A が B との個人識別情報を共有しようとしていることを示す
- 個人識別情報はいつでも共有される
    - プライバシと信頼性のために、A と B のキーセットを使って常に envelop される
- B の公開鍵を知らない場合は、A によって署名され、共通鍵を使って暗号化が可能
本番DBをダンプしてローカルにインポートを手作業でやっていたので、シェルスクリプトを書いてみました

# ニーズと、概要

ときどき、ローカルのDBが古くなってきたせいで、サイトに表示されるコンテンツが空っぽになって寂しくなったりします。
そんなときに、僕は本番DBから該当テーブルのデータを取ってきて、ローカルにインポートをしていたりしました。

けど、その手動作業に飽きてきたので、シェルスクリプトを書いてみました。（シェルスクリプトを書いたの初めてで、少し怯えています。）
全テーブルをダンプとかすると、すごいことになりそうだったので、引数にテーブル名を一つ引数にとるスクリプトにしてみました。

# 使い方の前に ※ 注意事項 :construction_worker:

- pg_dumpは、いっぱいデータあると排他制御入るので、アクセスが少なく、かつそんなに大量データじゃないとき限定で使用した方がよいです！（cf. [pg_dumpでサーバが停止してしまう](http://ja.stackoverflow.com/questions/14822/pg-dump%E3%81%A7%E3%82%B5%E3%83%BC%E3%83%90%E3%81%8C%E5%81%9C%E6%AD%A2%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86))
- 本番のデータを引っ張ってくるので、個人情報の扱いにはお気をつけください！


# 使い方 :bike:

シェルファイル名が `update_table.sh` だとしますと以下のように使います。（postsテーブルがあったとして）

```bash
sh update_table.sh posts
```

このように、ローカルでコマンドを打つことで、本番環境の該当テーブルをダンプして一旦保存して、それをローカル（Vagrantの中）でImportさせます。


# シェルスクリプト


PostgreSQLです。


```bash:update_table.sh
#!/bin/sh

if [ $# != 1 ]; then
  echo "テーブル名をひとつ引数としてわたしてください (ex: sh update_table.sh posts)"
fi
TABLE_NAME=$1

TODAY=$(date "+%Y%m%d")
DUMP_FILE_NAME="/tmp/${TODAY}_${TABLE_NAME}.dump"

# Production config
SERVER="{SERVER}"
HOST="{HOST}"
USER_NAME="{USER}"
DATABASE="{DB}"
PASSWD="{PASSWD}"

# Local config
LOCAL="{LOCAL}"
LOCAL_USER_NAME="{LOCAL_USER}"
LOCAL_DATABASE="{LOCAL_DB}"
LOCAL_PASSWD="{LOCAL_PW}"


echo "Connect to server..."
ssh $SERVER <<HERE
pg_dump -U $USER_NAME -d $DATABASE  -h $HOST  -t $TABLE_NAME -c > $DUMP_FILE_NAME
$PASSWD
HERE
# できればテーブルが存在しなかった場合、コマンドを停止させたかったのですが....できてない...

echo "Connect to local..."
ssh -A $LOCAL <<HERE
scp $SERVER:$DUMP_FILE_NAME $DUMP_FILE_NAME
PGPASSWORD=${LOCAL_PASSWD} psql -U $LOCAL_USER_NAME -d $LOCAL_DATABASE < $DUMP_FILE_NAME
rm -f $DUMP_FILE_NAME
HERE

echo "Connect to server..."
ssh $SERVER <<HERE
rm -f $DUMP_FILE_NAME
HERE
```

以上です。:bow::thought_balloon:
Preztoのおせっかい機能を除去する

# 目的

Preztoが用意するZshの設定は概ね悪くないのだが、（私にとっては）いらいらするおせっかい設定が混じっているので、これを除去する。「他にもこの機能はおせっかいだ」などあればコメントで教えてほしい。

# 方法

Preztoが用意する設定は `~/.zprezto/modules` 以下に配置される各モジュールで定義されている。ここから目的の設定を見つけ出し、コメントアウトなどで対処することにする（本当は`.zpreztorc`などで上書きしたいのだが、多重にエイリアスが貼られていたりするので`unalias`でなく不要部分だけのコメントアウトを選んだ）。

# 具体的な対処
## いちいち `rm` が削除確認をしてくる

`rm`コマンドでファイルを削除する際、本当に削除していいかどうかをインタラクティブに尋ねてくる。
これは`modules/utility/init.zsh` で定義されている`rm`コマンドに対するエイリアスによる。`-i`オプションを常に付与するようにエイリアスされているので、これを除去する。

```name:modules/utility/init.zsh
# alias rm="${aliases[rm]:-rm} -i"
```

## リダイレクトでファイルを上書き・追記できない

`>` または `>>` でファイルに書き込む際、そのファイルが既に存在している場合は拒否される(かわりに`>!`や`>>!`を使う必要がある)。
これは`modules/directory/init.zsh`で定義されている`clobber`の設定による。`unsetopt`で`clobber`を無効化しているため、これを除去する。

```name:modules/directory/init.zsh
# unsetopt CLOBBER            # Do not overwrite existing files with > and >>.
```
PHP5.3 系で PEAR の DB ライブラリのインストール

# 概要

PHP5.3 系で PEAR DB インストールの際にエラーが出たので対応メモ。

# 対応内容

インストールコマンド

```
# pear install DB
```

エラー内容

```
WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"
Failed to download pear/PEAR, latest release is version 1.10.0, but it requires PHP version "5.4.0", use "channel://pear.php.net/PEAR-1.10.0" to install
pear/DB requires package "pear/PEAR" (version >= 1.10.0), installed version is 1.9.5
No valid packages found
install failed
```

PHP5.4.0 以上が必要らしいが、上げれない環境だったので、PEAR DB のバージョンを下げてインストールする。

# PEAR DB インストール

**1.9.1**

```
# pear install DB-1.9.1
WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"
Failed to download pear/PEAR, latest release is version 1.10.0, but it requires PHP version "5.4.0", use "channel://pear.php.net/PEAR-1.10.0" to install
pear/DB requires package "pear/PEAR" (version >= 1.10.0), installed version is 1.9.5
No valid packages found
install failed
```

1.9.1 も PHP5.4.0 以上が必要らしい

**1.9.0**

```
# pear install DB-1.9.0
WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"
downloading DB-1.9.0.tgz ...
Starting to download DB-1.9.0.tgz (134,174 bytes)
.............................done: 134,174 bytes
install ok: channel://pear.php.net/DB-1.9.0
```

インストールOK
とことんサーバーレス：概要編

# 概要
最近巷で騒がれているサーバーレス。そのサーバーレスアーキテクチャをAWS上でとことんサーバーレスにこだわって簡単なTODOアプリを作るとどうなるかということを試して行く。

## フロントサイド
CloudFrontとS3でホスティングするReact.js + Relayで構成する

## サーバーサイド
Serverless Frameworkを用いてAPI Gateway + Lambda + DynamoDBを構築・管理しつつ、フロントサイドとGraphQLを用いてリソースのやり取りを行う

![cloudcraft_overview.png](https://qiita-image-store.s3.amazonaws.com/0/34930/4df0e128-1ca8-2073-f589-b51a0a28e9eb.png "cloudcraft_overview.png")


※ この一連の記事は現在未完です。
※ 今後進めるにあたってアーキテクチャが変更になる可能性があります。

# 前提
・AWSの各機能の詳細には触れません。ある程度知識があるのが前提となります。
・React.js単体に関しても詳細には触れません。
・すでにAWSアカウントを取得しているものとします。
・本執筆にはフロント、サーバーサイド共にJavascript ES6を用いていきます。

# 簡単に各用語の紹介

## React.js
Facebookが主導しているJavascriptセントラルな、MVCでいうビューのみの機能を満たしたライブラリ、フレームワーク

https://facebook.github.io/react/

## GraphQL
こちらもFacebookが主導しつつ、RFCのドラフトになっているGraphQLは、クライアント・サーバ間でのデータのやりとりを記述するためのクエリ言語。

http://graphql.org/

## Relay
またまたFacebookが主導している、データドリブンなReactアプリケーションを開発するためのフレームワーク。データのやりとりにGraphQLが用いられている。

https://facebook.github.io/relay/

## Serverless Framework
サーバーレスなアーキテクチャを容易に作成、管理できるフレームワーク・ツール。今回はAWS上で展開していく。

https://serverless.com/

# 次回

[とことんサーバーレス①：Serverless Framework入門編](http://qiita.com/hiroshik1985/items/6d979ff1afb56953b62e)
PostCSSで別ファイルをimportする際の注意点


PostCSS & cssnext環境で別cssファイルで変数を定義してimportして利用しようとして、ハマったので、その注意点を共有します。

## TL;DR
* webpack.config.jsのpostcss()内でpostcss-importを一番最初にrequireする

## ハマった環境
```webpack.config.js
const cssnext = require('postcss-cssnext')
const cssimport = require('postcss-import')

...

postcss() {
  return [cssnext, cssimport] // ここの順序が問題
},

...
```

```colors.css
:root{
  --background-color: #fff;
}
```

```some-component.css
@import 'path/to/colors.css';

.some-component {
  background-color: var(--background-color);
}
```

### 実行結果

```warninglog
variable '--background-color' is undefined and used without a fallback
```

```Styles
.some-component {
  background-color: var(--background-color); // colors.cssで定義した変数が展開されていない
}
```

## 正しい記述例
webpack.config.js内のpostcss()でpostcss-importを最初にrequireする
参考:
https://github.com/MoOx/postcss-cssnext/blob/master/webpack.config.js#L51-L55
https://github.com/css-modules/css-modules/issues/22

```webpack.config.js
const cssnext = require('postcss-cssnext')
const cssimport = require('postcss-import')

...

postcss() {
  return [cssimport, cssnext] // postcss-importを最初にrequireする
},

...
```

### 実行結果
```Styles
.some-component {
  background-color: #fff; // colors.cssで定義した変数が展開されている
}
```

無事に展開されました🎉
ビルドのプロセスを考えると、たしかにimportの展開を先にしないと上手く展開できないですね。
vectorにおける[]演算子とat()の速度を比較してみようメモ

個人的メモです
* 検証方法はガバガバかもしれない。


### vectorの要素にアクセスするには、[]演算子とat()の2通りがある。


* []演算子
* at()


### 一般的には[]演算子の方を使う。

なぜなら、at()はvectorの中のindexを全て見た上で、要素にアクセスするから。
[]は直接その要素にアクセスするので、パフォーマンスこちらの方が良い。
at()はその性質上デバッグする際に便利なので、開発時に使うものとい割り切った方がいいかもしれない。



### 速度比較したら、3倍くらい違った。
[]演算子とat()の速度比較を以下の方法で検証。


#### 検証手順
1. valという100000個のfloat型を用意し、その全てに0を格納。
1. その状態から、100000回0番目の要素にアクセス

```
vector<float> vals;
vals.assign(100000, 0.0);

float start = ofGetElapsedTimef();
    cout << "start:" << start << endl;
    
    for(int i = 0; i < vals.size(); i++)
    {
        vals[0]; //or vals.at(0)
    }
    
    float end = ofGetElapsedTimef();
    cout << "end:" << end << endl;
    span = end - start;
    
    cout << "実行時間:" << span << endl;
```


6回実施した平均の実行速度は以下。

| []演算子 | atメソッド |
|:-----------|------------:|
| 0.044165(ms) | 0.111919(ms) |
sshキーペア作成


ど忘れする時があるのでメモ


```shell-session
$ ssh-keygen -t rsa
```

~/.ssh以下にid_rsa(秘密鍵)、id_rsa.pub(公開鍵)の2ファイルが作成される。

-fオプションを追加してファイル名を指定することが可能。
Photoshopファイルを一括でpngにしたいエンジニア向けの記事

psd(Photoshop)ファイルを大量に受け取ったけど、私はpngが欲しかったのだ…というエンジニアに捧ぐ。
差し戻してもいいんだけどそれだと時間がかかるし、これくらいのことエンジニアなら自分でやりたい、というときは以下の手順でやってみれば、この先もきっと役に立つ時はまた来る。

Photoshopでは、任意の一連の作業を「アクション」として登録することができます
「ファイルを開き、画像サイズを変更し、pngとして保存する」というアクションを作成し、
そのアクションを複数ファイルにまとめて行う、という手順です。
PhotoshopCCです。

1. Photoshopを開く。まだ該当ファイルは開きません
2. ウィンドウ→アクションを選択。アクションウィンドウが開きます
![スクリーンショット 2016-10-31 15.59.20.png](https://qiita-image-store.s3.amazonaws.com/0/98954/9fced1f9-786a-8f36-2d74-25b42e5a45a4.png)

3. アクションウィンドウの下部の「新規アクションを作成」ボタンをクリック。
![スクリーンショット 2016-10-31 16.00.26z.png](https://qiita-image-store.s3.amazonaws.com/0/98954/6ea0c02b-73ca-7448-8778-cfce89edd057.png)

4. アクション名を入力し（ここでは「png化」としておきます）、「記録」ボタンをクリックします。この瞬間から、一連の作業の登録が始まります（アクションウィンドウの録画ボタンが赤くなります）
![スクリーンショット 2016-10-31 16.06.47.png](https://qiita-image-store.s3.amazonaws.com/0/98954/85609833-6566-038a-b381-75cbfb916974.png)

5. 登録したい一連の作業を間違えずに行います。今回は「ファイルを開く」「画像サイズを変更する」「pngで保存する」の3つの作業を行います。

6. 完了したら、アクションウィンドウの「録画停止ボタン」を押します。こんな感じにアクションが登録されてればオーケーです。無事にアクションが作れました。
![スクリーンショット 2016-10-31 16.05.39.png](https://qiita-image-store.s3.amazonaws.com/0/98954/6bc3a862-a882-1604-757b-0ac56b331667.png)

7. では、登録されたアクションを使います。「ファイル→自動処理→ドロップレットを作成」を選択します
![スクリーンショット 2016-10-31 15.12.56.png](https://qiita-image-store.s3.amazonaws.com/0/98954/5b8ed497-0c66-30d0-a94e-a347b335457a.png)

8. 以下のよう画面になります。
    - 「ドロップレットを保存」
        - この一連のアクションをドロップレットファイルとして保存します。保存場所を指定します。（ドロップレット… ドラッグ＆ドロップで使用出来るアプレット？）
    - 「実行」
        - セットとアクションから、先ほど作ったアクションを選択します。また、今回は「"開く"コマンドを無視」にチェックを入れます。 
    - 「実行後」
        - 今回はpngに変換した結果を新しいファイルとして保存するわけなので、「フォルダー」を選択し、保存先を指定します。また、「"別名で保存"コマンドを省略」にチェックを入れます。今回は複数ファイルの一括変換をするアクションなので、開くファイルや保存先のファイルの指定を毎回手で指定したり、ファイル名を固定にしておくことができないので、このような対応になります。ちなみに今回の場合、保存時のファイル名は元ファイルと同じになります（拡張子だけpsd->pngになります）。法則を指定することも可能。見ればわかると思います
![スクリーンショット 2016-10-31 15.16.29z.png](https://qiita-image-store.s3.amazonaws.com/0/98954/4d7a7544-33bd-91a2-87d4-882a7f4f2837.png)
12. 「OK」をクリック。ドロップレットが作成されているのを確認します
![スクリーンショット 2016-10-31 16.28.11.png](https://qiita-image-store.s3.amazonaws.com/0/98954/3ff7ff49-9f38-6b61-acfb-d283934fa314.png)

13. あとは、このpsd_to_png.app に　psdファイルをドカッとドロップしてやれば、Photoshopが頑張って全部pngにしてくれます！

### これでまた一つ、グラフィックでやきもきしなくて良くなりました
Wercker で使う Docker コンテナを更新するときの手順

# 前置き

Wercker は Docker コンテナの中で CI をするサービスで、とりあえずビルドに必要な環境が整った Docker イメージがあれば、あとは Wercker が勝手にイメージを引っ張ってきてコンテナを立ち上げて指示通りビルドをしてくれるため、公式ドキュメントにはない Android アプリのビルドも可能です。

ビルドに必要な環境はすべて Docker イメージにまとめて放り込んでしまえるので、SDK の更新があったときに CI サービス側の対応を待たなくとも、自分でイメージを作り直すだけで環境を最新に保つことができる点が魅力ですが、裏を返せば自分で環境をメンテナンスしなくてはならないという面倒臭さがあります。

とは言え、CI サービス側が環境を用意してくれる場合でも、自分で環境をメンテナンスする場合でも、環境が新しくなってもビルドが壊れないことの確認は最低限する必要があることに変わりありません。そう考えると、自分で環境のメンテナンスをするほうが、環境のポータビリティに歩があり、新しい環境でのビルドのチェックもし易いような気がします（CIサービス側が環境を用意してくれる場合、sshでビルドサーバに繋いで状況を確認することができればさほど違いはないかもしれませんが）。

# 更新時の手順

## 1. Docker イメージをビルドする

何を置いてもまずは Docker イメージをビルドします。

Android アプリのためのビルド環境の場合で、かつ Dockerfile でイメージを構築している場合、Support Repository や Google Repository のアップデートなど、Dockerfile に記述する手順に変更のない更新が稀によくあります。Dockerfile の変更がないとキャッシュを使ってビルドしてしまうため、この条件に当てはまる場合は、キャッシュを使わずにビルドしたり、キャッシュをパージしてビルドしたりする必要があります。

キャッシュを使わずに新しくイメージをビルドする場合は

```shell-session:command

$ docker build -no-cache -t image_name:tag .
```

キャッシュをパージする場合は

```shell-session:command

$ docker rm $(docker ps -a -q)
$ docker rmi $(docker images -q)
$ docker build -t image_name:tag .
```

でイメージをビルドします。古いイメージを残す必要がなければ、毎回キャッシュをパージしてしまったほうがディスクスペースの節約になります。

## 2. Docker コンテナを立ち上げてアプリをビルドする

イメージのビルドが終わったら、コンテナに入って新しい環境でアプリがビルドできるかを確認します。

```shell-session:command

$ docker run -it image_name:tag /bin/bash
# 
```

イメージの中には GitHub 用の ssh 鍵がない場合も多いでしょう。その場合は、GitHub の Personal Access Token を使って認証します(Personal Access Token の取得は、GitHub の設定画面からできます)。`git clone`後に聞かれるユーザ名は GitHub のユーザ名、パスワードに Personal Access Token を設定します。

```shell-session:command

# git clone https://github.com/Hoge/fuga.git
Username for 'https://github.com': YourName
Password for 'https://github.com': YourPersonalAccessToken
```

あとはクローンできたらいつものコマンド(wercker.ymlにある手順)を叩くだけです。

## 3. docker push

確認が終わったら忘れずにプッシュしましょう。

DockerHub でイメージのリビジョン管理をする場合、タグを活用するとよいです。常に latest にしてしまうと、アプリでブランチを分けたあとでイメージが更新されたときに、そのブランチの CI も最新イメージで実行されるため、何もしていないのに急にビルドが壊れる恐れがあります。

何をタグとして用いるかは難しいものですが、Dockerfile を git 等で管理する場合は、どのコミットの時点でビルドしたのかを表せるようハッシュ値をタグに設定する方法が考えられます。ただしこれだけだと、前述したような Dockerfile の変更を伴わない更新に対応できません。素直に support-rep-38 とかどのリビジョンのリポジトリが含まれているかをタグに書くなどしましょう。

# さいごに

Wercker はいいぞ
CarthageでModule compiled with Swift * cannot be imported in Swift *の対処法

## TL;DR
`carthage update --no-use-binaries`を使おう

## エラー内容
SwiftyJSONをimportした時のエラー
Module compiled with Swift 3.0 cannot be imported in Swift 3.0.1

## なぜ起こるのか
そもそも`carthage update`で何をしているかというと、[SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON)を例にすると、

```:cartfile
github "SwiftyJSON/SwiftyJSON"
```
このように書いて
`$ carthage update`
でgithubのSwiftyJSONを持ってくる

しかし、carthageのbootstrapやupdateは取ってくる先にビルド済のバイナリがあった場合、それを持ってきて展開してしまう
だからswift3.0でコンパイルされているSwiftyJSONがimportされてしまっている

## 対処法
carthageの`--no-use-binaries`を使ってあげると、バイナリではなくソースコードを持ってきてこちら側でビルドしてくれる
時間はかかるようになってしまうが、これでエラーが解消される
シェルスクリプトで日付と文字列を結合する

たとえば、今日が20161031だとして、

article_2016103.txt

という文字列をシェルスクリプトで生成する方法です。

```bash
today=$(date "+%Y%m%d")
echo "article_${today}.txt"
# => article_20161031.txt
```

または、以下のようにも書けるけど、`$` の方を使う方が良いらしい。

```bash
today=`date "+%Y%m%d"`
echo "article_${today}.txt"
# => article_20161031.txt
```

おわり。 :thought_balloon:
Proxy 支配下で FreeBSD をネットワークインストールする

HTTP Proxy を通さなければ HTTP で外に出ることができない環境下における，bootonly イメージを用いた FreeBSD のインストール方法です．

Linux の netinst メディアでは途中で HTTP Proxy を設定する画面が出てくるので良いのですが，FreeBSD は 2016 年 10 月末時点の最新版である 11.0 でも Proxy の設定画面は出てきません．

FreeBSD の Proxy 配下でのネットワークインストールは Google 先生に聞いてもなかなか出てこないので，備忘録代わりに書き残します．


# 考え方

`http_proxy` を設定した状態で `bsdinstall` を叩きます．


# 手順

## まずはブート

ここでは `< Shell >` を選びます．

![Screenshot_freebsd11_2016-10-31_15:22:53.png](https://qiita-image-store.s3.amazonaws.com/0/5837/6ede0fe9-4421-d8a0-9f67-853de285ab7e.png)


## IP アドレスの設定

`ifconfig` コマンドで設定するなり，DHCP 環境であれば `dhclient` で設定します．

 ![Screenshot_freebsd11_2016-10-31_15:23:53.png](https://qiita-image-store.s3.amazonaws.com/0/5837/7fd50ead-14bf-450c-57d8-7373eb1882bb.png)



## DNS / Proxy サーバの設定

DNS キャッシュサーバは通常通り `/etc/resolv.conf` で，Proxy は環境変数 `http_proxy` で設定します．

Proxy の設定は FreeBSD 11.0 の時点では `http_proxy` の設定のみで OK ですが，今後 HTTPS が必要になるかもしれないので例では `https_proxy` も設定しておきます．

なお `https_proxy` を設定することによる害はありません．

![Screenshot_freebsd11_2016-10-31_15:25:05.png](https://qiita-image-store.s3.amazonaws.com/0/5837/ea58ae2d-b29b-2fa4-94d2-df6cad1d7d26.png)


## インストーラ起動

`bsdinstall` になった最近の FreeBSD．昔は `sysinstall` だったのに．

インストーラ起動後は今までどおりの手順でインストールを進めます．

![Screenshot_freebsd11_2016-10-31_15:25:33.png](https://qiita-image-store.s3.amazonaws.com/0/5837/d29477e4-52c3-d007-0f9b-06ebd8ec17d7.png)

![Screenshot_freebsd11_2016-10-31_15:25:48.png](https://qiita-image-store.s3.amazonaws.com/0/5837/753297be-13c9-026a-392f-208d968e2eb8.png)

![Screenshot_freebsd11_2016-10-31_15:26:21.png](https://qiita-image-store.s3.amazonaws.com/0/5837/1362bf1d-ffa2-4ac7-7419-8afb0b4e5568.png)


## インストール完了後，再起動

`shutdown` コマンドなどで再起動します．

![Screenshot_freebsd11_2016-10-31_15:32:47.png](https://qiita-image-store.s3.amazonaws.com/0/5837/607dfbb5-ebad-745c-30b1-59c6721b1278.png)


## インストール完了

ベースシステムのインストールはこれで完了です．あとは Ports などの Proxy の設定などを行ってください．（探せば出てくるので，ここでは扱いません）

![Screenshot_freebsd11_2016-10-31_15:47:22.png](https://qiita-image-store.s3.amazonaws.com/0/5837/b55cebf3-d743-6453-91d7-2ea754207f86.png)
超簡単Laravel5.3ディレクトリ構造

始めまして!いずれ魔法使いになるkahiroです。
基本的に<a href="https://readouble.com/laravel/5.3/ja/structure.html">ReaDouble</a>の記述を引用して、初心者が解るように補足、もしくはリンクを張る感じで軽く解説します！

##目的
今熱いPHPのフレームワーク、Laravel5.3のディレクトリ構造を参考にディレクトリ構造の意味を学ぼうがテーマです！~~超簡単シリーズを作りたくてテーマに無理があるのは内緒~~

##対象読者
1. 何となくフレームワークを使用していて、appディレクトリしか編集した事ない~~私~~人とか！
2. ディレクトリ構造を上手く活用できなくて、汚しちゃう~~私~~人とか！

##プロジェクトディレクトリ一覧
1. appディレクトリ
---
>
appディレクトリは名前の示すとおり、アプリケーションのコアコードを配置します。このフォルダーの詳細は、このあとに説明します。しかし、アプリケーションのほとんど全部のクラスは、このディレクトリの中に設定されることを覚えておいてください。

**注釈：サーバサイドがここ！**

2. bootstrapディレクトリ
---
>
bootstrapフォルダーはフレームワークの初期起動やオートローディングの設定を行うファイルを含んでいます。その中のcacheディレクトリは、初期処理のパフォーマンスを最適化するため、フレームワークが生成するルートやサービスのキャッシュファイルが保存されるフォルダーです。

**理解を足す補足サイト：http://www.weblio.jp/content/bootstrap**

3. Configディレクトリ
---
>
configディレクトリは名前が示す通り、アプリケーションの全設定ファイルが設置されています。全ファイルに目を通し、設定可能なオプションに慣れ親しんでおくのは良い考えでしょう。

**注釈：アプリケーションの環境周りの定数を格納する所って思えばよいです！**

4. databaseディレクトリ
---
>
databaseフォルダーはデータベースのマイグレーションと初期値設定（シーディング）を配置します。ご希望であれば、このファイルをSQLiteデータベースの設置場所としても利用できます。

**注釈：DBのbootstrap見たいな所です！DDLとかを格納する所ですね**

5. publicディレクトリ
---
>
publicディレクトリは、アプリケーションへの全リクエストの入り口となるindex.phpファイルを持っています。また、このディレクトリにはアセット（画像、JavaScript、CSSなど）を配置します。

**注釈：ドキュメントルートですね！皆ここを通ります！**

6. resourcesディレクトリ
---
>
resourcesディレクトリはビューやアセットの元ファイル（LESS、SASS、JavaScript）で構成されています。また、すべての言語ファイルも配置します。

**注釈：フロントサイドがここ！**

7. routesディレクトリ
---
>
routesディレクトリはアプリケーションの全ルート定義により構成されています。デフォルトでは、web.php、api.php、console.phpの３ファイルが含まれています。
>
Web.phpファイルは、RouteServiceProviderのwebミドルウェアグループに属するルートで構成します。このミドルウェアは、セッションステート、CSRF保護、クッキーの暗号化機能を提供しています。もしアプリケーションがステートレスではなく、RESTフルなAPIを提供しないのであれば、すべてのルートはweb.phpファイルの中で定義されることになるでしょう。
>
api.phpファイルは、RouteServiceProviderのapiミドルウェアグループに属するルートで構成します。このミドルウェアはアクセス回数制限を提供しています。このファイル中で定義されるルートは、ステートレスであることを意図しています。つまり、これらのルートを通るアプリケーションに対するリクエストは、セッションステートにアクセスする必要がないように、トークンを使って認証されることを意図しています。
>
console.phpファイルは、クロージャベースの全コンソールコマンドを定義する場所です。それぞれのコマンドのIOメソッドと連携するシンプルなアプローチを提供するコマンドインスタンスと、各クロージャは結合します。厳密に言えば、このファイルはHTTPルートは定義していないのですが、コンソールベースのエントリポイントを定義しているという点で、ルート定義なのです。

注釈：つまり、api.phpにapiのルートを記載して、web.phpはviewへ遷移するルートを記載して、console.phpは結果をconsoleへ表示するルートを記載するんですね！

8. storageディレクトリ
---
>
storageディレクトリにはコンパイルされたBladeテンプレート、ファイルベースのセッション、ファイルキャッシュなど、フレームワークにより生成されるファイルが保存されます。このフォルダーはapp、framework、logsディレクトリに分かれています。appディレクトリはアプリケーションにより生成されるファイルを保存するために利用します。frameworkディレクトリはフレームワークが生成するファイルやキャッシュに利用されます。最後のlogsディレクトリはアプリケーションのログファイルが保存されます。
>
storage/app/publicディレクトリにはプロファイルのアバターなどのようなユーザにより生成され、外部からアクセスされるファイルが保存されます。public/storageがこのディレクトリを指すように、シンボリックリンクを張る必要があります。リンクは、php artisan storage:linkコマンドを使い生成できます。

**注釈：ブログとかで例えるとstorage/app/publicに画像とかを格納すれば良いって事ですね！**

9. testsディレクトリ
---
>
testsディレクトリには皆さんの自動テストを配置します。サンプルのPHPUnitテストが最初に含まれています。各テストクラスはサフィックスとしてTestを付ける必要があります。テストはphpunitか、php vendor/bin/phpunitコマンドにより実行できます。

**注釈：テストコード等をこの中へ配置します！有効に使ってみてください！**

10. vendorディレクトリ
---
>
vendorディレクトリには、Composerによる依存パッケージが配置されます。

**注釈：composerで導入したライブラリ等を格納する場所です！**

##まとめ
良いディレクトリ構造は人を幸せにしますね！

##参考サイト一覧
* https://readouble.com/laravel/5.3/ja/structure.html
* http://www.weblio.jp/content/bootstrap
CSS で背景画像を暗くする + マウスオーバーで明るくする

### まずは背景画像をつける

![スクリーンショット 2016-10-31 15.28.34.png](https://qiita-image-store.s3.amazonaws.com/0/142995/730003d7-14d7-ebea-00fb-9a8ab6223e71.png)


htmlコード

```html
<a href="#">
	<div class="menu">
		<div class="box">
			ここに文章があったり。
		</div>
	</div>
</a>
```

まずはCSSで背景を暗くする

CSSコード


```css
.menu {
	height: 100px;
	background: url(fruits.jpg) center no-repeat;
	background-size: cover;	
	
	position: relative;
	height:100%;
}

.box {
	position: absolute;
	width: 100%;
	top: 45%;

	text-align: center;
  	color: #FFF;
}
```

### 背景画像を暗くする

![スクリーンショット 2016-10-31 15.31.43.png](https://qiita-image-store.s3.amazonaws.com/0/142995/872ae232-db45-935f-f4d1-0a384edf4819.png)

背景を置いた要素にCSSで暗くした要素を追加するイメージ

```css
.menu::before{
	background-color: rgba(0,0,0,0.3);
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	content: ' ';
}
```

### マウスオーバしたら明るくする

![スクリーンショット 2016-10-31 15.37.56.png](https://qiita-image-store.s3.amazonaws.com/0/142995/89c68146-dee5-6302-f136-7cb46027497b.png)

挿入したCSSを明るくするだけ

```css
a:hover .menu::before{
	background-color: rgba(0,0,0,0);
}
```
FilezillaでSSH公開鍵認証を使う方法

## 前書き
Linux, MacでSSH公開鍵認証は導入済みで、ターミナルから接続する際には問題なかった。Filezillaの初期設定では公開鍵認証で接続出来なかったので原因を調べてみると、Filezillaに秘密鍵を設定しないと動かないことがわかったのでメモ書き。Filezillaのバージョンは3.22.1 （Mac）、3.15.0.2 (Ubuntu 16.04)。

## Filezillaに秘密鍵を設定する
### Macの場合
1. メニューバーからFilezilla -> Settings -> Connection -> SFTP で "Add key file..."ボタンをクリック。
2. 秘密鍵を選択する。 ~/.sshなどの隠しディレクトリに保存している場合は"Command + Shift + G"を同時に押してパスを入力できるウィンドウを開いて指定する。
3. ホスト、ユーザー名を指定して接続する。

### Linuxの場合
1. メニューバーの Edit -> Settings -> Connection -> SFTP で "Add key file..."ボタンをクリック。
2. 秘密鍵を選択する。
3. ホスト、ユーザー名を指定して接続する。

## 参考リンク
Filezilla公式: https://filezilla-project.org/
ググってでてきた解決法（英語）: https://wiki.filezilla-project.org/Howto
SSH公開鍵認証の設定方法: http://qiita.com/HamaTech/items/21bb9761f326c4d4aa65
Windows+Apache (OS 64)指定されたネットワーク名は利用できません AH00341 の解決法

コメントを外す。

```Apache24\conf\httpd.conf
Include conf/extra/httpd-mpm.conf
```

下の4行を追加。

```Apache24\conf\extra\httpd-mpm.conf
<IfModule mpm_winnt_module>
    ThreadsPerChild        150
    MaxConnectionsPerChild   0
    AcceptFilter http none 
    AcceptFilter https none 
    EnableSendfile off 
    EnableMMAP off
</IfModule>
```

参考
http://toshy7302104.cocolog-nifty.com/soliloquist/2015/10/apache-win64-c7.html
https://ah-2.com/2015/07/30/apache_win_not_respond.html
ngrepでSIPメッセージを覗き見してみた

SIPメッセージのパケットキャプチャをする必要性にかられて、どうせならテキストでみたいなぁと思ったらngrepとかう便利なツールの存在を知ったので書残す

HTTPとかでも素敵に見られるらしい。インストールは

```shell-session:
# yum install ngrep
```

でOKな幸せな人は

```shell-session:
# ngrep -W byline -d eth0 port 5060
```

とかでいいんだけど

##閉域にいる人は

```shell-session:
# yum install flex bison libpcap libpcap-devel
```

とか流してみて通れば
http://ngrep.sourceforge.net/
からソースコードを落としてきて

```shell-session:
# tar xvf ngrep-1.45.tar.bz2
# cd ngrep-1.45
# ./configure
# make
# make install
```

で幸せになります。

##pcap-develのない人は

```shell-session:
# tar xvf libpcap-1.7.3.tar.gz
# cd libpcap-1.7.3
# ./configure
# make
# make install
```

で、この状態でngrepのconfigureを通そうとすると

```shell-session:
please wipe out all unused pcap installations
```

とか言われて怒られてしまう。
これは

>/usr/local/include/pcap.h
>/usr/local/include/pcap/pcap.h

と二重にpcap.hが存在することが原因で後者が実体、前者は後者をincludeしてるだけなので

前者をmvとかで動かしてあげると

```shell-session:
mv /usr/local/include/pcap.h ./
```

configureが通って晴れてビルドできる。ngrepのインストール後は

```shell-session:
mv ./pcap.h /usr/local/include/pcap.h
```

戻してあげましょう。以上！
AndroidStudioでstyle.xmlのparentを読み込まずにxmlのpreviewがバグる

## 現象

タイトルどおりですが
<img width="798" alt="スクリーンショット 2016-10-31 15.19.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/14262/3d2a8158-2bcd-fff1-13f9-b17329ce1cfe.png">
parentが読み込まれず、xmlのpreviewが正しく読み込まれないようになった。急に(汗

## 発生した環境

- `Android Studio2.2.2`

## 治し方

- `cleanしてBuild`や`File/Invalidate Caches/Restart`してみたけど治らなかった。
- `rm -Rf ~/Library/Caches/AndroidStudio*`で治りました。
Cidr記法からIPアドレスの範囲を算出するロジック

# 前置き

* 個人的メモです。
* ネットワーク知識は薄いので、これで網羅できているかどうか・・・
* もっといい書き方あればご教授頂けると幸いです。

# やりたかったこと

* Cidr記法とIPアドレス単一指定でアクセス者のIPアドレスチェックを行う必要がありました。
* Nodeなので、JavaScriptで書いてやる必要がありました。
* Cidr記法、IPアドレスのフォーマットは守られている前提です。

# 使い方

* `getIpRange()` の引数にIPを渡すと範囲がオブジェクトで返ります。

```javascript
// Cidr記法
var range = getIpRange("192.168.0.0/24");
range // {min: "192.168.0.0", max: "192.168.0.255"}

// IPアドレス指定
var range = getIpRange("192.168.0.0");
range // {min: "192.168.0.0", max: "192.168.0.0"}

// 空
var range = getIpRange("");
range // {min: "", max: ""}

```

# コード

```javascript

/**
 * 10進数表記ののIPアドレスを2進数に変換
 * @params array sample: ['127', '0', '0', '0']
 * @return string sample: 01111111000000000000000000000000
 **/
function convertToBinaryNum(group){
  var ret = "";
  for (var i = 0; i < 4; i++) {
    var bit = "00000000" + parseInt(group[i], 10).toString(2);
    ret += bit.slice(-8);
  }
  return ret;
}

/**
 * 2進数表記ののIPアドレスを10進数に変換
 * @params array sample: 01111111000000000000000000000000
 * @return string sample: 127.0.0.1
 **/
function convertToIp(num){
  var ret = "";
  ret = parseInt(num.slice(0,8), 2) + ".";
  ret += parseInt(num.slice(8,16), 2) + ".";
  ret += parseInt(num.slice(16,24), 2) + ".";
  ret += parseInt(num.slice(24,32), 2);
  return ret;
}

/**
 * IPアドレスの範囲を取得
 **/
function getIpRange(ipAddress){
  var ip = ipAddress.split('/'),
      group = ip[0].split('.'),
      ipBit = "",
      minIpBit = "",
      maxIpBit = "",
      maxAddress = ip[0];
  
  // 入力値が空、IPアドレスをカンマ基準で配列にした際に４つじゃない場合
  // ネットワークのビット数が規定の数値(1~32)じゃない場合
  if ( ip === "" || group.length !== 4 ||
      (ip.length === 2 && String(ip[1]).match(/^([1-9]|[1-2][0-9]|3[0-2])$/) === null ) ) {
    return {min:'', max: ''}; // 空を返す
  }
  
  // 入力されたIPアドレスを2進数表記に変換し保持
  minIpBit = convertToBinaryNum(group);
  
  // IPアドレスのみの場合
  if ( ip.length === 1 ) {
    return {min: minIpBit, max: minIpBit};
  }
  for (var i = 0; i < 4; i++) {
    var bit = parseInt(group[i], 10).toString(2);
    if ( Number(ip[1]) >= ((i+1)*8) ) {
      ipBit += ("00000000" + bit).slice(-8);
    }
    else {
      var tmpIpBit = ("00000000" + bit).slice(-8);
      ipBit += (tmpIpBit.slice(0, Number(ip[1]) - (i*8)) + "11111111").slice(0, 8);
      break;
    }
  }
  maxIpBit = (ipBit + "11111111111111111111111111111111").slice(0, 32);

  return {min: minIpBit, max: maxIpBit};
}
```

[デモ](http://codepen.io/CyberMergina/pen/JRQBBE)

（これでいいのかしら・・・）

# お世話になったサイト様

- [ネットワーク計算ツール](https://www.softel.co.jp/labs/tools/network/)
　⇒算出結果の確認で使わせて頂きました。ありがたや・・・！
Python3 > 関数 > 関数の名前変更メカニズム > f = fib

```
Python 3.5.2ドキュメント
```

http://docs.python.jp/3/tutorial/controlflow.html#defining-functions

> 関数の定義を行うと、関数名は現在のシンボルテーブル内に取り入れられます。関数名の値は、インタプリタからはユーザ定義関数 (user-defined function) として認識される型を持ちます。この値は別の名前に代入して、後にその名前を関数として使うこともできます。これは一般的な名前変更のメカニズムとして働きます:

```py
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
```

fibをfとして定義して使用している。
エイリアスのようなものだろうか。
これまで経験してきた言語ではこういうのはなかったような気がする。

`def`では意味が分かりやすい関数名にして、ちょっとした処理の時は短縮名にする、という使い方はできそう。
Google Apps Scriptで指定したフォルダへ直接スプレッドシートを作成する

# 概要

本投稿では、Google Apps Script (GAS)を使ってGoogle Drive APIで直接指定したフォルダへスプレッドシートを作成する方法についてご紹介します。

これまでGASを用いてスプレッドシートを作成しようとするとき、基本はSpreadsheetAppクラスを利用していました。この場合、DriveAppのようにフォルダ指定でのファイル作成ができないため、スプレッドシートを指定したフォルダへ作成しようとすると、一度ルートへ作成した後に指定したフォルダへ移動させ、ルートにあるスプレッドシートを消去するという操作を行います。すなわち、下記のようになっています。

- SpreadsheetAppはスプレッドシートを作成することはできますが、ファイル操作はできません。

- DriveAppはファイル操作はできますが、スプレッドシートを作成することはできません。

上記のため、SpreadsheetAppとDriveAppの両方を使用した方法を使っていました。DriveAppにはファイル作成時のmimeTypeとして「GOOGLE_SHEETS」というものがあるのですが、”Google MIME の作成に「DriveApp.createFile()」は使用できません。高度な Advanced Drive サービスをご利用ください。”　とのエラーが発生してしまいます。ここで止まっていました。

丁度時間ができましたので「高度な Advanced Drive」とともに他に直接作成する方法はないかといろいろ探していましたところ、Drive APIに当たりました。Drive APIは主に外部からGoogle Driveを使用するためのものとして紹介されていました。これを利用して解決に至りました。

# 手順

GASからDrive APIを利用するためには下記2点の設定が必要です。

1. プロジェクトを開いて、上部の　「リソース」 - 「Googleの拡張サービス」　 - 「Drive API」をONにする。

2. Googleデベロッパーコンソールのライブラリにて　「Google Drive API」　を検索して有効にする。

上記はプロジェクト単位で設定する必要があります。

スプレッドシートを指定したフォルダへ作成するためのスクリプトは下記の通りです。

```gas:
  Drive.Files.insert({
      "title":    ファイル名,
      "mimeType": "application/vnd.google-apps.spreadsheet",
      "parents":  [{"id": フォルダID}]
  });
```

フォルダIDは、ブラウザからフォルダを見たときのURLの　https\://drive.google.com/drive/folders/「この部分」　です。

上記のmimeTypeを変更することでスプレッドシート以外にもいろいろ作成することができます。サポートされているmimeTypeは[こちら](https://developers.google.com/drive/v3/web/mime-types)で確認することができます。


参考サイト
[https://developers.google.com/apps-script/guides/services/advanced#enabling_advanced_services](https://developers.google.com/apps-script/guides/services/advanced#enabling_advanced_services)

# 少し気になった

タイトルに「Google Apps Scriptで指定したフォルダへ直接スプレッドシートを作成する」と書いてしまいましたが、「直接」という表現で問題ないかどうか少し不安です。

# 追記

スプレッドシートを作成した後のアクセス方法について追記します。

スプレッドシートを作成するとオブジェクトとしてその情報が返されますので、その中からファイルidを取得することができます。

```gas:
  var ss = Drive.Files.insert({
      "title":    ファイル名,
      "mimeType": "application/vnd.google-apps.spreadsheet",
      "parents":  [{"id": フォルダID}]
  });

  var sheet = SpreadsheetApp.openById(ss.id);
  SpreadsheetApp.setActiveSpreadsheet(sheet);
```

ファイルidが分かればフォルダ情報は不要になりますので、スプレッドシートへのアクセスはSpreadsheetAppクラスを使って行うことができます。
Python3 > 関数 > シンボルテーブル (symbol table) > 変数への代入 / 変数の参照 / グローバルな変数 / globals() / locals()

```
Python 3.5.2ドキュメント
```

http://docs.python.jp/3/tutorial/controlflow.html#defining-functions

>4.6. 関数を定義する
>...
> 関数を 実行 (execution) するとき、関数のローカル変数のために使われる新たな<font color=red>シンボルテーブル (symbol table)</font> が用意されます。もっと正確にいうと、<font color=blue>関数内で変数への代入</font>を行うと、その値はすべてこのローカルなシンボルテーブルに記憶されます。一方、<font color=blue>変数の参照</font>を行うと、まずローカルなシンボルテーブルが検索され、次にさらに外側の関数のローカルなシンボルテーブルを検索し、その後...

> 従って、関数の中では、グローバルな変数を参照することはできますが、直接値を代入することは (global 文で名前を挙げておかない限り)できません。

シンボルテーブルを意識することによりPython3をうまく使えるかどうかは未消化。

<hr>
(2016/11/01 追記)

@shiracamus さんにコメントにてglobals()とlocals()を教えていただきました。

情報感謝です。