OmniAICreator/Qiita-1.07M huggingface dataset:
テキストボックス実装周りで自分に必要なものまとめ

Webページ作成でJavaScriptを利用することにした。

ひとまずはjQueryで作成していって、
細かい点で対応が利かないことがあればJavaScriptままの実装をしていくつもり。
その他、必要に応じてライブラリを追加していくこととする。

# jQueryを導入する
jsファイルのダウンロードは[こちら](http://jquery.com/download/)

今回私が使用するのは "jquery-3.1.0.min.js" となった。

# ひとまず文字列入力とその利用を試す
ちょこちょこつまみ食いしつつとりあえず書いてみた。
"submit" ボタンを押すと入力値をそのまま表示してくれる。
＃ submitをクリックすることでようやく一つ目がusername用で、二つ目がpassword用とわかる。。

```
<!DOCTYPE html>
<html>
  <head>
    <title>test</title>
    <script type="text/javascript" src="js/jquery-3.1.0.min.js"></script>
    <script type="text/javascript">
      <!-- readyはhtml読み込み後に解釈される -->
      <!-- $(document).ready(function)はjQuery3.0では非推奨との指摘から$(function)に変更 -->
      $(function () {
        $("#submit").click(function () {
          val_userName = "username = "+$("#username").val();
          val_passWord = "password = "+$("#password").val();
          $("#o_uname").text(val_userName);
          $("#o_pword").text(val_passWord);
        })
      })
    </script>
  </head>
  <body>
    <input id="username" type="text" />
    <br>
    <br>
    <input id="password" type="password" />
    <input id="submit" type="button" value="submit" />
    <div id="o_uname"></div>
    <div id="o_pword"></div>
  </body>
</html>
```

# テキストボックスに初期値を置いて入力を促したい
テキストボックスに placeholder という属性を追加して、
初期表示したい文字列を指定するだけで良いみたい。
＃ ただし、HTML5に限る。らしい。

```
    <input id="username" type="text" placeholder="username" />
    <br>
    <br>
    <input id="password" type="password" placeholder="password" />
```

# 入力文字列を暗号化したい
crypto-js を使う。
https://code.google.com/archive/p/crypto-js/

わからん…。
理解したら更新する。

# 参考にしたWebページ
「jQuery日本語リファレンス」
http://semooh.jp/jquery/

「入力ボックスの初期値として薄いグレーの文字を表示する」
http://weback.net/htmlcss/1284/

「JavaScriptでCryptoJSを使って、AESの暗号化と復号を行う」
https://hibara.org/blog/2016/02/15/cryptojs/
Swiftで楽にJSONを扱いたかった話(1)


ずっと後回しにしていたSwiftへの移行。

秋にはiOS10でちゃうし、そろそろやばいなとと思って、あるアプリの一機能をSwiftで書くことにした。

まず、前提として、使っているのは、Xcode7.3。つまりSwiftは2.0。

なんとか見よう見まねで、あるAPIを叩いてJSONを取得するところまではできた。
ここで詰まった。

最初、自前でJSONをParseしようとしてたんだけど、なかなかうまくいかず、Obj-Cだったらサクッと完成するのにSwiftで書いたばっかりに、クソッ！とかいろいろ思ってたら、SwiftyJSONっていうのを使えば、割と楽になるという記事を発見（きっと今更でしょうね。すいません）

http://dev.classmethod.jp/smartphone/iphone/swiftyjson/
http://qiita.com/tsuruchika/items/673665fbec25dab462ed

まさにこれだと。

自前で頑張るのもいいけど、さくっとライブラリを使ってでも前に進みたかったので、迷わずダウンロードしてみる。早速SwiftyJSONを[github](https://github.com/SwiftyJSON/SwiftyJSON)にてダウンロード。

手動でインストールするには、、、、

<pre>
for Projects, just drag SwiftyJSON.swift to the project tree
</pre>


とあったので、SwiftyJSON.swift だけ自分のプロジェクトにDrag&Dropしてみたのですが、

	import SwiftyJSON

楽チンだと思っていたら、こいつがそんなの知らんよってエラーが。
さて、まずはここまで。

この後は、どうなっていくのか、まだ自分でもわかりません。

続き書きました。
[Swiftで楽にJSONを扱いたかった話(2)](http://qiita.com/nmisawa/items/233bc261a3f28bd0aa81)
web開発入門知識

# はじめに
身内向けに勢いで作った資料ですが、他の誰かの役にたてばと思いオープンにしておきます。
Wikipediaに載っているようなことは書かないようにしてます。気になる単語はググって調べてみてください。
言い回しや説明が正確でない可能性が高いので、変だなと思ったら教えてもらえると嬉しいです。

# httpってなに？
Hypertext Transfer Protocol
名前の通りHTMLコンテンツを送受信するプロトコルの１つ。
といいつつ汎用性があって、画像とかバイナリとかいろいろ送れる。
このプロトコルはリクエスト・レスポンス型のプロトコルで、
クライアントがリクエストを投げて、サーバがレスポンスを返す。

## HTTPプロトコル
### httpリクエスト
リクエストはメソッド、URI、HTTPバージョンでできている。
メソッドは「何がしたい」URIは「何を」という感じ。

webブラウザで使われているのメソッドはGETとPOST。
ほかにもメソッドがあるが、あまり使われていない。
HTTPを使用するRESTというアーキテクチャではPUTやDELETEも使う。

#### GET
リソースの取得。
リクエストのURIにパラメータを付加することができる。(URIの文字長上限に注意)
この際にパラメータはURIにそのままつくので簡単に見ることができる。
また、URIは使用できる文字に制限があるためURLエンコーディング(パーセントエンコーディング)を行う必要がある。

#### POST
クライアントからデータの送信。
httpリクエストのボディ部にパラメータを詰めて送信する。
なので、GETとは違い文字列の上限などはない。
また、バイナリデータも送ることができる。

### httpレスポンス
レスポンスは、ステータス、ヘッダ、本体の構成となっている。
ステータスの部分はHTTPバージョン、ステータスコード、メッセージとなっている。
#### ステータスコード
たまにpagenotfoundとかの文言と一緒に表示される400とかの数字がこれ。
100の位で大まかな意味がわかれている。

- 200番台　正常
- 300番台　転送
- 400番台　リクエストのエラー
- 500番台　サーバのエラー

#### 実際に見てみる。
F12キーで開発者メニューを開く。
Networkタブを開いた状態で画面上部の検索機能を使用すると
GETリクエストが一番最初にロギングされているので、クリックすることで内容を確認できる。

手作りHTMLで試すなら以下参照
http://www.kanzaki.com/docs/html/htminfo32.html

## セキュアなhttp通信
上のままだと平文なのでデータが丸見え。
データを暗号化する技術がhttps。これはSSL/TLSでセキュリティを確保した上で行うhttp通信。
SSL/TLSは共通鍵暗号方式＋公開鍵暗号方式による暗号化と電子証明書によるなりすまし対策を行っている。

鍵を使って通信の暗号化と復号化を行い、鍵の正当性を第三者であるCAが発行する証明書によってサーバーが正しい相手かを見ている。（はず

## 連続した通信の継続
### cookie
基本的にhttpでは誰がリクエストを送ってきたかを意識しない。
サーバがクライアントにデータを持たせる方法としてクッキーがある。
これはブラウザがサーバにアクセスする際に毎回クッキーも一緒に送信する。
これでサーバはクライアントの状態を判断することができる。
また、クッキーには有効期限を設定することができる。

### セッション
セッションを使うことでログイン状態などの情報を維持することができる。
方法としては、サーバが今回の通信のセッションIDを発行し、クッキーに設定する。
クライアントが送ってくるクッキーの中のセッションIDをサーバサーバが判断することで連続した処理を継続することができる。

# HTMLとWEBブラウザ
httpリクエストを使って所得したhtmlファイルはブラウザに表示される。
表示されているのhtmlはjsを使用することで操作できる。

## DOM（Document Object Model）
DOMはアプリケーションから利用するためのAPI。
ブラウザではJSでのDOM操作することができる。

### javascript実践
とりあえずjsを試してみる。
管理者メニューでConsoleタブを開く。そうすると最終行に入力ができる。
以下この画面でお試し。

#### お試し
　とりあえずポップアップ

```
alert(1);
```

##### test001
　画面の内容に値を代入

```
document.getElementById("test001").innerHTML="aaa"
```

　画面の内容の一部を取り出してみる

```
alert(document.getElementById("test001").innerHTML);
```

### jQuery
jQueryは便利なjsのフレームワーク。
かなり自由が効くので使いやすいが、自由な分だけ非常に読みにくいソースができやすいので注意が必要。
また、ajaxでの非同期通信が簡単に実装できる。

#### お試し
##### test002
　画面の内容に値を代入

```
$("#test002").text("aaa");
```

　画面の内容の一部を取り出してみる

```
alert($("#test002").text());
```

#### ajax
```
function ajaxTest() {
  $.ajax({
    type: 'GET',
    url: 'http://localhost/test',
    dataType: json,
    success: function(response) {
        alert("通信成功");
        $('#hoge').text(response);
    },
    error: function() {
        alert("エラー");
    },
    complete: function() {
        alert("コンプリート");
    }
  });
}
```
successなどのコールバックの部分に後続の処理を書くことができます。
コールバックの中でも、またajaxの処理も書くことができます。が、ネストが深くなり可読性が落ちやすいです。
これはpromisesというものを使うことで解決できます。
http://sota1235.hatenablog.com/entry/2016/04/12/103246
他の部分でも使うものだと思うので、jsをやるならはpromisesは押さえていたほうが良さそうです。

以下は勉強会でオススメされていたpromisesの資料です。
http://azu.github.io/promises-book/
Grails3.xでCommonsMultipartFileを使うには追加で設定が必要

Grailsでファイルアップローダーを実装するとき、Spring FrameworkのCommonsMultipartFileが便利そうなので使おうとしたけど、ググッた情報だとハマったので対処方法を書く。

https://www.ntts.co.jp/column/tec/java_02/index2.html や http://qiita.com/saba1024/items/aefa65143ff6087111d0 の情報などだと2.xの時は```import org.springframework.web.multipart.commons.CommonsMultipartFile```するだけで使えると書いているけど、これだとビルド時に内部で使われているクラスがないよと怒られた。
エラー内容をググったらcommons-uploadが必要だとわかったのでbuild.gradleのdependenciesに追加する。
2016/08/06時点では1.3.2が最新だったので

```
compile 'commons-fileupload:commons-fileupload:1.3.2'
```

と書いてビルドし直すと通った。
多分3.0以降でSpringベースからSpring Bootベースに変わったせいで読み込みライブラリに変更があったのだろう。
とりあえずビルドはできたので今からちゃんと動作しているか試してみる。
Windows7上(のVirtualbox内)でHortonworks Sandboxのチュートリアルを動かしてみるまで

# 前置き
[前回](http://qiita.com/akikazu_sudou/items/cad15433ea59025a6596)は「**require 64-bit host OS**」って指定されているCDHを32bit環境にぶち込んで大失敗だったので、今回は64bit環境で進めていく所存

まだチュートリアル(を始める前)なので、ふらふらっとHDPに変えてみたよ

いろいろ書いたけど、結論としては[公式のチュートリアルページ](http://jp.hortonworks.com/developers/#tutorials)見て進めればOKという切ない結果に
![screenshot.1470075302.png](https://qiita-image-store.s3.amazonaws.com/0/11348/56be97fe-9586-c444-8dc0-c680e9a3c3b5.png)


でもちょくちょくサイトデザインが変わってて迷子になるからメモは残しておこうね…


# 環境
・Windows 7 (**64bit**)
・メモリ8G
・ご家庭LAN
・VirtualBox：5.0.26


# ブツを揃えましょう！
Windows上に素でインストールするのは結構きついみたいなので、今回も出来合いの仮想環境をもらってくる、と
[Hortonworks Sandbox on a VM](http://jp.hortonworks.com/downloads/#sandbox)
真ん中にある「VIRTUALBOX用ダウンロード」ってのを押すと右側にREGISTER～って出てくるので、いい感じに埋めて「SUBMIT」をポチっ
![screenshot.1470074621.png](https://qiita-image-store.s3.amazonaws.com/0/11348/2aa3db17-20c7-1e2a-833f-3cc1b2b54b11.png)

2016/8/1時点ではHDP2.4が安定版の最新で、2.5がプレビュー版っぽい
8G超のファイルがもりもりやってくるのでじっと待つ
結構空いてそうな時間帯でも10分くらいかかった、日中の混んでる時間はもっとかも

待ってる間はインストールガイドを眺めてました

- VirtualBoxは4.2以降がいるよ
- HostOSはVirtulaBoxが動けばOK。…64bitじゃなくてもいいっぽい？
- ハードウェアは新しければ新しいほど良いみたい
    - 特にCPUは64bitOS使うならそれに見合ったものにしましょう
- RAMは少なくとも8GB必要
    - 実際は仮想環境自身が8GB使うから、Host分も含めると10GBあったほうがいいみたい

と、辞書とにらめっこしながら読んでいるうちにダウンロード終わるので、Virtualboxにインポート
下手にいじると動かないときの原因も調べにくいし、いったん全部デフォルト値で

CPUがアレなせいか、ダウンロードよりインポートのほうが時間かかるんで、また待ち時間

インストールガイド読み進めてくと、インポートの仕方とかもスクリーンショット付きで書いてあって親切設計ですね
RAMはデフォルト8GBだけど良きに計らえって書いてあるので変えちゃって良かったのか…

# VM起動してみましょう！
うちの環境ではRAM8GBのまま起動したら固まったので適当な値にしないといけないのかな
と思ったけど4GBにしても安定のHostMemoryLow祭り…
思い切って1GBまで減らして起動したら30分くらいかかって起動したのでやり遂げた感が凄い

[公式のコミュニティ](https://community.hortonworks.com/questions/35000/hdp-sandbox-startup-too-long-on-virtualbox.html)にも、Zeppelinの起動後に固まるってポストがあって、RAM2GBは少なすぎ、最小8GBだからねって回答されてた
1GBとか論外な扱いじゃないですか…

# チュートリアルページにアクセスアクセス！
VBのコンソールに、ブラウザで127.0.0.1:8888にアクセスしてねって出るので開いてみたところがこちら。なんだけど、1GBの弊害か、ページが見つからないよって言われることが多いのでF5頑張って
![screenshot.1470410821.png](https://qiita-image-store.s3.amazonaws.com/0/11348/1ff3d4dc-a511-070e-3720-3010624f03c2.png)

もちろん英語…ですよねー

たぶん2.tryってところから進めていくんでしょう、続きはまた今度

推奨よりRAM少ないから重たいけど、待ってれば起動するってことがわかったので収穫はあったんじゃないかな
起動の都度30分待ちは片腹痛いと言うか、普通にストレスで腹痛発症しそうなので何かしら考えましょうね
Git使いが突如Subversionのプロジェクトに参加することになったときに必要なコマンド一覧


Macで良いsvnのGUIクライアントがなかったのでコマンドで対応したのですが、Gitととの微妙な違いで混乱しがちだったのでそのときのメモ。

|[command](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/index.html)|メモ|
|:---:|:---:|
|[checkout](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.checkout.html)|`git clone`相当|
|[status](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.status.html)|作業コピーの状態を表示(stageがないので単純に全変更が表示される)|
|[svn st --no-ignore](http://ledyba.org/2011/07/01194902.php)|ignoreしているファイルを表示|
|[update](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.update.html)|`git pull`相当|
|[add](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.add.html)|追加|
|[revert](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.revert.html)|`add`の取り消し|
|[delete](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.delete.html)|ファイルの削除|
|[mkdir](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.mkdir.html)|ディレクトリを作成 + add|
|[import](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.import.html)|`add`+`commit`|
|[commit](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.commit.html)|リポジトリに`add`した反映|
|||
|[propset](http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svn.c.propset.html)|属性|
|propset svn:ignore path|ignore設定をディレクトリに設定する|
|[propset svn:ignore -R -F .svnignore .](http://yanor.net/wiki/?Subversion%2Fsvn%20propset%2Fignoreの除外リストをファイルで管理)|再帰的にignoreを設定する(svnのignoreはディレクトリ単位で設定がされる)|
|[propget -R svn:ignore .](http://tadasy.hateblo.jp/entry/20130129/1359456665)|再帰的にignore設定を表示|
|proplist -v *|全ての属性を一覧で詳細表示|
|||
|add * --force|再帰的に追加/変更されたファイルを`add`する。--forceをつけないとすでにバージョン管理されているディレクトリはスキップされてしまう。|
|||
|[update --set-depth exclude path](http://thinca.hatenablog.com/entry/20091119/1258556832)|対象のディレクトリが消え、以降の`update`操作ではそのディレクトリは一切無視される。|
|[update --set-depth infinity](http://thinca.hatenablog.com/entry/20091119/1258556832)|`--set-depth exclude`を元に戻す|
|||
|svn status --no-ignore|ignore指定されたファイルも表示|

## Tips
	
[subversionで外部ライブラリ(*.a)がコミットできない対処法](http://dorapro.co.jp/iphonedev/?p=359)
CodeIQ「『プライム・ホッパー』問題」に挑戦しました。

[CodeIQ「『プライム・ホッパー』問題」](https://codeiq.jp/q/2821)の掲載期間が終わったということで、自分の提出コードを公開します(´・ω・`)

```rb
require "prime"

# 問題のF(p, q) 
def f(p, q)
    ht = {p => 0} # pから始めてval回目にkeyへ到達した => ht[key] = val
    que = [p]

    # キューが空になるか、目的のqに達するまで幅優先探索を続ける
    until que.empty? || ht[q]
        x = que.shift

        g(x).each do |y|
            next if y > q || ht[y] # 新しく作られた素数がqより大きい or すでに訪問済み

            que << y
            ht[y] = ht[x] + 1
        end
    end
    
    ht[q] ? ht[q] : -1
end

# 素数xが与えられたとき、変換1と変換2を実行して、作られる素数の一覧を返す
def g(x)
    arr = []
    k = Math.log10(x).to_i + 1 # 桁数
   
    # 変換1: 右端もしくは左端に数字を連結する
    (1..9).each{|i| arr << x * 10 + i << i * 10 ** k + x}

    # 変換2: 右端もしくは左端の数字を取り除く
    if x > 10
        arr << x / 10 
        
        # 上2桁目が0でない場合は左端の数字を取り除くことができる
        arr << x % 10 ** (k - 1) if x / 10 ** (k - 2) % 10 != 0
    end
    
    arr.select(&:prime?)
end

# == main ==

p, q = STDIN.gets.split("\s").map(&:to_i)
puts f(p, q)

__END__

基本方針は「幅優先探索」
ある素数から規則通りに素数を作ることを繰り返し、それを目的の素数にたどり着くまで続ける
ただし1度訪れた素数は訪問しないようにする
```

基本的には何の工夫もない解答です……。与えられた規則に基づいて素数を生成し、幅優先探索で目的の素数をひたすら探すだけ。素数判定も標準添付ライブラリを使って、楽をしています。

かなりナイーブな実装でしたが、TLEを起こすこともなく、無事すべてのテストケースが通りましたので、これで良しとしましょう。終わり良ければ総て良し(｀・ω・´)ｼｬｷｰﾝ
RxSwift: UITableViewCellのreuse対策



reuseableなUITableViewで何も考えずにcellのイベントをRxSwift,RxCocoaで取ろうとすると、cell一つひとつが再利用されるたびにRxSwiftのオブジェクトが積み重なっていきます。そのため再利用の際に適切に破棄する必要があります。

### Cell側
```swift:MyCell.swift
import UIKit

class MyCell: UITableViewCell {    
    var disposeBag = DisposeBag()
    let button = UIButton()
.
.
.
    override func prepareForReuse() {
        super.prepareForReuse()
        // 再利用時にdisposeBagに溜まっていたものを破棄
        self.disposeBag = DisposeBag()
    }
}

```

### Table側
```swift:MyTableView.swift
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! MyCell
        cell.button.rx_tap
            .subscribeNext {
                // handle tap event
            }
            // cell側のdisposeBagへ追加
            .addDisposableTo(cell.disposeBag)
        return cell
    }
```

### 確認方法

3秒ごとにRxSwift関連の総オブジェクト数をログに出します。
上記対策をしない場合、Tableのスクロールによってオブジェクト数が増えていくのが分かります。

```swift:MyAppDelegate.swift

let timer = NSTimer.init(timeInterval: 3.0, target: NSBlockOperation.init(block: {
    print("Resource count \(RxSwift.resourceCount)")
}), selector: #selector(NSOperation.main), userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)

```

### 参考
[ReactiveX/RxSwift Invoked multiple times in UITableViewCell #437](https://github.com/ReactiveX/RxSwift/issues/437)
AWS Cognito UserPoolとIdentityを使ったiOSアプリ認証

[awslabsのObjective-Cサンプル](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample/Objective-C)を参考に、Swift版を作りました。

https://github.com/takehilo/CognitoUserPoolSample

![Kobito.GSZHa0.png](https://qiita-image-store.s3.amazonaws.com/0/81715/95996274-fead-8c63-441d-20c1911182e3.png "Kobito.GSZHa0.png")

UserPoolでユーザ認証を行い、UserPoolを認証プロバイダーとしてCognito IdentityでCredentialを取得するという流れです。
UserPoolのおかげで認証サーバすらも実装する必要がなくなり、ますますサーバレスな開発が可能となっています。

## 参考にしたサイト
UserPoolについてはまだあまり記事も多くなく、AWS公式のドキュメントが頼りでした。

http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/tutorial-integrating-user-pools-ios.html

言語はObjective-Cですが、awslabsのサンプルは大変参考になります。

https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample/Objective-C

## アプリ実行方法
1.UserPoolの作成

~~米国東部リージョン(us-east-1)でUserPoolを作成します。先日東京リージョン(ap-northeast-1)も利用可能になりましたが、SDKのバグ？なのか、うまくいきませんでした。~~
AWS SDKのバージョン2.4.5までは米国東部リージョン(us-east-1)がハードコードされていたようで東京リージョン(ap-northeast-1)では動作しなかったのですが、2.4.7にアップデートしてから動作するようになりました。
関連Issueは以下です。
https://github.com/aws/aws-sdk-ios/issues/447

2.IdentityPoolの作成

こちらは東京リージョンで作成します。

3.UserPool、IdentityPoolの情報をアプリに記述

`Constants.swift`に必要な定数をまとめています。ここに情報を記述すればアプリが実行できるようになっています。

```
static let COGNITO_IDENTITY_USER_POOL_ID = "YOUR_USER_POOL_ID"
static let COGNITO_IDENTITY_USER_POOL_APP_CLIENT_ID = "YOUR_USER_POOL_APP_CLIENT_ID"
static let COGNITO_IDENTITY_USER_POOL_APP_CLIENT_SECRET = "YOUR_USER_POOL_APP_CLIENT_SECRET"
static let COGNITO_IDENTITY_USER_POOL_KEY = "CognitoUserPool"
static let COGNITO_IDENTITY_POOL_ID = "YOUR_IDENTITY_POOL_ID"
```

4.依存ライブラリのインストール
 
podコマンドでインストールしましょう。

```
$ pod install
```

## コード解説
簡単にポイントだけ、順を追って説明します。
ちなみにログイン機能しかないので事前にUserPoolにユーザを作成しておく必要があります。。

### WelcomeViewController
本アプリのメイン画面です。`refresh`メソッドでUserPoolとの通信を試みていて、ここでユーザ未認証の場合、ログイン画面が表示されます。
ログイン完了後、Welcome Usernameというメッセージが表示されます。

### AppDelegate
`AWSCognitoIdentityInteractiveAuthenticationDelegate`プロトコルを適用し、`startPasswordAuthentication`メソッドを実装します。

`startPasswordAuthentication`メソッドはユーザが未認証の場合に呼ばれ、`LoginViewController`を起動します。

### LoginViewController
`AWSCognitoIdentityPasswordAuthentication`プロトコルを適用し、`getPasswordAuthenticationDetails:passwordAuthenticationCompletionSource:`と`didCompletePasswordAuthenticationStepWithError:`メソッドを実装します。

`getPasswordAuthenticationDetails:passwordAuthenticationCompletionSource:`メソッドでは、`passwordAuthenticationCompletionSource`を受け取ることができます。このオブジェクトには、UserPoolと通信してログインを行うタスクが格納されています。

このタイミングでログイン画面が表示され、ログインボタンがクリックされると`loginTapped:`メソッドが実行されます。この中で`            self.passwordAuthenticationCompletion?.setResult(result)`として、ログインタスクを実行します。`result`にはログイン画面で取得したユーザ名とパスワードが格納されています。

ログインが完了したら`didCompletePasswordAuthenticationStepWithError:`メソッドが実行されます。ここでは、ログインタスクがエラーであればアラートを表示、ログイン成功ならばログイン画面を閉じるという処理をします。

最後に、WelcomeViewControllerに戻って、ログインしたユーザの名前でWelcome Usernameというメッセージが表示されます。

### AwsClientManager
Cognito周りの処理はこのシングルトンクラスに閉じ込めています。


少しでもみなさんの参考になれば幸いです^^
openFrameworks0.9.~+MadMapper でプロジェクションマッピング

##概要
これはopenFrameworksとMadMapperをSyphonでつなぐためのメモです。
この記事は[oFでsyphonでVDMXする回](http://qiita.com/okawaryota/items/5ed9d975382caf7bfa9b)という記事を参考にして実際にMadMapperとoFを連携させた時に書いたメモです。

##準備
以下の二つをまずダウンロードし、以下のようなフォルダ構成となるようにそれぞれ配置します。

![_Users_hirokinaganuma_Documents_HACK_of_v0.9.2_osx_release_apps_myApps_ofxSyphon_Sample.png](https://qiita-image-store.s3.amazonaws.com/0/56510/cb2911fc-7f61-9c45-3c33-51ff71036197.png)


![_Users_hirokinaganuma_Documents_HACK_of_v0.9.2_osx_release_addons_ofxSyphon.png](https://qiita-image-store.s3.amazonaws.com/0/56510/1b91f6e3-aa2a-b31f-0a92-307baff84ed6.png)


###1. サンプルコード
https://github.com/Hiroki11x/openFrameworksSample/tree/master/ofxSyphon_Sample

###2. ofxSyphon
https://github.com/astellato/ofxSyphon


次にMadMapperをダウンロードします、無料版はメールアドレスの登録だけで使えます。

###3. MadMapper(体験版)
http://www.madmapper.com/


![MadMapper | The Video Mapping Software.png](https://qiita-image-store.s3.amazonaws.com/0/56510/b110dd87-eedf-ae23-c618-bc8ade7e5b8c.png)

![MadMapper | The Video Mapping Software-1.png](https://qiita-image-store.s3.amazonaws.com/0/56510/9985ffe0-f5c7-ef7b-a769-c5dc299b71b2.png)


##確認
実際に、[サンプルコード](https://github.com/Hiroki11x/ofxSyphon_Sample)を動かしてみます。
その際に[oFでsyphonでVDMXする回](http://qiita.com/okawaryota/items/5ed9d975382caf7bfa9b)にある通り、frameworkにsyphon.frameworkを追加されているかなどを確認してください(このサンプルプロジェクトは大丈夫なはず)

動かすと円がビヨビヨーんってなってます。

この[サンプルコード](https://github.com/Hiroki11x/ofxSyphon_Sample)ではすでにその映像がsyphonで通信されていて

MadMapperを開くと

![Demo - MadMapper.png](https://qiita-image-store.s3.amazonaws.com/0/56510/25209c1a-3894-d878-dbba-387e777c870e.png)


こんな感じになっていて、Syphonの通信が正しく行われていれば」ここに出るはずです。

これを


![Demo - MadMapper-1.png](https://qiita-image-store.s3.amazonaws.com/0/56510/79cb09d2-e68e-fd9d-9582-881618cc06f8.png)


このようにクリックすると映像が左の画面にも現れ、

![Demo - MadMapper-2.png](https://qiita-image-store.s3.amazonaws.com/0/56510/d65bf459-bdb0-6f4d-f2a4-433a8961e867.png)


様々なGUIでいろんな操作ができます！
MadMapperの使い方に関しては以下の記事が参考になりました。

・http://blog.livedoor.jp/vdmx5/archives/28803234.html
・http://ameblo.jp/tempdev/entry-11447178418.html

以上となります。
2行でpythonインストール@Windows

# 実行するコマンド

cmdを管理者として開いて、次のコマンドを貼り付け

```sh
@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

# ↑の処理が終わったら↓を貼り付け

choco install -y --execution-timeout=1000000 anaconda3
```


以上！






コマンドの内容は以下で解説する







# 環境

* windows10 64bit(2016年7月windows7からアップグレードした)



# "実行するコマンド"の解説

タネは"chocolatey"と"anaconda".
chocolateyをすでに使っている人は1行目のコマンドはいらない。
**2016年6月からchocolateyでanacondaをインストールできるようになった** のがこの記事を書いたきっかけ。






## 1行目:chocolateyインストール

```sh
@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
```

パッケージマネジャ"chocolatey"のインストール

これをインストールすると、管理者権限で開いたコマンドプロンプト上で

`chocolatey install <パッケージ名>`

これだけでソフトを簡単にインストールができる。

GooglechromeやiTunesなど、有名ソフトも多数置いてある。




公式→[chocolatey](https://chocolatey.org/install)

[chocolateyのパッケージ集](https://chocolatey.org/packages)

より詳しく→[Chocolateyを使った環境構築の時のメモ](http://qiita.com/konta220/items/95b40b4647a737cb51aa)







## 2行目:anacondaインストール

```sh
choco install -y --execution-timeout=1000000 anaconda3
```

chocolatey使ってpythonディストリビューション"anaconda"のインストール

anacondaとは...

* pythonのディストリビューションの一つ
* 主要ライブラリをオールインワンでインストールできる(numpy,scipy,pandas,ipython,jupyter,scikit-learn etc...) 
* python 2.xも3.xも対応。(ここでは`anaconda3`と打つことで3.xを落とすが、`anaconda2`とすることで2.x)も落とせる。
* Linux版、Mac版、Win版(32bit, 64bit)とそろっている。 
* `conda install <パッケージ名1> <パッケージ名2>...`で欲しいパッケージをインストールできる。←アップデートの項で`conda`は使う
	* 欲しいパッケージが落ちているかは[Anaconda Cloud](https://anaconda.org/)で探すか、`conda search -t <パッケージ名>`で検索。親切な人があげてくれているかもしれない。


公式→[anaconda3](https://www.continuum.io/downloads)

[chocolateyのPackage集:Anacondaのページ](https://chocolatey.org/packages?q=anaconda)

より詳しく→[データサイエンティストを目指す人のpython環境構築 2016](http://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c)





### `-y`

`-y`オプションはchocolateyが聞いてくるすべての問いに対して'yes'と答えることと同義。

いちいち`y`とタイプするのが面倒な時は最初に指定しておくと画面に張り付く必要なくて楽。






### タイムアウトについて

`--execution-timeout`オプション指定しないと、ダウンロードを30分くらい行った後にこんなエラーが出てくる

```
     --timeout, --execution-timeout=VALUE
     CommandExecutionTimeout (in seconds) - The time to allow a command to 
       finish before timing out. Overrides the default execution timeout in the 
       configuration of 2700 seconds.
```

インストーラが大きすぎて、chocolateyのデフォルト時間ではタイムアウトする。

無駄な時間を過ごしてしまったので皆さんはあらかじめ指定しておきましょう。


ちなみにダウンロードからインストールまで1-2時間かかるので注意。







# パッケージのアップデート

## chocolateyで管理されているソフトすべてをアップデート

```sh
choco upgrade all -y
```

chocolateyのパッケージをアップデートするときは`choco upgrade <パッケージ名>`

<パッケージ名>を`all`と指定すると、chocoによってインストールされたすべてのパッケージのアップデートを行う

ちなみに`choco update`コマンドはまだ一応あるけど廃止の予定らしい。(ワーニングが出る)







## anacondaのパッケージすべてをアップデート
```sh
conda update --prefix C:\tools\Anaconda3 --all　
```

アップデートするときは`conda update <パッケージ名>`

chocolateyによってインストールすると、デフォルトでanacondaでインストールするときのようにホームディレクトリ(`C:\Users\<UserName>`以下か、`C:\`以下)に作られない
そのため、`--prefix <パス>`のようにして、anacondaの場所を指定してあげる
Windows 10 Client Hyper-V 統合サービス(Instegration Services)導入

Windows 10 の Hyper-V では統合サービスが簡単に導入できない為、自分用にメモ。

ゲスト OS の対象は Windows 7/8/8.1。Linux はこの記事には含まない。

以下のサイトで各 OS の統合サービスファイル(.cab)をダウンロード
https://support.microsoft.com/en-us/kb/3071740

Hyper-V に通常手順で OS 導入し、統合サービスファイルをゲスト OS 上に持っていく(※)。

※仮想ディスクを利用した方法
1. ホストの Windows 10 上で VHD を作成、マウントして統合サービスファイルをコピー
2. アンマウントしてゲスト OS で VHD をハードディスク追加する
3. ゲスト OS を起動して、VHD 上の統合サービスファイルが見れることを確認する

ゲスト OS で管理者権限でコマンドプロンプトを起動して、以下のコマンドを実行する。
>dism /online /add-package:<*.cab Fullpath>

再起動メッセージが表示されたら「y」で再起動。

起動後デバイスマネージャを確認して、ゲスト OS 上でデバイスが認識されている事を確認して完了。
RaspberryPi2 初期設定メモ

RaspberryPi2を買ったので、初期設定のために参考にしたサイトをメモする。

(RaspberryPi3の方がいいと思う)

# 用意したもの

+ RaspberryPi2 (Amazonで購入)
+ HDMIケーブル (電気屋で購入)
+ ディスプレイ (元々所持)
+ USBマウス (電気屋で購入)
+ USBキーボード (元々所持)
+ LANケーブル (元々所持)
+ 無線LAN子機 (電気屋で購入)
+ microUSBケーブル (携帯充電器の充電用ケーブルを使用)
+ microSDカード (電気屋で8GB購入)


HDMIケーブルとディスプレイは画面を映すために必要なもの。必須。
USBマウスとUSBキーボードは入力のための道具。必須。
LANケーブルと無線LAN子機。インターネットにつなぐための道具。多分どちらかあればいい。
microUSBケーブル。RaspberryPiに電気を供給するもの。必須。
microSDカード。OSをインストールするために必要なもの。必須。

microSDカードは16GBのclass10がオススメらしい。それにすればよかった。

あと買ったものとして

+ microSDカードをUSBから読み書きできるようにするアダプタ

がありました。
https://www.raspberrypi.org/downloads/
のサイトからノートPCを使ってOSをダウンロードし、それをmicroSDカードに入れる時に使いました。

> 参考にしたサイト
http://dev.classmethod.jp/hardware/raspberrypi/raspberry-pi2-1st-impression/

# OSインストール後の設定

(OSのインストールは40分くらいかかりました)

http://nonstop-engineering.hatenablog.com/entry/raspberry-pi-first-setting

このサイトを参考にしながら設定をしていく。

ターミナルを起動し、次のコマンドを打つ。サイトを参考にタイムゾーンなどの設定を行う。

```
$ sudo raspi-config
```

次に、下のようなコマンドを順番に実行していく。

```
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo rpi-update
```

時間がかかりますが、我慢します。

次に日本語入力に対応するような設定をしていきます。

まず日本語入力ソフトをインストール

```
$ sudo apt-get install ibus-anthy
```

日本語表示のためのソフトをインストール

```
$ sudo apt-get install jfbterm
```

ここで再起動するといいらしいので再起動。

> 参考サイト
http://www.stdio.jp/entry/raspberry_pi/rp2-raspbian-install

パスワードの更新を行いました。

```	
$ passwd
```

Macから、ラズベリーパイを操作する方法
http://darmus.net/raspberry-pi-mac-vnc/

以後、ここにメモしていきます。
re:dashをローカル(OSX)で試す

ローカルで試しに動かしてみたかっただけ。
意外と簡単だった。
動かしたバージョンは、v0.11.1.b2095。今の最新。

postgresとredisはbrewでインストールして起動しておく。
Pythonとnodeは入ってる前提。
(いま確認したらPython：2.7.10、node:v6.2.2 が入ってた。 )

https://github.com/getredash/redash/releases
からtar.gzをダウンロードして適当な場所に展開しておく。

ver: 0.11.1+b2095で再度試したら
~~celeryの起動が元の書き方だとダメだった。修正！~~
ダメじゃなかった。
redisがversion 3じゃないとダメみたい。
redisのバージョンが古かっただけっぽい。

```
cd redash.0.11.1.b2095
pip install -r requirements.txt
npm install
./node_modules/.bin/bower install
./node_modules/.bin/gulp bower
./node_modules/.bin/gulp
echo 'export REDASH_STATIC_ASSETS_PATH="../rd_ui/dist"' > .env
bin/run python manage.py database create_tables
bin/run python manage.py users create --password <パスワード> --admin <ユーザ名> <メールアドレス>
bin/run celery worker --app=redash.worker --beat -Qqueries,celery,scheduled_queries~~
bin/run python manage.py runserver
```
これで動いた。

あとは
http://localhost:5000 にアクセスして、
作ったユーザでログインして、data source追加してあげればOK。
MKMapViewに現在地を表示する


MapKitとCoreLocationライブラリをリンクして、StoryboardにMapViewを貼り付けて、MapViewの「User Location」にチェックを入れて、という手順までは、まあ素直に進むと思います。

そのまま起動すると以下のようなエラーが。

```
2016-08-05 22:25:41.739 MapTest[1844:443449] Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
```

言われるまま、request..メソッドを足します。

```
let lm = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    
    lm.requestWhenInUseAuthorization()
    lm.startUpdatingLocation()
}
```

が、これでも現在地が表示されません。そもそも、位置情報利用を許可するためのダイアログも出ません。もう一手間必要なんですね。Info.plistに以下のプロパティを足してやります。

```
NSLocationWhenInUseUsageDescription
```

値はなんでも良いのですが、ダイアログの下部に表示されます（添付画像の「Hello MapKit」の部分）。

![IMG_2067.jpg](https://qiita-image-store.s3.amazonaws.com/0/50780/6ba93e70-addf-4152-51e5-6796ef90a583.jpeg "IMG_2067.jpg")

これで晴れて現在地が表示されます！

![IMG_2068.jpg](https://qiita-image-store.s3.amazonaws.com/0/50780/d09a33f1-7806-b940-d952-7a744cde8996.jpeg "IMG_2068.jpg")



## 参考
http://stackoverflow.com/questions/34013045/swift-ios9-trying-to-start-mapkit-location-updates-without-prompting-for-locati
notice（通知）を動的に追加、削除


Atom等のエディタでもお馴染みの通知をテキトーに実装。

```css
#notice_box{position: fixed; top: 2rem; right: 2rem;}
.notice {display: none; width: 250px; background: #ccc; border: 4px solid; margin-bottom: 10px; padding: 8px;}
.notice > p {margin: 0; padding: 0; font-size: 12px;}
.notice_info {background: #0099ff; color: #ffffff; border: 4px solid #0066ff}
.notice_warn {background: #ffffcc; border: 4px solid #ffff00}
.notice_error {background: #ffcccc; border: 4px solid #ff6666}
```

```html
<div id="notice_box"></div>
<button type="button" id="btn_info">info</button>
<button type="button" id="btn_warn">warn</button>
<button type="button" id="btn_error">error</button>
```

```js
var gb = {};
$(function(){
    gb.noticeArea = $('#notice_box');
    $('#btn_info').on('click', function(){
        notice('info', 'test test test test test test test');
    });
    $('#btn_warn').on('click', function(){
        notice('warn', 'test<br> test test test test test test');
    });
    $('#btn_error').on('click', function(){
        notice('error', 'test test test<br> test<br> test<br> test test');
    });
});

// 呼べば呼んだだけnoticeを追加して、時間が来たら破棄する。
function notice( level, content, time, width ) {
    var t = time ? time : 3000, w = width ? width : 250;
    var item = $('<div class="notice"><div>')
    gb.noticeArea.append(item);
    item.width(w).addClass(`notice_${level}`).html(`<p>${note}</p>`).slideDown('swing');
	setTimeout(function(){
        item.slideUp('swing' ,function(){
            this.remove();
        });
    }, t);
}
```
Python3とPyQt5を使ってのGUIプログラミング（１）

pythonを初めてまだ日がたってない学生なので知識は浅いです。
ほぼ備忘録のようなものになると思います。
#ウィンドウ表示
```py3:test.py
# coding: UTF-8

import sys
from PyQt5.QtWidgets import QApplication, QDesktopWidget, QWidget


class Test(QWidget):

    def __init__(self):
        app = QApplication(sys.argv)

        super().__init__()
        self.init_ui()
        self.show()

        app.exec_()

    def init_ui(self):
        self.setWindowTitle("PyQt5")
        self.resize(640, 400)
        self.frameGeometry()\
            .moveCenter(
                        QDesktopWidget()
                        .availableGeometry()
                        .center()
                        )


if __name__ == '__main__':
    Test()
```
![image](https://qiita-image-store.s3.amazonaws.com/0/135885/e4a54dd1-b99b-cecf-5000-115ed4373367.png)

これでウィンドウを画面中央に表示できるはず。

~~書き方がpythonかどうかはわからない~~
他に書き方があればぜひ教えて下さい。

[次](http://qiita.com/tak0-auk/items/6dcbfc70e9d583d12911)
findで日時指定で検索する

覚書

findコマンドで検索するとき、日時を指定したくなります。
この時間の範囲を対象に更新(`-mtime`)したファイルを検索してくれます。

`find /home/ -name "*.txt" -newermt '20160805 09:00:00' -and ! -newermt '20160805 09:30:00'`

ほかにも、`-newerat`が`-atime`で、`-newerct`が`-ctime`として指定できます。
Aptana 3.6が落ちまくるのに、ネットで見つからない・・・orz


# 現象
Aptanaがとにかく、よく落ちる。
固まっているかのごとく、反応が遅い（ファイル一つを開くのに1分とか・・・）。

で、何よりも大変なのは、ネットで検索してもこの話題が見つからない。

# 環境

Scientific Linux 6.0(実は、教材環境の都合があって、このバージョンは動かせない。)
そのLINUXを、VMware Workstation上で動作させている。
当初は、Cygwinとかを使っていたが、これだと、一般の学生はもう壊滅状態なので, Linux/VMwareが快適かもしれない。
あ、どういう職場環境かがバレてしまうような書き込みでした。

改めて：
Scientific Linux 6.0 on VMware
ruby 2.3.1   → /usr/lib/rubyに置き換え
gem 2.6.6
git 2.8.4
rails 5.0.0
java jdk1.8.0_101

IDEはやめて、いっそのこと、Vimを使わせて鍛える？
う〜ん、泳ぎを教えるのに、いきなり足の立たない海に放り込むような鍛え方。何人が溺れることか・・・

もしかしたら、VMwareとの相性が悪いかと思ったら、そうでもなさそうな記事があった。Aptana3.4から3.5にupgradeした途端に、ファイルを開こうとするとエディタで落ちる。原因不明。

# 「Aptana 落ちる」で検索
見つけたのは、これ
http://saifis.net/?p=174

VMwareを使っているから、とか、そういうことではないと理解。
試行錯誤
Aptana 3.6.0 Standalone版
  → ファイルを編集しようとすると、突然落ちる。
  　　→　この現象は、editorを切り替えるとなんとかなるらしい。
Eclipse - Neon + Aptana
  → ファイルを開くのに2〜3分かかる。
  　　後で見たら、workspace/.metadata/.logに膨大な
  　　エラーログの書き込みがあり、このエラーログを作成する
  　　ために、どうしようもなく重くなっていた。
Eclipse Mars + Aptana
  → コンソールから起動すると、かなりのエラーログを吐き出す。
  一応、まともに動いているっぽいが・・・
Eclipse Kepler + Aptana
  これはもう、最悪：プロジェクト生成したら落ちた。

# インストール先の変更
最初、Eclipseを
/usr/shareの下で展開し、/usr/local/binに実行ファイルの
シンボリックリンクを貼る形で作った。
ところが、これだと、sudoerに名前がある「一般ユ−ザ」でも
root権限ではないため、実行時にエラーが起きるようだ。
（実行中に、何かをroot権限の領域に書き込みにいっている。）

そのため、
/home/robertBrown/eclipse
のように、一般ユーザのホームにeclipseというフォルダを作成するように
インストール先を変更した。

これで、また、上記の組み合わせを試したら、幾分改善された
気がしたので、もう、これで行くことに・・・

# 一番マシな組み合わせを選択
Eclipse Marsと、Aptana Studio 3.6.0の組み合わせをベースに
コツコツとエラーを潰すことにした。
eclipse-java-mars-2-linux-gtk-x86_64.tar.gz
をベースに、Aptana PluginをEclipseから追加させた。
（すみません、他の方の記事を見て下さい。）

回りくどい説明はやめます。

# 今回、修正のために直したこと。
## gem install jruby-parser
なんでか知らないが、jrubyparserがエラーを吐き出していたので、
gemとしてinstallしたら、Gemfileには含まれていないのに
なぜか、きちんと動作した。関連するlibraryが入ったため？

## Gemfileに gem 'execjs'を追加
railsが自動生成してくれるlayout/application.html.erbは
Gemfileのtherubyracerを有効にしないと、うまくいかない。
そのすぐ下に、
gem 'execjs'
を追加して、bundle installした。

## /etc/hostsの編集
なぜか、host名が取得できない、というエラーが出た。
ホスト名、表示しながらそれが取得できないとか言われたので、
127.0.0.1   myHostName   localhost
で、一行をhostsの先頭にしようとしたら、既に記述されている。
古いやつをコメントアウトして、ほとんど同じ内容なのだけれども
上記の一行を先頭に入れた。

# 解決しました。

どの呪文に効果があったのかわかりませんが、
Aptanaとして、まともに動作するようになりました。
ファイルを開くのに1〜2分かかる、という現象も、プロジェクトを
新規作成させると、いきなり落ちる現象も、「Ecipseを終了」してから
本当にプロセスの終了が完了するまで4〜5分かかる現象も、とにかく
全部解決しました。

何が悪かったのかわかりませんが、ご参考になればと思い、公開します。
Qiitaの投稿について調べた件

#Qiitaの投稿について調べた件
- Qiitaに投稿している人はどの時間帯に投稿してるのだろう
- どの曜日に投稿が多いのだろう・・・

などいろいろ疑問に思い、調べた話

#調査のやり方や期間など
- Webスクレイピングによって、[全ての投稿](http://qiita.com/items)の投稿タイトルやURL、投稿者を記録する（APIの存在は後で気づいた）
- 10分間隔で情報をとりにいく（10分間に大量に投稿があった場合、とりこぼしがあるかも）
- 使用言語はPythonでRasberry Piをサーバ代わりに運用
- 調査期間は2016年5月29日～6月4日、7月13日～現在進行形

##ラズパイが落ちまくった話
全ての投稿のページがJavaScriptで動的にロード？されてるみたいで、seleniumを採用

こん感じでログインして、ソースコードを取得する

``` python
display = Display(visible=0, size=(800, 600))
display.start()
driver = webdriver.Firefox()
driver.get("http://qiita.com/")
driver.find_element_by_id("identity").send_keys("mail address")
driver.find_element_by_id("password").send_keys("password")
driver.find_element_by_name("commit").send_keys(Keys.RETURN)
time.sleep(10)//配慮
driver.get("http://qiita.com/items")
source = driver.page_source.encode("sjis","ignore")
driver.close()
display.stop()
```

数日、テストとして動かしていたら１～３日でラズパイがフリーズしてしまい、ソースコードを見なおしていたら「stopがないじゃん！」って思ってdisplay.stop()を書いたら、フリーズしなくなりました（#^ω^）


``` python
display.stop()//←こいつ
```

タイトルとか投稿者を抜き出すコードは要らないですよね(´・ω・｀)
タグも抜き出せば良かった・・・（大失敗）

#結果
##まず、時間帯別
![p_hour.png](https://qiita-image-store.s3.amazonaws.com/0/122949/dd28c2de-abeb-0c9f-6e3c-895cd0aee510.png)

当然のようですが、４，５時の時間帯が最も投稿数が少なく、２３、０時が多く投稿されている時間帯のようですね
やはり、エンジニアは夜型のようです
１１時、１６時に投稿数が増えるのは休憩や休み時間とかなのでしょうか（笑）

##次は曜日別
![p_week.png](https://qiita-image-store.s3.amazonaws.com/0/122949/7ba67573-f5d7-ebc9-04eb-07c42bd62d34.png)
予想外に、水曜日が多い・・・個人的予想では日曜が多いのかと思った
これは調査した期間の影響か！？

##日別
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/122949/37693332-9790-2aff-0366-548b0a8fcfe5.png)
７月２２、２３日はなぜかラズパイが死に、それに気づかず放置
７月３０、７月３１日は間違えてラズパイの電源タップを切ってしまった


#終わり
本当は、ミスった日は除外しないと正確な結果が出ないのだけれど、面倒になってエクセルに「ぽいー」したので、結果をあまり信用しないように・・・
途中で気づいたことで、タグも記録してればタグごとにも集計出せたのに・・・
[タグごとに集計された方](http://qiita.com/kure/items/dd57f1fdf66b0bd8db8e)
submitボタンを押してページがリロードされてもページが一番上に行かないようにする。

submitボタンを押してページがリロードされてもページが一番上に行かないようにする。
下記コードをjqueyを読み込んだ後に読み込まれるように挿入。

```index.html
・
・
・
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script type="text/javascript">
      var windowPosition = function(){
        //ローカルストレージからデータを取得
        var windowPosition;
        windowPosition = localStorage.getItem('windowPosition');
        windowPosition = window.localStorage.getItem('windowPosition');
        windowPosition = localStorage.windowPosition;
        //読み込んだ表示位置を復元
        $(window).scrollTop(windowPosition);
        //読み込んだらローカルストレージをクリア
        localStorage.clear();
        window.localStorage.clear();
        //submitした時の表示位置をローカルストレージに保存
        $('input[type="submit"]').click(function(){
          windowPosition = $(window).scrollTop();
          localStorage.setItem('windowPosition', windowPosition);
          window.localStorage.setItem('windowPosition', windowPosition);
          localStorage.windowPosition = windowPosition;
        });
      }();
    </script>
    <script src="メインとなるJSファイル"></script>
  </body>
</html>
```

該当画面が重いor通信速度が極端に遅くなければリロードされページが一番上に行く動作もないかと思います。
プロジェクトに参加した（てる）とき思うこと

※ I (maybe) will translate to English (maybe)

プロジェクトキックオフ（あるいは後発ジョイン）のごくごく初期に、**全力で**以下のことを明らかにしようと心がけてる。

1. Task Base
2. Document Base
3. Source Base
4. (optional) Communication Base

多くのプロジェクトがわりと情報を散らかしてるし、口頭のコミュニケーション（場合によっては口論）ですべて解決できると思ってて、非常にたちが悪い。

# Task Base

- JIRA
- Asana
- Trello
- GitHub issues
- Mantis <- 最近知った

「何をやらなきゃいけないか」を明らかにするためにある。「やらなきゃいけない」というのは、**「理想」と「現実」の「差分」**。したがって、Task Baseには「（そのタスクにおける）理想の形」が明記されていなければならない。その点を理解してない人がつくったタスクは非常につらいものがある。

# Document Base

- Confluence
- GitHub wiki page
- Qiita

ある種のタスクには「○○を決める」というような「具体的なもの」ではない「理想の形」を持つものがある。この「具体的でないもの」の「アウトプット」の記録媒体として、Document Baseは使われる。日報を書いたりポエムを書いたりするもの**ではない**。これを共有サーバのWebDAVとかでやるプロジェクトもあったけど、あれはクソだ。アクセス権限の管理がだるいし、URLの共有がだるいし、バージョン管理もだるい。

# Source Base

- GitHub
- BitBucket

ソースコード管理が必要な理由は割愛します。

# Communication Base

- Slack
- Skype
- Gitter

これはべつに明らかにしようとしなくても明らかになってる場合が多いので、頑張らなくてもいいんだけど、だいじなのはおそらく、顧客のコミュニケーションスピード？意思決定のスピードとか、バグなどの問題の透明性を知るために、顧客が使ってるcommunication baseを知り、可能な限りそこに溶け込む必要があると思っている。あるプロジェクトで、無理にSlackへの移行を進めた結果、結局顧客のコミュニケーションが二元化してしまい、問題の共有（とくにサーバサイドのバグの共有）がされず、遅延の原因やブロッカーの存在が不透明になってしまうケースがあった。

# 最近思うこと

- 1つのプロバイダーで統一してほしいと思う
- とくにConfluenceとJIRAの組み合わせは気持ちいいので好き
- とにかくvisibleにしてくれー口頭で言われてもわからんー
- Tasksの表示方法って個性があっておもしろいなって思う
    - Trelloとかもう1depthしかなくて並列だし
    - JIRAはサブタスクつくれるけど2depthまでだし
        - ツリー構造で簡単に表示したいんだけどな
    - GitHub issueは1depthでfiltering哲学だよな
    - Asanaはお化粧だけ整えてて直感的ではない
        - Taskを定義する人間にTaskに必要な情報を強いないので、Taskが意味不明になりやすい
    - Taskを定義するうえでTaskに必要な情報の入力を強いるツール/フレームワークが必要
- とかつらつら考えてたら、サービスつくりたくなってくるわけで、こういうのがプロダクトのタネになるんだろうな
Rails5 + Pumaにて、正しくLogrotateされなかった問題の対応

## 概要 
Rails, PumaのLogrotate設定をしたものを、itamaeを利用して本番に反映した。
その結果、logrotateが実行された形跡はあるものの、実際にはrotateされてなかった。
また、force optionをつけて実行して、新しい logを作成したとしても、
rails の production.log が loggingされなかった。

## 原因 
logrotateの初回実行はタイムスタンプを残すだけで、実際に rotateは行わない。
(公式ドキュメント見たい)
参考: http://catnapper-mar.hatenablog.com/entry/2015/08/30/141424

また Puma も unicornと違って、HUP シグナルを送るだけでは production.log
の reopenがされないらしい。
参考: https://github.com/puma/puma/issues/806

## 対応
Railsのproduction.logはcopytruncateで対応。

copytruncateはlogの欠損リスクはあるものの、
該当する時間帯のログ欠損は、現状さほど大きなリスクではないという点で一旦この方法で対応。
後ほど、td-agentも含めて対応を考える.

```
Note that there is a very small time slice between copying 
the file and truncating it, so  some  log ging  data  might be lost.
```

http://www.linuxcommand.org/man_pages/logrotate8.html


## 今後の予定
cronologを試してみる。
http://qiita.com/ma2ge/items/1fba78a08e8d3b82b3c2#logger--logrotate
dns_round_robin trueの動作確認

送る先のサーバが増減するだけでうん百台のtd-agentのクライアントをrestartしてまわるのが不毛なのかなと思って、
（confは送るとこはs3にあるのをincludeして読むようにしたので配らなくていいにしても）
dns_round_robin trueの軽い動作確認をしました。その記録です。

・セットで設定しとかないといけないやつ
expire_dns_cache 15
dns_round_robin true
heartbeat_type tcp

・送信元
test-komi02

・受信先
test-komi01
ip-192-168-1-174

・ドメイン：td-agent.hoge.local

```
# dig +noall +answer td-agent.hoge.local
td-agent.hoge.local. 47    IN      A       192.168.1.174
td-agent.hoge.local. 47    IN      A       192.168.3.103
```

・送信元の主要なconfig

```
<source>
  type tail
  format apache
  path /var/log/httpd/access_log
  tag apache.access.log
</source>
<match apache.access.log.**>
 type copy
  <store>
    type forward
    heartbeat_type tcp
    heartbeat_interval 1s
    send_timeout 61s
    flush_interval 1s
    buffer_queue_limit 512
    buffer_type file
    buffer_path /var/tmp/fluent_buf0
    expire_dns_cache 10
    dns_round_robin true
    require_ack_response
    <server>
      host td-agent.hoge.local
      port 24224
    </server>
  </store>
</match>
```

・受信先の主要な設定

```
<match apache.access.log.**>
  type copy
  <store>
    type forest
    subtype file_alternative
    <template>
      path /path_to_log/access_log
      buffer_path /path_to_buffer/fluent_buf/__TAG__
      flush_interval 1s
      buffer_queue_limit 512
      buffer_chunk_limit 10m
      buffer_type file
    </template>
  </store>
</match>
```

テストコマンド
送信元

```
# for i in `seq 1 10000`; do echo '{"json":"message dayo"}' | /opt/td-agent/embedded/bin/fluent-cat apache.access.log.; done
```

受信先

```
# tail -f /path_to_log/access_log.20160804.log
```

ログの出方を眺めてたところ、とりあえずexpire_dns_cache 10秒にしてたので5～30秒くらいおきに出る先のサーバが変わったりしていました。
もともと設定していた以下のような送る先の設定だと、1秒前後おきに頻繁に送る先が変わっていました。

```
    <server>
      host td-agent1.hoge.local
      port 24224
      weight 50
    </server>
    <server>
      host td-agent2.hoge.local
      port 24224
      weight 50
    </server>
```

以上です。

参考：
http://docs.fluentd.org/articles/out_forward#dnsroundrobin
http://docs.fluentd.org/articles/out_forward#expirednscache
https://speakerdeck.com/fujiwara3/consul-casual-1
vccwにsshでログインする / データベースのインポートとエクスポート


## sshでvagrantにログインする

~~~
$ ssh vagrant@vccw.dev
~~~

パスワードもvagrant

ってやらなくても

~~~
$ vagrant ssh
~~~

でいける...

http://vccw.cc/

## データベースのインポート／エクスポート

~~~
// データベースのエクスポート
$ wp db export /vagrant/import.sql

// データベースのリセット
$ wp db reset --yes

// データベースのインポート
$ wp db import /vagrant/import.sql
~~~

sshでログインしていなくても下記のように書いて操作する事も出来る

~~~
$ vagrant ssh -c "wp db export /vagrant/import2.sql"
~~~
Facebookアプリの設定でOauthのリダイレクト設定が表示されない



アプリ設定 > プロダクト > 製品を追加 > Facebookログイン

でログインを追加して、

「有効なOAuthリダイレクトURI」へURIを入力出来るようになります。

Facebookのdocs(https://developers.facebook.com/docs/facebook-login/security )の情報は古いため注意。
Win10のネットワークプロファイルをPowerShellでプライベートにする

Win10はネットワークプロファイルがパブリックになってるとリモートデスクトップ接続できなくてマジ困りなのでプライベートにしたかったけど手動だとなんかできなくてでPowerShellだとすんなりでした。

```
Get-NetConnectionProfile -Name "ネットワーク名"
Set-NetConnectionProfile -Name "ネットワーク名" -NetworkCategory Private
Get-NetConnectionProfile -Name "ネットワーク名"
```

http://www.atmarkit.co.jp/ait/articles/1509/07/news018_2.html


たまに勝手にパブリックに戻るのがどうしたものかよくわかってないですが。。
以下のファイル名を指定して実行 ([Win] + [R]など) から 「 secpol.msc 」 と入力し、ローカル セキュリティ ポリシー エディター を起動しネットワーク リスト マネージャー ポリシーを設定しまくるのがよさそうかな。たぶん。

http://techstorage.interlink.ne.jp/?p=1534
【イベントレポート】The Blockchain Event

７月に米国で開催されたThe Blockchain Eventに参加しました。
基本的にパネルディスカッションが中心でしたが、メモを纏めます。

##市場動向
・現在の米国市場ではブロックチェーンに付加的な機能を与えるようなスタートアップ企業が多く創業されている（例：セキュリティ など）
・ビットコインのやりとりには個人毎のアドレスが必要であり、非テクニカル領域の人にはそれだけでアレルギーが出るのが実情である
・そもそも、ブロックチェーンはインターネット技術の上に成り立っているものであり、既存銀行システムをインターネットサービスと連携させるかというハードルは、ブロックチェーンを採用するかの前段にあるものである
・Currency（貨幣）とMoney（金）で事情が大きく違う。貨幣の場合には各国ごとに規制がベースにあり、IT技術を適用するには各国ごとに考慮が必要
・技術的課題と規制問題を混同してはならない。ここはIndustrial IoTと同様である
・VCは銀行システムをどう変革するかでは投資をしていない。新プラットフォームを構築できるかどうかでベンチャー投資を行っている
・基盤技術でしかないブロックチェーンではエコシステムが重要。その為、プライベートブロックチェーンだけでなくAPI化して外部インターフェースを提供すべきである

##IoTとBlockchain
・IoTで一番の課題はハッキングである。セキュリティ対策は一般的な言い方ではあるが、対ハッキングに対してはブロックチェーンの堅牢性は価値が高い
・スマートプロパティ（資産管理）も用途として期待される。Hardware as a Service：ハードウェアを販売するのではなく、サービスとして提供する。そこには販売後のアクティベーション、課金、メンテナンスなどの一連のサポートと転売なども柔軟に実現する事が必要


##Tally Capital
・The Internetが世界にリリースされた時にTCP/IPとSNAが戦った時にようなステージに、現在のブロックチェーンはある
・どの個別にPrivate Blockchainも本来のDecentralizedされたBitcoin Blockchainの特徴を活かしていない
・Proof of WorkとProof of Stakeの組み合わせでブロックチェーンを実現するPeercoinに注目すべき
・Blockchain is a control plane. パフォーマンスはあくまで足回りのネットワークとインフラに依存する

##BlockCypher
・クラウド上のブロックチェーンプラットフォーム展開し、サービス提供
・主に仮想通貨アプリケーションに対し、スケーラビリティと可用性を提供する

##Blockchain of Things
・2016年末にリリース予定
・ビットコインブロックチェーンをインフラとして利用し、トランザクションの高速化を付加提供する
・規制の多い業界、例えば製造業での製品パーツ調達におけるガバナンスには効果があると考えてる（例：航空機）

##Nuco 
・Deloitteのブロックチェーンチームが創業
・MS Azure情にプライベートブロックチェーンを構築してサービスを提供開始予定
・証券取引委員会（SEC)と当局のコンプライアンス業務の追跡ツールなどの開発を行う
Pythonのダイナミックな型付け

# 概要
[はじめてのPython第3版](https://www.oreilly.co.jp/books/9784873113937/)の勉強メモ

# アジェンダ
- 型宣言がないPython
- 共有リファレンス
- 共有リファレンスとオブジェクトの上書き
- 「同等」と「同一」

# Pythonのダイナミックな型付け
## 型宣言がないPython
### 変数の作成
```py
a = 3
```

- 変数は値が代入されると同時に作成される
- 作成後に代入が行われた場合、すでに代入されていた値が新しいものに入れ替わる
  - この場合、変数はすでに作成済みのため、新たに作成されているわけではない

### 型情報
- 変数自身は型情報を持たない
- 型情報を持つのは変数に対応する「オブジェクト」
- 変数は対応しているオブジェクト（その時点で代入されているデータ）へのリファレンスだけを持つ

### プログラム実行時の変数の扱い
- 対応するオブジェクトにすべて置換えられる
- 対応するオブジェクトがない変数は使用できない
- 変数とオブジェクトはメモリの別の部分に格納されリンクされる

![WS000427.png](https://qiita-image-store.s3.amazonaws.com/0/79134/4a97582d-788e-d85c-5252-85ec69e9f5de.png)

### ガーベージコレクション
- 変数に新たなオブジェクトが代入された場合、それまで代入されていたオブジェクトは破棄され、**そのオブジェクトが占めていたメモリ領域は開放される**、このことを**ガーベージコレクション**と呼ぶ

## 共有リファレンス
```py
a = 3
b = a
```

これはいかのようになっている

![WS000428.png](https://qiita-image-store.s3.amazonaws.com/0/79134/62baacb7-62e4-207a-d1fc-d3a3ef1b773a.png)

このように、**複数の変数が同じオブジェクトのリファレンスになっている状況**を**共有リファレンス**と呼ぶ


次に、先のコードに1行加える

```py
a = 3
b = a
a = 'spam'
```

これはこのようになっている
変数aは新たに作られた文字列オブジェクトの'spam'へのリファレンスとなるが、変数bはそのまま、オブジェクト3へのリファレンスのままとなる 

![WS000429.png](https://qiita-image-store.s3.amazonaws.com/0/79134/82fd7b4d-a732-2936-a75d-fd8444b95742.png)

## 共有リファレンスとオブジェクトの上書き
リストは、角カッコの中にオブジェクトを並べたものであり、上書きが可能なオブジェクト


以下の例ではL2は`[2, 3, 4]`へのリファレンスのままとなる

```py
L1 = [2, 3, 4]
L2 = L1
L1 = 24
```

以下の例の場合、リファレンスとなっているオブジェクトの値が上書きされる

```pycon
# 可変性のオブジェクト
>>> L1 = [2, 3, 4]

# 同じオブジェクトへのリファレンスをもう1つ作る
>>> L2 = L1

# 要素の上書き
>>> L1[0] = 24

# L1に対応するリストに変更が加えられている
>>> L1
[24, 3, 4]

# L2にも影響が！
>>> L2
[24, 3, 4]
```

以下の方法でコピーさせた場合、L2は変更されず、**2つの変数は違うメモリ領域を示している状態となる**

```pycon
# 可変性のオブジェクト
>>> L1 = [2, 3, 4]

# L1のコピーを作る
>>> L2 = L1[:]

# 要素の上書き
>>> L1[0] = 24

# L1に対応するリストに変更が加えられている
>>> L1
[24, 3, 4]

# L2は変更されない
>>> L2
[2, 3, 4]
```

## 「同等」と「同一」
```pycon
>>> x = 42

# 42はすぐに破棄される？
>>> x = 'shrubbery'
```

**Pythonでは、小さい整数や文字数の少ない文字列はキャッシュされて再利用される**


### **オブジェクトが「同じ」であるかどうかの比較には2つの種類がある**
- ==演算子は、オブジェクトが「同等」であるかを比較するもの
- is演算子は、オブジェクトが「同一」であるかを比較するためのもの
- **「同等」よりも、「同一」であるための条件の方が厳しい**

```pycon
>>> L = [1, 2, 3]

# MとLは同じオブジェクトのリファレンス
>>> M = L

# 両者が「同等」であるかの比較
>>> L == M
True

# 両者が「同一」であるかの比較
>>> L is M
True
```

```pycon
>>> L = [1, 2, 3]

# MとLが対応するオブジェクトは別のもの
>>> M = [1, 2, 3]

# 両者の値は同じ
>>> L == M
True

# 2つのオブジェクトは同等だが同一ではない
>>> L is M
False
```

### **同様のことを小さい数値に対して行うと、結果が異なる場合がある**
- 下記の場合、XとYは同等ではあっても、同一ではない
- しかし、小さい数値や文字列はキャッシュされて再利用されるため、どちらも同一のオブジェクトのリファレンスになっている

```pycon
>>> X = 42

# 2つの42は本来、同一でないはず
>>> Y = 42
>>> X == Y
True

# キャッシュが行われるため、2つは同一になる！
>>> X is Y
True
```
yuml > インターバル図 

参考 http://qiita.com/tukiyo3/items/840b52027be03d270b0a

```
![](http://yuml.me/diagram/class/[起点]6h-->[測定1],[測定1]6h-->[測定2],[測定2]6h-->[測定3])
```
は以下となる。

![](http://yuml.me/diagram/class/[起点]6h-->[測定1],[測定1]6h-->[測定2],[測定2]6h-->[測定3])

テキスト変更だけでバリエーションを作れるのは、やはりいいと思う。

![](http://yuml.me/diagram/class/[起点 (2016/08/05 12:00)]6h-->[測定1],[測定1]6h-->[測定2],[測定2]6h-->[測定3])

![](http://yuml.me/diagram/class/[起点 (2016/08/05 12:00)]3h-.->[測定1],[測定1]3h-.->[測定2],[測定2{bg:green}]3h-.->[測定3])

![](http://yuml.me/diagram/class/[起点 (2016/08/05 12:00)]3h-.->[測定1],[測定1]3h-.->[測定2],[測定2{bg:red}]3h-.->[測定3])
Docker のバージョン管理を Fish Shell で。。

## dvm

バージョン管理する意味はまだよくわかってないですが
`dvm` なるものがあるみたいなので使ってみました。

![https://gyazo.com/54404558a00956dd0398fdafdf4fd47a](https://i.gyazo.com/54404558a00956dd0398fdafdf4fd47a.gif)

参考

* [Manage Docker clients with the Docker Version Manager | Carina by Rackspace](https://getcarina.com/blog/docker-version-manager/)

### install

```
curl -sL https://download.getcarina.com/dvm/latest/install.sh | sh
```

上を実行すると `~/.dvm/` 以下にファイルが入りました。

```
ls ~/.dvm
bash_completion  dvm-helper/  dvm.sh
```

## fish に対応

fish を使っているので、fish用に書きなおしてくれている人がいないか探しました。

[Set up dvm command for fish shell.](https://gist.github.com/7sDream/69eb3ab8c8ca028c4975e922f356a96b)

上記のコードを読みこむ際にエラーが出てしまったので、最低限の部分だけ抽出することにしました。

### DVM_DIR 変数

これは決めうちで

```~/.config/fish/config.fish
set -x DVM_DIR $HOME/.dvm
```

することにしました。

### dvm function

[dvm.fish](https://gist.github.com/sosuke-k/fdcc563474acc6ae40daa637a6528c53)

このファイルを `~/.config/fish/functions/` 以下に置いています。

### 補完

[dvm_completion.fish](https://gist.github.com/sosuke-k/fdcc563474acc6ae40daa637a6528c53)


`bash_completion` を参考に、 `dvm` を今日入れた自分でもすぐ使いそうなものだけ、補完するようにしています。

```
complete -f -c dvm -n '__fish_dvm_using_command' -a "install uninstall use current ls ls-remote deactivate which"
complete -f -c dvm -n '__fish_dvm_using_command use' -a '(command ls $DVM_DIR/bin/docker)'
```

`completions` フォルダに置いたのですが読みこんでくれなかったのでとりあえず、無理やり読み込みました。

```~/.config/fish/config.fish
source ~/.config/fish/completions/dvm_completion.fish
```

## 補足

`dvm` function の中で `sed -r` を使っているのですが

```
sed: illegal option -- r
```

みたいなエラーが出たら [こちら](https://github.com/pyrsmk/molt/issues/8) を参考に `gnu-sed` を入れてみてください。
nomsのはじめ方

# はじめに

この記事は分散DBである**nomsのはじめ方**の日本語記事です

https://github.com/attic-labs/noms

## インストール

### Goをインストール

この辺を見てGoをインストール。

http://qiita.com/puttyo_bubu/items/4e60e42ff041f2474428

僕の場合GOPATHは`.bashrc`に以下を設定した。

```
export GOPATH=$HOME/go_work
export PATH=$PATH:$GOPATH/bin
```

### nomsをインストール

`go install`でインストールします。

```
git clone https://github.com/attic-labs/noms $GOPATH/src/github.com/attic-labs/noms
go install github.com/attic-labs/noms/cmd/noms
```

### 動作確認

デモ用のDBに接続します。

```
noms log http://demo.noms.io/cli-tour::sf-film-locations
```

## ローカルでサーバを立ち上げる

```
noms serve ldb:/tmp/uhuru-ds
```
### JSから接続する

Node.JSは6.xがいいです。

```
mkdir norm_js_example
cd norm_js_example
echo '{"name":"norm_js_example","version":"0.0.1"}' > package.json
npm install @attic/noms -S
```

noms serverに接続するための`main.js`を用意します。

```
"use strict";

const noms = require('@attic/noms');

const db = noms.DatabaseSpec.parse('http://localhost:8000').database();

let ds = new noms.Dataset(db, 'sensor');

// prints: null
ds.head().then(console.log);


setInterval(function() {
	let data = noms.newStruct('', {
	    temp: getSensorValue()
	  });
	ds.commit(data).
	  then(r => ds = r);
}, 1000);


function getSensorValue() {
	return Math.floor(Math.random() * 100);
}
```

作成したスクリプトを実行します。

```
noms-js-example$ node main.js
noms-js-example$ noms ds http://localhost:8000
sensor
```

```
syuhei@P280-MAC:noms-tour$ noms show http://localhost:8000::sensor
struct Commit {
  meta: struct {},
  parents: Set<Ref<Cycle<0>>>,
  value: struct {
    temp: Number,
  },
}({
  meta:  {},
  parents: {
    vm27jrrllt0ue2n74u00dcddatur97g8,
  },
  value:  {
    temp: 47,
  },
})
```

Histotyを確認する。

```
noms-js-example$ noms log http://localhost:8000::sensor
commit u1p29fssi2dt7rjni7a4cafln6ii4upa
Parent: vm27jrrllt0ue2n74u00dcddatur97g8
(root) {
-   temp: 83
+   temp: 47
  }

commit vm27jrrllt0ue2n74u00dcddatur97g8
Parent: d932uavaltd9aq2t6iv4kl4a5dveprtc
(root) {
+   temp: 83
-   temp: 200
+   temp: 83
  }

commit d932uavaltd9aq2t6iv4kl4a5dveprtc
Parent: 0bsvt46et6vqkks30rlr7bemtab63fhh
(root) {
-   temp: 100
+   temp: 200
  }

```



# 参照

https://github.com/attic-labs/noms