OmniAICreator/Qiita-1.07M huggingface dataset:
企業内NWでのMacOSアップデート

#問題
古いMac(MacBook Pro 13-inch,Late 2011)をHighSierraに更新しようとした際に次の問題に遭遇しました。
 - Lionを再インストールできない
 - LionからHighSierraに更新できない（ライセンスがない）
 - MountainLionをインストールできない
 - HighSierra起動時のセットアップに時間がかかる
社内利用であったために、一般家庭とは異なりプロキシーが存在したり、IPアドレスを手動設定していたことに起因するものでしたが、これらのエラーはNW設定以外が要因のこともあるようです。

#「Lionを再インストールできない」解決策
##症状
Command+Rでディスクユーティリティを起動しLionを再インストールしようとすると、「ご利用のデバイスまたはコンピュータを確認できません。詳細はサポートへご連絡ください。」の表示となる。
##解決策
Appleのサーバにアクセスできていない模様。Command+Rで起動した状態ではメニューからネットワークユーティリティを起動してみるとIPアドレスは適切に設定されていました。ヘルプ（Safari）を使うとローカルNW（社内）のサーバにはアクセスできるものの社外のWebサーバにはアクセスできないのでどうやらProxyサーバの設定が必要なようです。Command+Rで起動した状態ではシステム環境設定が使えないので、ターミナル（メニューから起動可能）して、[次のコマンド](http://hints.macworld.com/article.php?story=20120403034830403)を打つことで解決しました。

`networksetup -setwebproxy Ethernet 192.168.1.10 8080
 networksetup -setsecurewebproxy Ethernet 192.168.1.10 8080`
IPアドレスとポート(192.168.1.10 8080)は例です。

#「LionからHighSierraに更新できない」解決策
##症状
AppStoreにはHighSierraへのアップデートは無料とありますが、ボタンをクリックしてもアップデートできない。
##解決策
HighSierraへのアップデートにはMountain Lion（10.8）以上が必要です。LionからMountain Lionへのアップグレードは有償（2400円）です。
HighSierraにアップデートできる機種は[こちら](https://support.apple.com/kb/SP765?locale=ja_JP)。
Mountain Lionの購入は[こちら](https://www.apple.com/jp/shop/product/D6377Z/A/os-x-mountain-lion)
更新にはApple-IDが必須です。購入すると数日後に登録したメールアドレス（クレジットカード登録したアドレス）にライセンスIDが送られてきます。

#「MountainLionをインストールできない(1)」解決策
##症状
インストールしようとすると「The Recovery Server could not be contacted」が表示される。
##解決策
サーバへの接続ができない原因は複数考えられますが、私のケースはDNSの設定が不完全なためでした。システム環境設定の「ネットワーク」でDNSを設定することで解消しました。

#「MountainLionをインストールできない(2)」解決策
##症状
インストールボタンを押すと、
「You may not install to this volume because it is currently converting to Core Strage.」の表示が出る。
##解決策
FileVaultによる暗号化処理中のためでした。システム環境設定の「セキュリティとプライバシー」でFileVaultタブを選択すると処理状態を確認できます。
暗号化処理はクリーンインストール直後で8時間かかりましたので、FileVaultを入にするのは、OSの更新を完了してからの方が効率的です（暗号化処理中でも作業はできますが、OSのアップブレードはできません。）

#「HighSierra起動時のセットアップに時間がかかる」解決策
##症状
インストール後のアカウントログイン時に、品質情報の提供やSiriを利用可にすると、そこから先に進まない。
##解決策
インストールが完了するとネットワーク設定がデフォルト（DHCP利用）に戻っており外部との通信ができない状態になっていました。品質情報の提供やSiriの利用は、まずはログインしてネットワーク設定を行ってから、有効化するべきでしょう。


#番外：ディスクユーティリティ利用後に立ち上がらない
##症状
PGP（symantecのディスク暗号化ユーティリティ）をインストールした状態で、Command+Rで起動しディスクユーティリティを使った後で、再起動をかけるとMacintosh HDから立ち上がらなくなった。（「フォルダ？」マークが出る）
##解決策
クリーンインストールをするつもりだったので、Macintosh HDを初期化してOSをインストールしなおしたら解決しました。もしディスクに重要なデータが残っているような状態だと悲惨です。PGPの影響なのかは不明です。
MacはFileVault機能をOSが具備しているので、これを使う方がベターでしょう。
ただし、BootCampのエリアは[暗号化されないらしい](https://www.symantec.com/connect/ja/forums/some-important-feedback-symantec-regarding-pgp-vs-filevault-advantages-and-disadvantages-when)ので要注意です。
kintoneの本番環境・開発環境で異なるアプリIDを自動判定する方法

## はじめに
kintoneのJSカスタマイズで複数アプリを連携して何かする場合、
アプリIDをソースコード内に書かなければいけない場合があります。
例えばこんな風にやってる人は多いでしょう。

```js
const app = {
  customer: 10,
  order: 11,
}

kintoneUtility.rest.postRecords({
  app: app.customer,
  records: [ /* something */ ],
})
.then(resp => { /* do something */ })
```

## 複数環境に対応したい
ここで問題になるのが、開発環境・本番環境をドメイン・スペースなど複数使って分けている場合、それぞれの環境ごとにアプリIDが違うということです。

本番リリース時にappオブジェクト内の全IDを書き直して、次の開発時にまた開発用アプリIDに戻して…
みたいなことをするのが非常に手間だったので、
自動判定するようにしてみました。

## 別ドメインのアプリIDを自動判定
ドメイン名をキーにしたオブジェクトを作って、

```js
const App = {
  '<開発ドメイン>.cybozu.com': {
    customer: 10,
    order: 11,
  },
  '<本番ドメイン>.cybozu.com': {
    customer: 127,
    order: 128,
  }
}

const domain = location.hostname
const app = App[domain]

kintoneUtility.rest.postRecords({
  app: app.customer,
  records: [ /* something */ ],
})
.then(resp => { /* do something */ })
```

どうですか？？シンプルでとても使いやすくないですか？？
最初はwebpackの開発・本番の各設定ファイル内に分けて定義しようとしたんですが、
それだと再ビルドの手間もかかっちゃうので、普通にこっちの方が便利という結論になりました。
よかったら活用してみてください〜。

## 同一ドメイン別環境のアプリIDを自動判定

### スペースIDでの判定
本当は、同じドメインの中でもスペースで環境分けた場合に、
スペースIDもキーに含めてこんな風に書きたいんです。

```js
const app = App[domain][space]
```

でもスペースIDは[REST APIのapp.json](https://developer.cybozu.io/hc/ja/articles/202931674)使わないと取れないので、
非同期処理でその辺をやるのがとても面倒だったのでやめました。

### スペースIDを使わない判定（2018-09-13追記）
2018年1月の投稿時点では諦めてたんですけどね、
そのあと7月にね、思いついたんですようまいやり方！
（Qiita書くのが9月にもつれ込んでしまって申し訳ない・・・）

スペースIDは不要で、「現在のアプリID」をうまく使ってやれば良いのです！

```js
const environments = {
  '<開発ドメイン>.cybozu.com': [
    {
      // 開発環境
      customer: 10,
      order: 11,
    },
  ],
  '<本番ドメイン>.cybozu.com': [
    {
      // 本番環境
      customer: 127,
      order: 128,
    },
    {
      // ステージング環境
      customer: 129,
      order: 200,
    },
  ],
}

// まず現在のドメイン名で絞る
const spaces = environments[location.hostname]
// 次に現在のアプリIDを含む環境を1つ抽出
const app = spaces.find(s => Object.values(s).some(appId => appId === kintone.app.getId()))

// 以降の使い方は同じ！
kintoneUtility.rest.postRecords({
  app: app.customer,
  records: [ /* something */ ],
})
.then(resp => { /* do something */ })
```

ドヤァ。
これによって、同一ドメイン内に「本番環境」「ステージング環境」をそれぞれ用意して、スムーズに運用することが可能になりました :sunglasses: 

ちょっとネストが深いですが、一回定義してしまえば後はスムーズに動きます。そしてこの方法なら、スペース未所属のアプリを便宜上グループ化したい場合でも問題なく動きます :thumbsup: 

環境は3つでも4つでも好きに作ることができますので、みなさん是非お試しくださいね〜。

## サイボウズさんへ
スペースIDが簡単に取れればもっと色々スムーズなので、
JavaScript APIに `kintone.app.getSpaceId()` みたいな関数が欲しいです！
ぜひ機能追加お願いします！

そうそう、kintoneに機能追加してほしい要望などある場合、管理画面の「お問い合わせ -> ご意見・ご要望」から投稿すると、けっこう真剣に検討してもらえるみたいですよ！
僕もさっきこちらから要望出しときましたw

https://jp.cybozu.help/ja/general/admin/support.html
<img width="957" alt="スクリーンショット 2018-01-05 13.46.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/24333/5ba01ace-1cee-6098-31ce-e010e221b8b7.png">

皆さんも何かあればどんどん要望しちゃいましょう〜。

## 補足
ちなみにkintoneUtilityってのはこれです。
https://developer.cybozu.io/hc/ja/articles/115000333223
API経由のデータ転送は、このライブラリ使った方が断然便利なので、
僕は絶対こっち使うようにしてます。

ではまた〜。
PostgresSQL のerror　Postgres PG::ConnectionBad: could not connect to server: No such file or directory 	Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

# 環境
- macOS High Sierra
- psql (9.6.4)
- homebrew でpostgresをinstallした
- 一応Railsでつかっています。

# 結論
```
$ brew services start postgresql
$ brew services stop postgresql
$ brew services restart postgresql
```

brewでinstall したものの再起動のしかたを学びました。
これは他のbrewでinstallしたものにもつながるかもしれませんん！


# 流れ

急になぜか、下記のようなエラーがでてpsqlが起動しなくなってしまいました。

```
PG::ConnectionBad: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

この辺にかかれている
https://qiita.com/ms2sato/items/a0f7d32a3ecda76a7be3

```
rm /usr/local/var/postgres/postmaster.pid
```

を試すもうまくいかず。

ここに書かれている
https://qiita.com/lasershow/items/aa8025379edda760dad8

```
rm  -rf /usr/local/var/postgres/postmaster.pid
initdb /usr/local/var/postgres
```

をやろうかなって思いましたが、DBが初期化されてしまうようなので、もう少ししらべようかなと。

すると

https://make-from-scratch.com/error-connections-on-unix-domain-socket-tmp-s-pgsql-5432/

この方のブログにありました。

### twitterもフォローよろしくおねがいします。 ！
https://twitter.com/yoshixj
Androidプロジェクトに.rawprotoファイルが爆裂誕生している対策

GitへPushしようとすると、毎回diffに `./build/android-profile/` のデータが大量に爆誕していたので、付け焼き刃ですが対策しました。

# 何が起こってる？
なんだか大量にdiffが出るなぁと思っていたら、Androidプロジェクトの `./build/android-profile/` に、大量のファイルが生成されていました。
![スクリーンショット 2018-01-05 13.20.59.png](https://qiita-image-store.s3.amazonaws.com/0/84307/cd16f44d-14fd-a064-4037-932c534b3ab2.png)

生成されているファイルは、JSONと `rawproto` という拡張子のファイルです。
これらは2つのファイルが1セットでビルドの度に生成されます。

私の作っているアプリでは、1回のビルドで2ファイルの合計容量が約250KB前後でした。
そして、1210ファイル存在しました。
合計で300MBと、意外と少なくない容量です。
これらのファイルが何に使われるのかは調べきれず不明ですが、消しても問題ない気がします。

## 対策
こちらを参考にしました。
[オプションに「–profile」をつけて Run時間が1分から2秒になった話](https://android.benigumo.com/20160304/option-profile/)


これ（command-line optionsに--profileを付ける）をやると、上記のJSONとrawprotoファイルは生成されなくなり、
代わりに `./build/reports` ディレクトリが生成され、そこにビルドの結果が記載されたHTMLファイルが生成されます。

生成されるHTMLファイルは20KB程度ですので、約13分の1まで抑えられました。

## 他に嬉しい副作用
上記ブログにある通り、ビルドが高速になりました。
（ `./build/reports` が増えるので、 .gitignore の更新をお忘れなく！）

## 最後に
どなたかここで生成されていたJSONと `.rawproto` ファイルの用途をご存知であれば教えて下さいませ…
あと、そもそも生成を止める方法があれば知りたいです。
GitHub入門

#目的
GitHubに入門して、初めてlocal, remote repositoryを作成して投稿するまでの流れを備忘録を兼ねて書きます。

#Remote repositoryを作成する
まずは、GitHubのページでrepositoryを作成します。GitHubにアカウントを持っていない人は登録しましょう。

1. 画面右上のプラスボタンをクリックして、「New repository」をクリックします。
2. Repository Nameを記入します。
3. Public, Privateを選択する部分がありますが、無料版ではPublicしか選べません。
4. 更にその下に、ReadMeファイルを作るか、などありますがチェックはしないでおきます。最初、ReadMeファイルを作成したために、エラーが出てしまい苦労しました。

作成すると、
![Screenshot at 2018-01-05 11-01-36.png](https://qiita-image-store.s3.amazonaws.com/0/226092/d33b4f55-7d2d-2f9f-eeb5-c53f18fe0eaf.png)

このような画面が出ます。赤枠で囲んだ部分はrepositoryのアドレスで、このあとlocal repositoryとつなげるときに必要になりますのでコピーしておきます。

#Local repositoryを作成する
次に、パソコン上にlocal repositoryを作成します。コマンドライン上で、

```bash
$ mkdir git_test    #新しいフォルダを作成
$ cd git_test　　　　
$ git init    #local repositoryを作成
```
これでlocal repositoryが作成されました。この中にファイルを作成していきます。ここでは例として`test.txt`という簡単なテキストファイルを作りました。これを追加するには

```bash
$ git add test.txt 
$ git commit -m "This is a test file."    #コメント
```
などとします。

#GitHub上にPushする
では、local repositoryをGitHubのRemote repositoryにPushします。ここで、先ほど確認したRemote repositoryのアドレスを使います。

```bash
$ git remote add origin https://"アドレス"
$ git push -u origin master
```
これでPush完了です。

Remote repositoryを作成するときに、ReadMeファイルを作ってしまうと、Pushするときに

```bash
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/ /test.git'
ヒント: Updates were rejected because the remote contains work that you do
ヒント: not have locally. This is usually caused by another repository pushing
ヒント: to the same ref. You may want to first integrate the remote changes
ヒント: (e.g., 'git pull ...') before pushing again.
ヒント: See the 'Note about fast-forwards' in 'git push --help' for details.
```
なるエラーが出てきて、Pushできません。~~理由は謎です~~
Ruby で setuid, setgid を 設定, 解除する

Ruby で setuid, setgid を設定, 解除する

## サンプル
### setuid
```ruby
require 'fileutils'

IO.write("testfile", "")
# setuid を設定
FileUtils.chmod("u+s", "testfile")
printf "%o\n", File.stat("testfile").mode # => 104755
p FileTest.setuid?("testfile")            # => true
# setuid を解除
FileUtils.chmod("u-s", "testfile")
printf "%o\n", File.stat("testfile").mode # => 100755
p FileTest.setuid?("testfile")            # => false
```

### setgid
```ruby
require 'fileutils'

IO.write("testfile", "")
# setgid を設定
FileUtils.chmod("g+s", "testfile")
printf "%o\n", File.stat("testfile").mode # => 102755
p FileTest.setgid?("testfile")            # => true
# setgid を解除
FileUtils.chmod("g-s", "testfile")
printf "%o\n", File.stat("testfile").mode # => 100755
p FileTest.setgid?("testfile")            # => false
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [setuid - Wikipedia](https://ja.wikipedia.org/wiki/Setuid)
Action Cableでリアルタイムチャットアプリの作成方法 （Rails 5.1.4にて）（その3）　投稿をリアルタイムで削除する

#概要
この記事は[Action Cableでリアルタイムチャットアプリの作成方法 （Rails 5.1.4にて）（その2）グループ別チャンネルの作成！！](https://qiita.com/Hijiri-K/items/7e3c018c8330f69fc4cf)続きである。

今回は、投稿データをActionCableを使用してリアルタイムで消すという機能を実装したい。
誰かが、投稿の削除ボタンを押すと、ActionCableによってすべてのユーザーの画面から非同期通信でリアルタイムに投稿が削除される。

まず、すべての投稿に投稿idを個々の投稿divのidとして紐づける。
そして、ActionCableでそのidを送信し、それを使用して、jqueryのremove()を利用して、表示を消し、同時にdestroyでデータベースからも消す。

#環境
Ruby2.2.4
Rails 5.1.4

#手順
##1．投稿idをdivのidとして紐づけと削除ボタンの追加
通常の表示画面とActionCableのテンプレートの両方を編集する。

idの紐づけ：`<div class="posts-index-item" id="<%=post.id%>">`
削除ボタン： `<button id="<%=post.id%>" class="delete-btn">削除</button>`
削除アクションのトリガーのためにclassを`delete-btn`とする。

```html.erb:app/assets/view/posts/index.html.erb
  <div class="container">
    <%@posts.each do |post|%>
    <%user = User.find_by(id: post.user_id)%>
    <div class="posts-index-item" id="<%=post.id%>">
      <%if post.user_id%>
      <div class="post-user-name">
        <img src="<%="/user_images/#{user.image_name}"%>" alt="">
        <%=link_to("#{user.name}","/users/#{user.id}/show")%>
      </div>
      <%end%>
        <%=link_to(simple_format(post.content), "/posts/#{post.id}")%>
        <button id="<%=post.id%>" class="delete-btn">削除</button>
    </div>
    <%end%>

```
##2．deleteチャンネル・アクションの作成
[その1](https://qiita.com/Hijiri-K/items/c3774c72a2cb68e1a720)と同様の手順でチャンネルとアクションを作成する。

```
$rails g channel delete delete
```

##3. delete.coffeeの編集（クライアントサイド）
先ほど作成した削除ボタンをトリガーにしてdelete event.target.idで投稿idをidから取得しdeleteメゾットに渡す。
それによってdelete_channelのdeleteアクションを呼び、その際にもidを渡す。

```coffee:app/assets/javascripts/channels/delete.coffee
(...)
  delete: (id)->
    @perform 'delete', id: id


  $(document).on 'click', '.delete-btn', (event) ->
    App.delete.delete event.target.id
```

##4．delete_channelの編集（サーバーサイド）
delete.coffee（クライアントサイド）から受け取ったidをブロードキャストするのと同時に、投稿をデータベースからも削除する。

```rb:app\channels\delete_channel.rb
def delete(data)
    ActionCable.server.broadcast 'delete_channel', id: data['id']
    post = Post.find_by(id: data['id'])
    post.destroy
  end
```

##5．再度delete.coffeeの編集（クライアントサイド）
ブロードキャストされたものを受け取った時の処理を書く。
受け取ったidをjqueryで使えるように変換し、それを使いremove()で投稿を削除する。

```coffee:app/assets/javascripts/channels/delete.coffee
received: (data) ->
    # Called when there's incoming data on the websocket for this channel
    # 該当投稿の削除
    id = "#" + data['id']
    console.log(id)
    $(id).remove()
```

完成！！！
TeratermでIMAP4の操作をしてみる（注意点）

IMAP4メールクライアントアプリケーションの制作がてら、[TeraTerm](https://forest.watch.impress.co.jp/library/software/utf8teraterm/)でIMAP4サーバの操作をしてみました。

#リファレンス
## @ ITさんの連載
- 詳説 [前編](http://www.atmarkit.co.jp/ait/articles/0106/13/news001.html) [後編](http://www.atmarkit.co.jp/ait/articles/0107/03/news002.html) [拡張機能](http://www.atmarkit.co.jp/ait/articles/0203/23/news002.html)
- [IMAP4コマンド一覧](http://www.atmarkit.co.jp/fnetwork/rensai/netpro09/imap4-command.html)
- [SEARCHコマンドオプション](http://www.atmarkit.co.jp/fnetwork/rensai/netpro09/imap4-searchoption.html)
- [FETCHコマンドオプション](http://www.atmarkit.co.jp/fnetwork/rensai/netpro09/imap4-fetch.html)

#注意点
- IMAP4プロトコルでは、行の区切りは CR+LF です。TeraTermの初期設定では改行コードがCR+LFになっていないはずなので、「設定」メニューの「端末」から送信・受信とも改行コードを CR+LF に設定する必要があります（でないと、最初の応答メッセージのあと、コマンドを入力しても応答がなく固まります）同じく、ローカルエコーを有効にして、自分が入力した内容を表示させることがおすすめです。

![p1.png](https://qiita-image-store.s3.amazonaws.com/0/100206/cd1c238f-1ca9-25b1-e822-b913589e8b73.png)

#メモ
- パスワードなどの文字列中に括弧が含まれると解析に失敗してエラーが返されてしまいます。その場合、パスワードなどを "" で囲むと大丈夫です。
- STOREコマンドでつけられるフラグのうち、￥Deletedも恒久的とされ、LOGOUT（TCP接続解除）して再びログインしたあとも￥Deletedフラグはついたままです。この点、[POP3](http://www.atmarkit.co.jp/ait/articles/0106/05/news001.html)プロトコルのDELEコマンドとは異なります。
- STOREコマンドでメッセージに￥Deleted をつけると、同時接続中のThunderbirdなどではその段階でメッセージ一覧から消えます。コマンドを発行したクライアントだけではなく、同じ対象へ接続している各IMAP4クライアントへ、変更された内容が一斉配信されるようです。ちなみに
￥Deletedフラグを消すと、そのメッセージは一覧に復活します。完全に削除してストレージ使用量を減らすには、￥DeletedフラグをつけてからEXPUNGEコマンドを発行します。
- EXPUNGEコマンドの効果は、SELECTコマンドで選択中のメールボックス内のみです。 
- SEARCHコマンドのBEFOREオプションやSINCEオプションで指定する年月日の書式は、日付-月英略称-年（例：1-Jan-2018）です。([ご参考](http://www.chilkatforum.com/questions/369/imap-date-format-for-searching-email))
strptime gemで高速にTimeを文字列に変換する

## 背景

Rubyで時間表現を文字列に変換するには`Time#strftime`をよく使います．以下は公式リファレンスの例です．

```rb
t = Time.now                         #=> 2010-09-05 15:41:17 0900
t.strftime("Printed on %m/%d/%Y")    #=> "Printed on 09/05/2010"
```

これは楽でとても便利なんですが，`Time#strftime`には遅いという問題があります．例えばFluentdのような秒間数千数万とかのログの時間を任意の文字列に変換しないと行けないミドルウェアの場合，`Time#strftime`がパフォーマンス低下の一要因になります．

なので，定数倍でもここが高速化してくれると嬉しいなぁと，オフィスにいたRuby 2.5のリリースマネージャの方に相談したところ，`strptime` gemに`Strftime`を追加してくれました！

https://github.com/nurse/strptime#strftime-for-time-formatting

## 使い方

インストールは`gem install strptime`するだけです．使い方は`Strptime`と同じで，`Strftime`クラスを変換したいフォーマットで生成し，その後`exec`メソッドに`Time`オブジェクトを渡すだけです．処理結果は`Time#strftime`と同じになるように作られています．全てのフォーマットをサポートしているわけではありませんが(例えば`%F`などのショートカット)，プロダクションで利用されるようなフォーマットはほぼサポートされています．

```rb
require 'strptime'

now = Time.now
formatter = Strftime.new('%Y-%m-%dT%H:%M:%S.%L %z')
formatter.exec(now)        # 2017-12-29T07:24:31.505 +0900
formatter.execi(now.to_i)  # 2017-12-28T22:24:31.000 +0000
```

`Strftime`はあらかじめフォーマットをパースして専用の命令セットを構築し，変換する時にはその命令セットをなぞるだけになっています．なので`Time#strftime`で行われるような毎回のフォーマットのパースをスキップでき，その分高速化されています．

## ベンチマーク

`Strftime`を使えば，よく使われるフォーマットへの変換が高速化されます．以下が簡単なベンチマークスクリプトと手元のMBPでの結果になりますが，色々なケースで数倍高速されていることが確認出来ます．

- 結果

```sh
Time#strftime:%d/%b/%Y:%H:%M:%S %z          667.146k (± 7.5%) i/s -      3.340M in   5.035575s
Strftime#exec:%d/%b/%Y:%H:%M:%S %z            1.853M (± 8.3%) i/s -      9.242M in   5.024461s
Time#strftime:/path/to/log/file.%Y%m%d.log  683.880k (± 7.3%) i/s -      3.443M in   5.062916s
Strftime#exec:/path/to/log/file.%Y%m%d.log    1.965M (± 6.8%) i/s -      9.818M in   5.021328s
Time#iso8601                                427.001k (± 3.7%) i/s -      2.143M in   5.025909s
Strftime#exec:%Y-%m-%dT%H:%M:%S.%LZ           2.058M (± 3.6%) i/s -     10.287M in   5.006869s
```

- スクリプト

```rb
require 'benchmark/ips'
require 'time'
require 'strptime'

now = Time.now
Format1 = '%d/%b/%Y:%H:%M:%S %z'
strftime1 = Strftime.new(Format1)
Format2 = "/path/to/log/file.%Y%m%d.log"
strftime2 = Strftime.new(Format2)
strftime3 = Strftime.new('%Y-%m-%dT%H:%M:%S.%LZ')

Benchmark.ips do |x|
  x.report('Time#strftime:%d/%b/%Y:%H:%M:%S %z') {
    now.strftime(Format1)
  }
  x.report('Strftime#exec:%d/%b/%Y:%H:%M:%S %z') {
    strftime1.exec(now)
  }
  x.report('Time#strftime:/path/to/log/file.%Y%m%d.log') {
    now.strftime(Format2)
  }
  x.report('Strftime#exec:/path/to/log/file.%Y%m%d.log') {
    strftime2.exec(now)
  }
  x.report('Time#iso8601') {
    now.iso8601(3)
  }
  x.report('Strftime#exec:%Y-%m-%dT%H:%M:%S.%LZ') {
    strftime3.exec(now)
  }
end
```

## まとめ

ということで，もし`Time#strftime`を結構な頻度で呼び出すアプリケーションを書いてる人がいれば，`strptime` gemを使うと，パフォーマンスが改善すると思います．まぁ`Time#strftime`のパフォーマンスで困るようなRubyアプリケーションがそんなにあるとは思いませんが…
電子工作 > 磁石検知装置 > 555 Timer + 74HC04 + 振動モーター | ウェアラブル

[カギ閉め忘れ問題 > 対処案 v0.1](https://qiita.com/7of9/items/a2bb833caa91ab798188)
にて検討しているシステム。

[電子工作 > 磁石検知装置 > 555 Timer + 74HC04 + buzzer](https://qiita.com/7of9/items/ce9f5e3cbdbcca6b1213)
の続き。

ブザーは夜に動作確認できないため振動モーターに変更した。

![DSC_0292.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/2dd82fa9-da1f-1db8-b8a6-c2f6b42324f6.jpeg)

- A. 左上（黒）: [超小型振動モーター](http://eleshop.jp/shop/g/gCBR363/)
    - DC1.5V-3V
    - 50円
    - 黒色のゴムカバーが付属
- B. 右上（オレンジ）： Aと同じ?
    - オレンジ色のゴムカバーが付属
- C. 下(ボタン型): [振動モーター](http://eleshop.jp/shop/g/gCBR362/)
    - DC 3V 60mA
    - 50円

[日本電産の製品?](http://www.nidec.com/product/specific/vibration)

デジットにて購入。

B. 右上（オレンジ）をbuzzerの代わりに実装した。XHP用のリード線(AWG26?)を経由してユニバーサル基板に実装している。
buzzerはプラス端子側だけを切断していて、基板から取り外してはいない。

3.2VであったCR2032が200回の検知で2.65Vにまで下がっていた。
消費電力(待機時含む)については未調査。



### リンク

振動モーターは初めて使ったが、振動のために基板にかっちりと実装できないことに気づいた。
グルーガンなどで設置している例はある。

- [スイッチ入力ぶるぶる君 その１](http://mahoro-ba.net/e1768.html)
- [振動モータの位相制御](http://kaji-lab.jp/kajimoto/VibrationMotor.htm)
 
- [振動モータ技術紹介・原理機構](http://www.namiki.co.jp/product/vibration/motor/tech.html)
- [Micro Vibration Robot 振動モータを使ったラインとレースロボット](http://micro-vibot.blogspot.jp/2011/02/blog-post.html)

### ウェアラブル
(追加 2018/01/07)

グローブのようなものを作成してみた。

![DSC_0297.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/5a0b96dd-fdf8-76fa-7776-81146eaf9ed0.jpeg)

![DSC_0298.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/9fd2391f-0483-6589-ab25-563f8726acac.jpeg)

- 手の甲部分: パンチングレザー
    - 30cm 幅: 510円、の1/9程度使用 @ とらや商店(難波)
- 手のひら部分: 30円の端切れ @ とらや商店(難波)
- 側面部: ゴムベルト (30mm幅)
    - ４箇所に縫製
- パンチングレザー用糸: ししゅう糸 @ とらや商店(難波)
- 端切れ生地用糸: 30番

パンチングレザーから刺繍糸で基板を６点縫製しているが、手を動かしても安定している。
パンチングレザーのため、基板の脱着時に布をいためることがない。刺繍糸をやりかえるだけで良い。
側面のゴムベルトにより、手にフィットしている。

将来的によりフレキシブルなユニバーサル基板が登場したとすると、パンチングレザーの代わりの生地として使用して、直接ICを実装できるようになるだろうか。

なお、肝心の磁石検知機能は上部の写真に見られるような位置にネオジウム磁石をおいても検知せず、MM-DE21Pの直近に磁石がないと検知されなかった。

[磁気形近接センサ（定格と性能）](http://www.fa.omron.co.jp/guide/special/knowledge/prox/magnetic_type/ratings_characteristic.html)
> 磁性金属を検出する一体形の近接スイッチの動作距離は分離形に比べて一般に短くなる。リードスイッチ形で、3～20mm程度、固体磁気素子形ではさらに短くなり2～5mmとなる。誘導形近接スイッチと同じ程度である。
> 永久磁石を検出する分離形の場合には、リードスイッチ形で、10～100mm程度と比較的長距離となっている。固体磁気素子形では、2～10mm程度と短くなる。

### ウェアラブル (ESP8266)
(追記 2018/01/14)

![DSC_0305.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/0c79560c-14b5-7d7d-c727-71bda5d6516a.jpeg)

@ SF映画で学ぶインタフェースデザイン by MATHAN SHEDROFF, CHRISTOPHER NOESSEL, 安藤 幸央さん監訳
p238

> 「JM」では、タカハシが逆手の平手打ちのように空中で手を水平に強く振って、苛立たしいテレビ電話を終わらせる、という普通ではない手段で通話を終了させているのが見られます。...(図10.18)。

- 加速度センサーで手の動きの大きさを検知
- グロブ上でのESP8266から別のサーバーへ通信をする
    - Raspberry Piや別のESP8266など
- サーバーがなんらかの処理を行う

KinectやLeap Motionと比較した場合のUIの優位性はなにだろうか。
Kinectの場合は、カメラ?の設置位置が固定なので、カメラに正対して操作する必要はありそう。
Leap Motionについては以下だろうか。

http://techon.nikkeibp.co.jp/article/COLUMN/20140116/327883/?rt=nocnt
> Leap Motion Controllerは、CMOSイメージセンサーと赤外線LEDを内蔵し、外形寸法が80mm×30mm×11.5mm、重さ30gと小型の装置。装置の上方にある約60cm角の空間領域で物体の3次元の動きを±10μmの精度で検出し、パソコンなどの入力手段として利用できる。

上記が本当であるなら、検知装置が見えている範囲でのジェスチャー動作は可能であり、その範囲外でのジェスチャーは有効にはならない、と認識した。
Python3 の Scraping 基礎(JSON)

今回は，Python3を使ってWebスクレイピングの基礎について触れ合いたいと思います．また，スクレイピングするデータ形式はJSONとします．

## ライブラリインストール
スクレイピングするためのライブラリ：

- requests: HTTP ライブラリ
- beautifulsoup4: htmlパーサー(pythonから呼び出し)

```text
pip3 install requests
pip3 install beautifulsoup4
pip3 install lxml
```
## ライブラリの確認
```
pip3 freeze | grep -e request -e beautiful

   or

pip3 freeze 
```
## JSONについて

今回は，JSON形式のデータをスクレイピングしたいため．ここで，JSONについて簡単に説明を行います．
JSON は「JavaScript Object Notation」の略で、「JavaScript 言語の表記法をベースにしたデータ形式」と言えます。しかし、表記が JavaScript ベースなだけで、それ以外のさまざまな言語で利用できます。JSON では、ある数値と、その数値の名前であるキーのペアをコロンで対にして、それらをコンマで区切り、全体を波かっこで括って表現します。

``` JSON
[{
 "@type" : "LocalBusiness",
 "name" : "東京ディズニーランド(R)"
},
{
 "@type" : "LocalBusiness",
 "name" : "東京ディズニーシー(R)"
},
{
 "@type" : "LocalBusiness",
 "name" : "草津温泉"
},
{
 "@type" : "LocalBusiness",
 "name" : "みなとみらい21"
},
{
 "@type" : "LocalBusiness",
 "name" : "あしかがフラワーパーク"
}]
```

## 使用方法

まずライブラリのインポートを行います．

``` python
import requests  ##スクレイピング用
from bs4 import BeautifulSoup  ##スクレイピング用
import json  ##Python3 で JSON 形式のデータを扱う方法
```

HTMLの内容の取得を行います．

``` python
target_url = 'www.*****.com'
r = requests.get(target_url)         #requestsを使って、webから取得
``` 

htmlパース用のオブジェクト作成します。内部で利用するパーサーを指定する場合は、"html.parser"の部分を"lxml"などに変更します。

``` python
soup = BeautifulSoup(r.text "html.parser")
 or
soup = BeautifulSoup(r.content, 'lxml') ##要素の抽出
``` 
lxmlは速度が早いのでおすすめです．

ここで，注意すべきことは，文字化けです．
Requestsのr.encodingやr.textをそのまま使うと、文字化けしやすくなります。 回避できる方法は以下2つです．

- Chardetをインストールしておく
- BeautifulSoup()にr.contentを渡してBeautiful Soup側でデコードする

Chardetをインストールすると，大体の場合文字化けを回避できます。シンプルなのでオススメです。

## サンプルコード

``` python
min_page = 1
max_page = 550


while min_page <= max_page:
    target_url = "https://www.***/page_" + str(min_page) + ".com"
    print(target_url)  ## url表示

    r = requests.get(target_url)         ##　requestsを使って、webから取得
    soup = BeautifulSoup(r.content, "lxml") ##　要素の抽出

    ## 特定のタグの取得　(scriptタグのtypeのapplication/ld+jsonを指定)
    title_part = soup.find_all("script", {"type": "application/ld+json"})

    for i in title_part:
        title = i.get_text() ##タグの中のtext部分のみを指定

        ## JSON ファイルを load 関数で読み込むと、Python で扱いやすいように辞書型で保存されます。
        ## 辞書型なら要素の取り出しなどが容易に出来て便利です．

        a = json.loads(title)
        print(a) ## titleを表示

    min_page += 1 ##ページ数を1追加
```
Word&Excelの小技メモ

1. [ワードの表へ番号を振る](https://qiita.com/cmssai/items/e5f258df82e92f7d32d5)
1. [ワードで1枚の画像を2ページに分けて挿入する](https://qiita.com/cmssai/items/0e9dde85b379ff379d03)
1. [ワード文書内の全角半角文字を統一する](https://qiita.com/cmssai/items/5353436dc4752e4e4f66)
Unity Cloud BuildでのみPostProcessを無視したい

## `#if UNITY_CLOUD_BUILD`

UnityCloudBuildでのみxcodeの処理が失敗する! とか ~sdkが上手く動かない！ってことがあったときの対応。
UnityCloudBuildを判別するマクロが挿入されるので利用すれば良い.

```csharp
public class PostProcessBuilder
{
    [PostProcessBuild]
    public static void OnPostProcess(BuildTarget target, string buildPath)
    {
        // UNITY_CLOUD_BUILD を利用すれば、処理を分岐できる
#if UNITY_CLOUD_BUILD
            return;
#endif
i       // ...
    }
}
```
Word&Excelの小技メモ002

[Word&Excelの小技メモ](https://qiita.com/cmssai/items/62399091ab4d2a184f12) > 002.ワードで1枚の画像を2ページに分けて挿入する

# 002.ワードで1枚の画像を2ページに分けて挿入する

(1)Wordに画像を挿入する（ここではExcelで描いた図を貼り付ける）
![tech_21.png](https://qiita-image-store.s3.amazonaws.com/0/211906/8237c7e0-4f25-e313-3029-999dbf321701.png)

(2)図をコピーし、すぐ下の行に貼り付ける（同じ図が2枚縦に並ぶ）
![tech_22.png](https://qiita-image-store.s3.amazonaws.com/0/211906/b7f6088e-0447-358b-8c6d-3ddc4381c1bc.png)

(3)上の画像を右クリックして「図の書式設定」を選択する
![tech_23.png](https://qiita-image-store.s3.amazonaws.com/0/211906/89a58d1a-524f-34dc-6580-b9ed1f23a7ec.png)

(4)図の書式設定から「トリミング」を選択する
![tech_24.png](https://qiita-image-store.s3.amazonaws.com/0/211906/b521d6d8-610c-2ae4-fb9d-2d8e35a94eeb.png)

(5)トリミング位置の「高さ」を調節（値を減らす）してページに収まるようにする
![tech_25.png](https://qiita-image-store.s3.amazonaws.com/0/211906/5c3903c3-eacc-df25-ca7a-3827fca6e656.png)

(6)下の図をクリックし、トリミングの画像の位置から「縦方向に移動」を調整（値を減らす）して上の図の下端に合わせる
![tech_26.png](https://qiita-image-store.s3.amazonaws.com/0/211906/90f9d829-c4c8-736b-48f1-38ab6c65d9b6.png)

(7)トリミング位置の「高さ」を調節（値を減らす）して下側の空白を消す
![tech_27.png](https://qiita-image-store.s3.amazonaws.com/0/211906/ca4f82ba-9d79-d0d7-f7b9-a69fbe13a854.png)

※3ページ以上の場合でも同様に必要な部分をトリミングすると1つの図を分割することができる

[Word&Excelの小技メモ](https://qiita.com/cmssai/items/62399091ab4d2a184f12) > 002.ワードで1枚の画像を2ページに分けて挿入する
3GIM > Arduino UNO R3 から3G通信

以下の続きになります。
[3GIM > Arduino UNO R3 から3G通信 \- Qiita](https://qiita.com/sugasaki/items/6a0c76ef307eb9dd9a06)

# Arduino から3G通信
3G通信である3GIMを使った通信を始める準備編です。
Arduinoから3G通信を使ってクラウドやインターネットに情報を送る事ができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/49910/50a37df5-737f-f276-e43c-e06eecd5b9b1.png)

### 公式サイト
[3gim_v2 [3GIM Wiki]](https://3gim.wiki/doku.php?id=3gim_v2)

最初はいろいろ書いてあって頭がパニックになると思います。
慣れてくれば分かってくるので、最初はさらっと流し読みしましょう。

## 必用なもの

* 3GIMモジュール
* Arduino UNO、Mega
* SIM（マイクロSIM）
* プログラミング用のPC
* はんだ付けできる環境
* めげない心


## 対象のバージョン（2018/1/2現在）
今回では以下のバージョンを対象に説明します。
* 3GIM Ver 2.2
* Arduino UNO R3

## 説明
以下、それぞれについて説明します。

### 1. 3GIMモジュール
何はともあれ、まずはこれが必須です。
室内の開発がメインだったらロングアンテナ付がお勧めです。私はアンテナ無しを調達しましたが、後にロングアンテナ単体を追加購入しましたorz。　今でもロングアンテナ付きにしとけばよかったと後悔してます。

以下から購入できます。
[3GIM V2.2（3GロングアンテナおよびアクティブGPSアンテナ付き） - スイッチサイエンス](https://www.switch-science.com/catalog/3433/)

フレキアンテナもあった方がいいです。
[3GIM V2\.2用GPS専用フレキアンテナ \- スイッチサイエンス](https://www.switch-science.com/catalog/2610/)

### 2. Arduino UNO R3、Arduino Mega、Arduinoシリーズ
UNOか、Megaがあれば動かす事が可能です。
以降ではArduino UNO R3をベースに説明します。

以下から購入できます。
[Arduino Uno R3 \- スイッチサイエンス](https://www.switch-science.com/catalog/789/)


### 3. SIM（マイクロSIM）
Soracom SIMが安くて簡単で入門にはいいかと思います。
安いからと何枚も買ってしまうと月間維持費がのしかかってくるので注意。
最低料金：１枚あたり300円/月
Soracomはパッケージ売りの場合、SIM登録期限があるので注意です。

※他のカードは以下に利用実績一覧があります。
[3GIM - 利用実績のあるSIMカードについて](https://3gim.wiki/doku.php?id=sim)

### 4. プログラミング用のPC
MacでもWindowsでもOKです。（Macの方がドライバのインストール等、ちょっと楽です）
Arduino IDEを事前にセットアップしといてください。

[Arduino \- Software](https://www.arduino.cc/en/main/software)

ボードやらライブラリやら専門的な用語が出てきますが、おいおい慣れます。


### 5. はんだ付けできる環境
3GIMは基板単体で販売されているので、Arduinoとの接続の為にピンをハンダ付けが必用です。


### 6. めげない心
通信を扱う以上、待機時間が長い、検証時間が長い、使用場所の検証、いろんな事がでてきます。
しかし、これを乗り越えたらIoTは怖くありません。
大丈夫！3GIMに向かい始めたあなたならすでに一歩踏み出してます。



## おしながき

以下のリンクから各説明に飛びます。

* [3GIMとArduinoとの接続](https://qiita.com/sugasaki/items/16121b446d6ae13239fe)
* [3GIMの設定](https://qiita.com/sugasaki/items/29515142cf2f9fd62ebe)
* [Lチカ](https://qiita.com/sugasaki/items/b01ae6a8f12e67e9c077)
* [時刻取得](https://qiita.com/sugasaki/items/9f1c1e3d5c51ac3935a2)
* [GPSデータの取得](https://qiita.com/sugasaki/items/334b4181b9a1730d0002)
* [電波強度（rssi）の取得](https://qiita.com/sugasaki/items/ae791b041ae2f00509a6)
* 時刻取得
* 電波強度の取得
* IMEIの取得
* HTTP GET
* ライブラリの使い方
selenium webdriverでステータスコードのチェック

[テスト自動化ツール「selenium webdriver」最初の一歩](https://qiita.com/sssssumito/items/35f2d0c49c35ea44a755)に続きまして、少し実践的なテストコードを書いてみます。
どうやらselenium-webdriverではステータスコードのチェックができないようなので、仕方なくjavascriptを使ってゴニョゴニョすることにしました。

```ruby
class StatusChecker
  require 'selenium-webdriver'
  
  def initialize
    @driver = Selenium::WebDriver.for :firefox
  end

  def check(host, paths, protocol='http')
    return unless @driver
    @driver.navigate.to "#{protocol}://#{host}"
    puts "[host] #{host}"
    begin
      paths.each do |path|
        statuscode = get_statuscode(path)
        puts "#{statuscode}, #{path}"
      end
    rescue => e
      puts e.message
      quit
    end
  end

  def quit
    @driver.quit if @driver
    @driver = nil
  end

  private def get_statuscode(path)
    begin
      @driver.execute_script( get_statuscode_script(path) )
      element = nil
      loop do
        element = @driver.find_elements(:id, 'selenium_status')
        if element && element.size > 0
          if !element[0].attribute("value").empty?
            break
          end
        end
        sleep 0.5
      end
      return element[0].attribute("value")
    rescue => e
      raise e.message
    end
  end

  private def get_statuscode_script(path)
    script = %[
      var elm = document.getElementById('selenium_status');
      if( elm == null ) {
        elm = document.createElement('input');
        elm.id = 'selenium_status';
        document.body.appendChild(elm);
      }
      elm.setAttribute('value', '');
      
      var request = new XMLHttpRequest();
      request.open('get', '#{path}', true);
      request.onload = function (event) {
          elm.setAttribute('value', request.status);
      };
      request.onerror = function (event) {
          elm.setAttribute('value', request.status);
      };
      request.send(null);
    ]
    script
  end
end

checker = StatusChecker.new
checker.check('example.com', ['/', '/hoge/'], 'https')
checker.check('www.example.com', ['/', '/poge/'], 'https')
checker.quit
```

javascriptのところが冗長なので、本当は関数化してinitializeのタイミングで設置して使いまわすのが良いと思いますが、書き直すのが面倒だったのでこのまま公開しちゃいます。
気になる人は適宜修正してください。笑
homebrewインストール個人メモ

## 前書き

コメンドラインでインストール、アンインストールができるので愛用している
macOS用パッケージマネージャー、homebrewのインストール個人メモ。

## [Homebrew](https://brew.sh/index_ja.html)のインストール

```bash:インストール
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

```bash:確認(version)
$ brew --version
```

```bash:結果(version)
Homebrew 1.4.2
Homebrew/homebrew-core (git revision a4e3; last commit 2018-01-04)
```

myインストール

```bash
brew install wget
brew install tree
brew install sbt    # (java8必要)
```

## [Homebrew-Cask](https://caskroom.github.io/)のインストール



```bash:インストール
brew tap caskroom/cask
```

```bash:確認(version)
brew cask --version
```

```bash:結果(version)
Homebrew-Cask 1.4.2
caskroom/homebrew-cask (git revision 233b; last commit 2018-01-05)
```

```bash:確認(tap)
brew tap
```

```bash:結果(tap)
caskroom/cask
homebrew/core
```

myインストール

```bash
brew cask install google-chrome
brew cask install visual-studio-code
brew cask install sourcetree
brew cask install docker
```

## [homebrew-cask-versions](https://github.com/caskroom/homebrew-versions)のインストール

```bash:インストール
brew tap caskroom/versions
```

```bash:確認(tap)
brew tap
```

```bash:結果(tap)
caskroom/cask
caskroom/versions
homebrew/core
```


myインストール

```bash
brew cask install java8
```


以上。
Google Driveのチームドライブでディレクトリをコピー


Google Driveのチームドライブを使っていると、2018/01/05現在だとディレクトリコピー(再帰コピー)できないので困ることがあります。

そんなときは、Macであれば以下の手順で楽できるかもしれません。

## 手順

### 事前準備
**「Mac版ドライブファイルストリーム」**(専用クライアント)をインストールします。

上記アプリでGoogle Driveをマウントします。
私の環境では`/Volumes/GoogleDrive`にマウントしています。
以下のように調べられます。

```bash:マウントパス確認
$ df -h | grep drivefs
drivefs         16Ti    0Bi   16Ti     0% 18446744069414607612 4294967295 79201168131100448%   /Volumes/GoogleDrive
```

### 再帰コピーの実行

ターミナルを開いて、以下の手順を実行しましょう。

```bash:複製手順
$ mkdir /Volumes/GoogleDrive/チームドライブ/{{複製先ディレクトリ}}
$ cd {{複製元ディレクトリ}}
$ tar cf - * | (cd /Volumes/GoogleDrive/チームドライブ/{{複製先ディレクトリ}}/; tar xfp -)
```

要は`tar`で再帰コピーしているだけです。

## 最後に

条件やら環境やらクライアントバージョンやらで手順は変わるかもしれません。
2018/01/05現在のtipsということで。
Bitbucketでgit-ftpを自動化する

## 環境

タイトルにあるようにソースコードのホスティングにはBitbucketを使用する必要があります。

## はじめに

この記事は[こちら](https://qiita.com/sayama0402/items/d3d11bbc6b09b9b78527)の続きです。
コマンドで`git ftp push`をしたくなかったのと、push時に色々出来るようにしたかったので、Bitbucketのpiplinesを使って見ました。

> [こちら](https://qiita.com/sayama0402/items/d3d11bbc6b09b9b78527)の記事の続編であるため、`git ftp init`は終わっているという前提で進めていきます。

## 1.Bitbucketでpiplinesを有効化

Bitbucketではデフォルトでpiplinesが無効化されているので、有効化していきます。
リポジトリのページにアクセスをして、サイドバーの一番下の「設定」をクリックします。

![スクリーンショット 2018-01-05 10.57.11.png](https://qiita-image-store.s3.amazonaws.com/0/19716/db2d6647-1eac-fe16-caff-60ed930b27a2.png)

「設定」 → 「settings」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19716/91b1b2b4-0492-79e0-a4cd-176dc6d5948e.png)

「settings」をクリックしたら、以下のように有効化させます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/19716/96aa24e3-a4e7-a39f-090c-09b702b50c87.png)

以上でBitbucket側の設定は完了です。

## 2.bitbucket-pipelines.ymlに設定を記述

上記でpiplinesが有効化されたら、タスクを登録するためのファイルを作成します。
該当のリポジトリ内に`bitbucket-pipelines.yml`というファイルを作成します。

作成したら、以下を入力

```yml
image: samueldebruyn/debian-git

pipelines:
  default:
    - step:
        script:
          - echo "Pipline Start"
          - apt-get update
          - apt-get -qq install git-ftp
          - echo "start deploy"
          - git ftp push --user FTPのユーザー名 --passwd FTPのパスワード ftp://FTPのホスト/対象となるディレクトリ
          - echo "All done deploy"
```

例：

* FTPのユーザー名：ftp-user
* FTPのパスワード：ftp-user-pass
* FTPのホスト：example.xsrv.jp

とした場合は、以下のようになる。

```yml
image: samueldebruyn/debian-git

pipelines:
  default:
    - step:
        script:
          - echo "Pipline Start"
          - apt-get update
          - apt-get -qq install git-ftp
          - echo "start deploy"
          - git ftp push --user ftp-user --passwd ftp-user-pass ftp://example.xsrv.jp/
          - echo "All done deploy"
```

bitbucket-pipelines.ymlを設定し、masterにpushを行うと、piplinesが起動する。
piplinesの経過はリポジトリページの`piplines`で確認が出来る。
以上で、`git ftp push`をコマンドから実行しないで実行が可能となる。

## 3.設定情報を環境変数に置き換える

設定ファイルにパスワードなどを書き込みたく無い場合は、環境変数に置き換える。
設定→Piplines→Environment variablesをクリックする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/19716/ce0c399a-2048-0c9c-b133-3160fb28ce09.png)

環境変数を設定していく、一応簡易な手順

* 1.Variable name：変数名
* 2.Value：変数に代入する値
* 3.Securedにチェック入れてaddする

以下が設定された状態

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19716/453e1987-a766-aad2-42ed-75e17e0501a4.png)


2で設定した`bitbucket-pipelines.yml`を以下のように変更する。
Bitbucket側に環境変数を定義したので、該当部分を環境変数に変更していく。
設定した環境変数を用いる場合は、`$変数名`とする必要がある。

> 例：FTP_USERとした場合、$FTP_USERとymlファイルに記述する

```yml
image: samueldebruyn/debian-git

pipelines:
  default:
    - step:
        script:
          - echo "Pipline Start"
          - apt-get update
          - apt-get -qq install git-ftp
          - echo "start deploy"
          - git ftp push --user $FTP_USER --passwd $FTP_PASS $FTP_URL
          - echo "All done deploy"
```

上記が設定し終わったら、再度masterにpushをして確認してみる。
ここでこける場合は、bitbucket側の設定とbitbucket-pipelines.ymlの記述が正しく無い可能性があるので、チェックして見てください。
Androidでのギャラリー起動

メモとして残しておきます。


## ギャラリーから写真を取得する

ボタンを押したときなどギャラリーからデータを取得したいとき下記のメソッドを呼びます

```kotlin
　　　　　　　　/**
     * ギャラリーから写真を選択する
     */
    private fun selectPhoto(){
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
        intent.addCategory(Intent.CATEGORY_OPENABLE)
        intent.type = "image/*"
        startActivityForResult(intent, RESULT_PICK_IMAGEFILE )
    }

```


写真の選択が完了したら`Activity`内の`onActivityResul`メソッドが呼ばれます。

```kotlin
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

        if (resultCode == Activity.RESULT_OK) {

            // この辺でデータを取得していろいろやっちゃう
            Toast.makeText(this, "おk", Toast.LENGTH_LONG).show()
        }
    }
```

あとよしなにやるだけです。
参考にさせていただいたサイトに詳しく書かれていますので詳しくはこちらをご参考ください。

https://akira-watson.com/android/gallery.html
なぜmallocしている量が多くなるとforkが遅くなるのか？

# TL;DR

>It seems that even though the data of the allocated/used memory itself is not being copied, thanks to the copy-on-write feature, the internal virtual memory structures in the kernel, which hold the information about how much and what memory the parent process has allocated, are being copied in an inefficient way while the child process is being created by fork().
forkしたときコピー・オン・ライトによりmallocされたメモリそのものはコピーされないが、カーネル内部での仮想メモリの構造が非効率な方法でコピーされている。
https://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/



# 実験用プログラム

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    int count = 3000;   // forkする回数
    int mb = 10;        // mallocするサイズ（MiB）
    struct timeval tv1;
    struct timeval tv2;

    if (argc >= 2)
        mb = atoi(argv[1]);
    if (argc >= 3)
        count = atoi(argv[2]);

    printf("count = %d\n", count);
    printf("mb    = %d\n", mb);

    int len = 1024 * 1024 * mb;
    int size = sizeof(int) * len;
    int* p = malloc(size);
    // mallocしただけではカーネルはメモリを確保しないので書き込んでおく
    for (int i = 0; i < len; i++) {
        p[i] = i;
    }

    gettimeofday(&tv1, NULL);

    // fork
    for (int i = 0; i < count; i++) {
        if (fork() == 0) {
            exit(0);
        }
    }
    // 全子プロセスが終了するまで待つ
    while (wait(NULL) != -1) {
    }

    gettimeofday(&tv2, NULL);

    double elapsed = tv2.tv_sec - tv1.tv_sec + (tv2.tv_usec - tv1.tv_usec) / (1000.0 * 1000.0);

    printf("elapsed = %f\n", elapsed);
    return 0;
}
```

実行例

（10の部分を1から40まで変えて実行してみた）

```
./a.out 10
```

実験結果

```
FreeBSD
1   0.645625
10  1.102455
20  1.150587
30  4.327679
40  6.803514

Linux
1   0.445254
10  1.767612
20  3.032894
30  4.407658
40  5.822945
```
parcelでconsoleを残しつつビルドする

# 結論

[parcel/uglify.js](https://github.com/parcel-bundler/parcel/blob/261848cd5a399d0b3d665f4b0033e8d4a372b3d1/src/transforms/uglify.js)

のオプション値、`drop_console: true`を直接`false`に書き換える。

(キャッシュを削除しておくこと)

```js
  let options = {
    warnings: true,
    mangle: {
      toplevel: true
    },
    compress: {
      drop_console: true // ←ここ！
    }
};
```


# 現象

jsファイルを対象に
`parcel build hoge.js`
すると、

```
Dropping side-effect-free statement [0:1,0] 
```

という出力とともに、distに出力されるファイルから`console`系の記述が消える。

***

入門系の記事ではよく`console.log('Hello World')`するコードが見受けられる。
確かにエントリーポイントがHTMLならconsole.logは削除されない。
エントリーポイントがjsならモジュール的扱いになって副作用を排除しようとしているのだろうか？
いや、単純に拡張子ごとに

[～Asset.js](https://github.com/parcel-bundler/parcel/tree/5210bc685127596c8e8e48b64639021ccc9ace5d/src/assets)
が別れていて、`uglify`を呼び出すのが`JSAsset.js`のみだからだろうと予想する。

# 参考

[jsファイル中のconsole出力をminify時に削除する - Qiita]

[jsファイル中のconsole出力をminify時に削除する - Qiita]:https://qiita.com/vmmhypervisor/items/502481102748828c6dc3
Vagrantのマウントディレクトリ上でnpm installが失敗する場合の対処法

# はじめに

ハマったのが2回目なのでメモしておく
Vagrantのマウントディレクトリ上でnpm installが失敗します。
私の場合はシンボリックリンクが作れないよ。と怒られています。

```sh
npm ERR! Linux 3.10.0-514.el7.x86_64
npm ERR! argv "/usr/bin/node" "/bin/npm" "install" "serverless-offline" "--save-dev"
npm ERR! node v6.11.1
npm ERR! npm  v3.10.10
npm ERR! path ../babylon/bin/babylon.js
npm ERR! code EPROTO
npm ERR! errno -71
npm ERR! syscall symlink

npm ERR! EPROTO: protocol error, symlink '../babylon/bin/babylon.js' -> '/mount-dir/api/node_modules/.bin/babylon'
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /mount-dir/api/npm-debug.log
```

# 対処法

VagrantがマウントされたディレクトリをVM上のディレクトリだと思わせればよさそうです。

１．VM上にnode_modulesディレクトリを作成する

```sh
mkdir /home/vagrant/node_modules
```

２．Vagrantでマウントされたディレクトリ上にnode_modulesディレクトリを作成する

```sh
mkdir /mount-dir/api/node_modules
```

３．マウントする

```sh
mount --bind /home/vagrant/vagrant_node_modules /mount-dir/api/node_modules
```
Word&Excelの小技メモ001

[Word&Excelの小技メモ](https://qiita.com/cmssai/items/62399091ab4d2a184f12) > 001.ワードの表へ番号を振る

# 001.ワードの表へ番号を振る

(1)Wordで表を作る
![tech_11.png](https://qiita-image-store.s3.amazonaws.com/0/211906/ba8effb2-27d5-9703-6297-47925b528635.png)

(2)Excelを開く
(3)Excelの表で連番を作ってコピーする
　(セルに"1"を入力した後、そのセルの右下隅をctrlキーを押しながらマウスの左ボタンを押したまま下へドラッグすると連番が入力されるので、そのままctrl+cでコピーする)。
![tech_12.png](https://qiita-image-store.s3.amazonaws.com/0/211906/1f796035-d21f-6703-6a57-b4ab885fb515.png)

(4)Wordの表の対象部分を選択して貼り付けをする
![tech_13.png](https://qiita-image-store.s3.amazonaws.com/0/211906/a5f694aa-d559-2dba-5f13-dd204c3925d7.png)
※Excelで選択した行数よりもWordで選択した行数が少ない場合、Wordで選択した分のみコピーされるのがポイント

[Word&Excelの小技メモ](https://qiita.com/cmssai/items/62399091ab4d2a184f12) > 001.ワードの表へ番号を振る
curlでよく使うオプションメモ

よく使うわりにいつも忘れるcurlのオプション。

# メソッドを指定
`curl -X "POST" https://...`

Xオプション

# オレオレ証明の警告無視
`curl -k https://...`

kオプション

# Cookie埋める
`curl -b name=value https://...`

bオプション

複数個送りたい時はbを複数書くのではなく

`curl -b 'name=value&name2=value2' https://...`

という感じにする。

# リダイレクトに追従
`curl -L https://...`

Lオプション

# ヘッダを見る
`curl --head https://...`

これだとヘッダだけが出力される

`curl --include https://...`

こうするとヘッダも含めて出力される
RAID5の仕組み

RAID 5は、耐障害性の向上と高速化、大容量化のすべてを実現できるRAID技術である。

![raid5.gif](https://qiita-image-store.s3.amazonaws.com/0/155403/f4e7d857-0eed-fd97-c4a0-7a4f0266284f.gif)


######RAID 5の動作原理
######RAID 5は、エラーを修復するためのパリティ・データをデータ・ブロックの組ごとに生成し、分散して記録する。たとえ1台のディスクが壊れても、残りのディスクに格納されたデータとパリティから、失われたデータを復活させることができる。データを配分するときの単位サイズは、ブロック（セクタ）単位である。 


######また、どれか1台のディスクが故障しても、それ以外のディスクのデータとパリティ情報から、元の完全なデータを生成して回復できる。ただし、回復可能なのは1台のディスクが故障したときまでであり、同時に2台以上が壊れると回復は不可能になる。
x10のプログラムをstatic linkする

x10で書かれたプログラムをビルドされたバイナリ形式で配布して、ユーザーがx10ランタイムをインストールしなくても使えるようにしたい。
デフォルトではx10のランタイムは共有ライブラリにdynamic linkされるので、それをstaticにリンクする方法。

# 前提条件

- x10 2.6.1
- Native x10 (JavaではなくC++のバックエンド)
- Linux

# デフォルトでの挙動

x10の[公式サイト](http://x10-lang.org/)から配布されているx10コンパイラ(x10c)は、x10プログラムをコンパイルした後、x10のランタイムライブラリとdynamic linkする。

```shell
$ x10c++ -d build -o hello.out Hello.x10
$ ldd hello.out    # lddコマンドでどの共有ライブラリにリンクされているか表示される
        ...
	libx10.so =>  /home/..../x10/x10.dist/stdlib/lib/libx10.so
	libgc.so.1 => /home/..../x10/x10.dist/lib/libgc.so.1
	...
	libx10rt_sockets.so => /home/..../x10/x10.dist/lib/libx10rt_sockets.so
        ...
```

この通り、`libx10.so`, `libgc.so`, `libx10rt_sockets.so`の３つのファイル動的リンクされている。
一般のLinux環境ではこれらの共有ライブラリが無いので、これらをstatic linkしたい。

# 方法

配布されているコンパイラは`.a`ファイルを持っていないので、x10コンパイラとランタイムをソースからビルドする必要がある。
その際に環境変数`X10_STATIC_LIB=1`をセットすると静的なランタイムライブラリがビルドされる。

```
git clone git@github.com:x10-lang/x10.git
cd x10
# 必要であれば特定のタグをcheckout
cd x10.dist
export X10_STATIC_LIB=1     # static libraryを利用するためのフラグを環境変数で指定
ant dist                    # 必要に応じて -Davailable.procs=... -Doptimize=true -DNO_CHECKS=true
ls lib                      # lib/以下に.aファイルができているはず
ls stdlib/lib               # 同上
```

これでstatic linkする準備は整った。
しかし、この状態でコンパイルをしてもlibgcだけが動的リンクされたままになってしまう。
（これはx10のバグかもしれないのでgithubで[issue](https://github.com/x10-lang/x10/issues/24)を立てた。）

強制的にstatic linkするために`libgc.so*`を削除して.aだけ存在するようにする

```
rm -f lib/libgc.so*
```

これ以降x10c++でコンパイルすればstatic linkされるようになる。

# 注意事項

この方法はmacOS(clang利用)の場合、リンカオプションが適切にセットされないようでうまくいかない。（これもx10のバグ？）
TestFlightの使い方（テスター向け）

これは非開発者テスター [^1] 向けのTestFlight説明資料です。

開発者がテスターにTestFlight経由でアプリをインストールしてもらうための補助として使ってください。

# TestFlightとは

TestFlightはデバイス登録不要で
iOSアプリを試用できるというApple純正のベータテストの仕組みです。

10000人のテスターが、1つのバージョンを最大90日間、試用できます。

AppStoreで配布されるものと全く同じように使うことができます。
アプリ内課金も普段使われているAppleIDでテスト可能です（もちろん実際には課金されません）。

Apple Watchへのアプリのインストールもできます。

Apple公式サイト
https://developer.apple.com/testflight/

# 準備

TestFlightでアプリを配布する為にちょっとしたAppleの審査（ベータ版の審査）があります。

ベータ版の審査通過後、テスト参加者に招待メールが送られますので以下の準備をしてください。

* メールアドレスを開発者に伝える
  このアドレスに招待メールが送られてきます
  AppleIDとは関係なくても大丈夫ですが、iPhone/iPadで受信できるアドレスがいいです

* TestFlightアプリのインストール
  https://itunes.apple.com/jp/app/testflight/id899247664?mt=8

* TestFlightアプリでログイン
  AppleIDでログインしてください

同じAppleIDのもと、複数のデバイスでテストすることも可能ですので
もし複数のデバイスでテストしたい場合は、各デバイスにTestFlightアプリをインストールしてください。

# ベータ版アプリのインストール方法

以下の手順でインストールできます。

1. 招待メールが届きます（タイトル：XXX has invited you to test "YYY"）
![testflight_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/228129/8a34c4d6-62f5-8fa6-31af-87e6ed4de868.png)


2. iPhone/iPadでメールを表示し、メール内の「View in TestFlight」をタップ
   →TestFlightのアプリが起動

3. "YYY"のアプリ情報が表示されるので「ACCEPT」をタップ
4. 続けて「INSTALL」をタップ
   →アプリがインストールされます
![testflight_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/228129/e443ed5b-fb2e-7fff-c38e-ab384080bb5d.png)


TestFlight経由でインストールしたアプリはホーム画面上でアプリ名の左端にオレンジの丸印がつきます

Watchアプリがある場合は、iPhoneヘのインストール後に "Show App on Apple Watch" のスイッチが有効になるので
そのスイッチをONにすることでApple Watchヘインストールできます。
![testflight_3.PNG](https://qiita-image-store.s3.amazonaws.com/0/228129/e043f5cf-b250-4995-9027-2f79c71aa27a.png)


一度インストールしたあとは、ベータ版のアップデートがあるたびに
同じようにメールが配信されますのでTestFlightアプリにて「UPDATE」をタップして更新することができます。


[^1]: External Testerを想定
DockerのUbuntu16.04でtimedatectl出来ないときの対処法

## 問題

通常のUbuntuでは `timedatectl` を使ってシステムのタイムゾーンを変更できますが、
Dockerfileから使用した場合は以下のようなエラーで動作しません。

```sh
RUN timedatectl set-timezone Asia/Tokyo
 ---> Running in c1cb017f5384
Failed to create bus connection: No such file or directory
```

## 対処法

Dockerfileからシステムのタイムゾーンを変更する場合は以下のようにします。

```dockerfile
RUN apt-get install -y tzdata && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```
Beanstalk worker tierの 単一コンテナの Dockerを Docker for Macで起動するメモ

# Beanstalk worker tierの 単一コンテナの Dockerを Docker for Macで起動するメモ

- Worker tierのサンプルアプリケーションを Macでいじりたかった

## Docker for Macをインストール
- [Install Docker for Mac](https://docs.docker.com/docker-for-mac/install/)
 - Docker.dmgを実行して起動
- ```brew install docker```や VirtualBoxインストールは不要

## 単一コンテナの Docker をダウンロード

- [ステップ 4: 新しいアプリケーションバージョンのデプロイ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/GettingStarted.html#GettingStarted.Walkthrough.DeployApp)
 - docker-singlecontainer-v1.zip をダウンロードして解凍

## ビルド

```bash
cd docker-singlecontainer-v1/

ls
# Dockerfile		Dockerrun.aws.json	application.py		cron.yaml

docker build .
# (略)

docker images
# REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
# (略)

docker ps
# CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
# (略)

docker run -i -t $(docker images -q | head -1)
# (略)
# IOError: [Errno 2] No such file or directory: '/tmp/sample-app/sample-app.log'

vi application.py 
vi Dockerrun.aws.json 
# "/sample-app" を削る

docker build .
# (略)

docker images
# REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
# (略)

docker ps
# CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
# (略)

docker run -i -t $(docker images -q | head -1)
Serving on port 8000...
```

## ログイン

- 別コンソールより

```bash
cd docker-singlecontainer-v1/

ls
# Dockerfile		Dockerrun.aws.json	application.py		cron.yaml

docker ps
# CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
# (略)

docker exec -it $(docker ps -q | head -1) bash
# ログイン

root@xxxxxxxxxxxx:/# curl -XGET http://localhost:8000/
# <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
# <html>
# (略)

root@xxxxxxxxxxxx:/# exit
```
[PostEffect]ラスタースクロール

# 環境
- Unity5.5
- DOTween

ドラクエの旅の扉とか、マザーの戦闘シーンとかで画面の歪みを表現するのに使われてるらしい。
どこかの記事で読みましたが、ファミコン世代のレースゲームでコーナーを表現するのにも使われてたとかないとか。
先人の知恵は素晴らしいですね。

![raster.gif](https://qiita-image-store.s3.amazonaws.com/0/141994/152330c0-bad8-6d33-86f8-71e83db69398.gif)

Shader側のPropertyには

- speed : 周期の速さ
- amplitude : 揺れの強さ(振幅)

を定義します。

Y軸の１ライン(dot?)毎にxをスクロールさせます。
ただ全てのY軸のライン毎にｘをスクロールさせただけでは、テクスチャが横にずれていくだけなので
Sin波を利用して徐々にずらしていきます。

#Shader側

```glsl:RasterScroll.shader
Shader "Custom/RasterScroll"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
        _speed("speed", float) = 0.2
        _amplitude("amplitude", float) = 1.0
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			v2f vert (appdata v)
			{
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
			}
			
			sampler2D _MainTex;
            float _speed;
            float _amplitude;
            float _frequency;

			fixed4 frag (v2f i) : SV_Target
			{
                // 時間の取得
                float time = _Time.y * _speed;

                // y軸ライン上のx座標をずらす
                float dx = _amplitude * sin(radians((i.uv.y + time) * 360));

                // x成分をスクロールさせる
                i.uv.x += dx;

                return tex2D(_MainTex, i.uv);
			}
			ENDCG
		}
	}
}
```

#Script側

```csharp:RasterScroll.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class RasterScroll : MonoBehaviour {
    private Material material;

    /// <summary>
    /// 時間の進みの速さ
    /// </summary>
    [SerializeField, Header("周期"), Range(0.0f, 2.0f)]
    private float speed;

    /// <summary>
    /// 振幅
    /// </summary>
    [SerializeField, Header("振幅"), Range(0.0f, 2.0f)]
    private float amplitude;

    void Start ()
    {
        material = new Material (Shader.Find ("Custom/RasterScroll"));
    }

    void OnRenderImage (RenderTexture source, RenderTexture destination)
    {
        UpdateMaterial ();
        Graphics.Blit (source, destination, material);
    }

    void UpdateMaterial ()
    {
        material.SetFloat ("_speed", speed);
        material.SetFloat ("_amplitude", amplitude);
    }
}

```