OmniAICreator/Qiita-1.07M huggingface dataset:
How to export Cybozu Live My Calendar as iCalendar

## サイボウズLive マイカレンダー　を　Google カレンダー　に

 1. サイボウズ Live　 グループの　『イベントカレンダー』　については　iCalendar 出力できる
 　https://help.cybozulive.com/hlpb201206181140/

 1. My カレンダー については iCalendar 出力できません
 1. iCalendar 出力したい :exclamation:  - Cybozu Live API


### How to run Cybozu Live data API example codes 
- Source : https://developer.cybozulive.com/doc/current/pub/samples.html

- but the codes are Not working at all ... :expressionless: 

- current version of Python icalendar 3.11.2, however the example codes does NOT work with it.
- [x] :information_source: **Need to install icalendar 2.2** to run examples above :frowning2: 

### Environment
 - CentOS 7.3
 - Python 2.7.5

---
### easy_install pip

```shell-session
# easy_install pip
```

### pip install icalendar==2.2

```shell-session
# pip install icalendar==2.2
Collecting icalendar==2.2
  Using cached icalendar-2.2.tar.gz
Requirement already satisfied: setuptools in /usr/lib/python2.7/site-packages (from icalendar==2.2)
Installing collected packages: icalendar
  Running setup.py install for icalendar ... done
Successfully installed icalendar-2.2
```

### httplib2 oauth2

```shell-session
# easy_install httplib2
Searching for httplib2
Reading https://pypi.python.org/simple/httplib2/
Best match: httplib2 0.9.2
Downloading https://pypi.python.org/packages/ff/a9/5751cdf17a70ea89f6dde23ceb1705bfb638fd8cee00f845308bf8d26397/httplib2-0.9.2.tar.gz#md5=bd1b1445b3b2dfa7276b09b1a07b7f0e
Processing httplib2-0.9.2.tar.gz
Writing /tmp/easy_install-uF92dS/httplib2-0.9.2/setup.cfg
Running httplib2-0.9.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-uF92dS/httplib2-0.9.2/egg-dist-tmp-KIqNK_
zip_safe flag not set; analyzing archive contents...
httplib2.__init__: module references __file__
Adding httplib2 0.9.2 to easy-install.pth file

Installed /usr/lib/python2.7/site-packages/httplib2-0.9.2-py2.7.egg
Processing dependencies for httplib2
Finished processing dependencies for httplib2
```

```shell-session
# easy_install oauth2
Searching for oauth2
Reading https://pypi.python.org/simple/oauth2/
Best match: oauth2 1.9.0.post1
Downloading https://pypi.python.org/packages/64/19/8b9066e94088e8d06d649e10319349bfca961e87768a525aba4a2627c986/oauth2-1.9.0.post1.tar.gz#md5=22d49051d1d19d9ec17df480a463d0bb
Processing oauth2-1.9.0.post1.tar.gz
Writing /tmp/easy_install-vg8Nq_/oauth2-1.9.0.post1/setup.cfg
Running oauth2-1.9.0.post1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vg8Nq_/oauth2-1.9.0.post1/egg-dist-tmp-vQHvU9
Adding oauth2 1.9.0.post1 to easy-install.pth file

Installed /usr/lib/python2.7/site-packages/oauth2-1.9.0.post1-py2.7.egg
Processing dependencies for oauth2
Finished processing dependencies for oauth2
```


:tada:
github の2段階認証を github にリセットしてもらった話

# 結論

ちゃんと Recovery codes を保存したり， Fallback SMS number を保存しておきましょう．
それをしていない場合はお手上げですが， github を ssh で使用している場合，次の方法で解決する場合があります．

> 自分のアカウントでログインしている端末上で
> 
> ```
> $ ssh -T git@github.com verify
> ```
> を実行し，その結果を github の support に送って，本人確認が取ってもらう．

確認が取れれば github の中の人が 2FA をオフにしてくれます．
その後，改めて 2FA をオンにし Recovery codes を保存したり Fallback SMS number を設定したりするのを忘れずに設定しましょう．

## 自分のアカウントでログインされているかを確認する

**解決する場合があります** ，と書いたのは「その端末でログインしているアカウントが本当に自分のアカウントの場合である」という条件が付くからです．(当たり前と言えば当たり前ですが)
自分の場合，最初2回程「送られたコード違うよ」「別のアカウントぽいよ」って返事が来てしまって???ってなったんですが，
確認したら別のアカウントでログインしてる状態になっていました．

github への ssh で，どのアカウントでログインしているかを確認するには

```
$ ssh -T git@github.com
Hi takesato! You've successfully authenticated, but GitHub does not provide shell access.
```
と， `ssh -T git@github.com` を実行すれば ok です．

ちなみに別のアカウントになっていた理由は ssh-agent に別の秘密鍵が登録されたままになっていた為でした．
ssh-agent が有効の場合，正しい秘密鍵を `-l /path/to/id_rsa` で渡しても駄目みたいです．
(1回目はそのまま，2回目は `-l` を付けて，3回目は ssh-agent に登録されてる鍵を削除して github に伝えたんですが3回目でやっと一致しました)

# 余談

## なんで github にリセットして貰う事になったのか

が実は謎です．
ちょうど年末に iPhone の機種変更をし Google Authenticator が引き継がれなかったので，どうせなので新端末側で 1Password に 2FA を発行しなおして登録，年明けにその 2FA でログインして仕事を始めたはずなんですが，仕事始めて4日目位に急にログインできなくなりました．
再設定した際に 1password に保存したから複数端末でみれるし， Recovery codes 無くても良いかな…って考えていたのが甘かったという話．
Recovery codes を保存していなかったり Fallbackk SMS number を設定していない人は今すぐしましょう

## 不要になった公開鍵を消したい場合

なんで verify code が一致しないか調べてる時に知ったのですが，
github の管理ページから不要な鍵を消したい場合，管理ページからだと公開鍵の中身が見れないのでどれがどの公開鍵かわからない場合は，
```
$ ssh-keygen -l -E md5 -f ~/path/to/id_rsa.pub
2048 MD5:44:e4:c5:40:1b:36:30:c4:7a:7b:39:5b:87:2d:67:ec user@machine.local (RSA)
```
とやってでてくる finger print を比較するのが良いようです．
プログレッシブWEBアプリの情報をまとめました。


Progressive Web App(PWApp)とは？
Progressive Web App (PWA) is a term used to denote a new software development methodology. Unlike traditional applications, progressive web apps are a hybrid of regular web pages (or websites) and a mobile application.

[はじめてのプログレッシブ ウェブアプリ](https://developers.google.com/web/fundamentals/getting-started/codelabs/your-first-pwapp/?hl=ja)
本家GoogleのDevポータルの記事

[プログレッシブウェブアプリ詳解 ─ 過去・現在・未来](https://html5experts.jp/agektmr/20527/)
日本語でPWAppを解説した記事

[Googleが新たに提唱するProgressive Web Appsの新たな開発パターン「PRPL」とは？](https://html5experts.jp/komasshu/19704/)
PWAppの開発における問題点を考察している記事

[What is the good framework to build progressive web app?](https://www.quora.com/What-is-the-good-framework-to-build-progressive-web-app)
PWApp開発用に良いフレームワークありませんか？というQuoraの投稿。
以下は、この記事で紹介されているFrameworkやサービス。

[Polymer](https://www.polymer-project.org/1.0/)
[Ionic](http://ionic.io/)
[Firebase](https://firebase.google.com/)
AndroidStudioでパッケージ内のファイルをコピー

はじめに
--------------------------------------------------------------------------------

例）Windows + AndroidでDBにRealmを使用していてDBの中身を確認したいが、
Realm BrowserがあるのはMacなのでMacにRealmファイルをコピーしたい、といった場合の方法です。

全体の流れ
--------------------------------------------------------------------------------

1. ADB コマンドでデバイスに接続する
2. デバイスのパッケージ内に移動し、コピーしやすい場所にファイルをコピーする
3. ADB コマンドでファイルを取得する

ADB コマンドでデバイスに接続する
--------------------------------------------------------------------------------

#### ※この操作は AndroidStudio があるマシン上の操作です

1. ADBコマンドにパスを通しておく
    - ADBコマンドは次の様な場所にある。 C:\Users\ユーザー名\AppData\Local\Android\sdk\platform-tools
2. ADBコマンドでデバイス一覧を取得する
    - `adb devices`

    > こんな感じでデバイス名が分かる
    > List of devices attached
    > emulator-5554      device

3. ADBコマンドでデバイスに接続する
    - `adb -s emulator-5554 shell`

デバイスのパッケージ内に移動し、コピーしやすい場所にファイルをコピーする
--------------------------------------------------------------------------------

#### ※この操作は接続したデバイス内の操作です

1. パッケージ内に移動する
    - `run-as jp.co.xxxxx.example`
2. アクセスしやすい場所にファイルをコピーする
    - ここでは `/sdcard` にコピーしている
    - `cp files/default.realm /sdcard`
3. デバイスから抜ける
    - `exit`
    - ※ 最初のADBコマンドを実行していたプロンプトまで戻る

ADB コマンドでファイルを取得する
--------------------------------------------------------------------------------

#### ※この操作は AndroidStudio があるマシン上の操作です

1. ADBコマンドでファイルを取得
    - `adb pull /sdcard/default.realm /Users/xxxx/Downloads`
vbaのApplication.GetSaveAsFilename のInitialFilenameが表示されないとき



```
    sFileName = "ほげー.xlsm"
    Dim vntFileName As Variant
    vntFileName = Application.GetSaveAsFilename(sFileName)
```
として、InitialFilenameが表示されない場合がある。

どうもosとかexcelのバージョンに依存するっぽいけれど、解決できたっぽいのでメモ。



__★FileFilterにInitialFilenameの拡張子を指定する★__

たとえば、下記。

```
    sFileName = "ほげー.xlsm"

    Set FSO = CreateObject("Scripting.FileSystemObject")
    extName = FSO.GetExtensionName(sFileName)
    

    Dim vntFileName As Variant
    vntFileName = Application.GetSaveAsFilename(sFileName, "Excelファイル,*." & extName)
```
JavaScriptで日付をJDBCタイムスタンプエスケープ形式に変換する

JavaScriptで日付を「yyyy-mm-dd hh:mm:ss.fffffffff」の文字列（JDBCタイムスタンプエスケープ形式）にフォーマットする。

```javascript
/**
 * エポックタイムあるいは「Wed Feb 01 2017 00:00:00 GMT+0900 (東京 (標準時))」を
 * 「yyyy-mm-dd hh:mm:ss.fffffffff」の文字列（JDBCタイムスタンプエスケープ形式）にして返す。
 */
function formatTimestamp(timestamp) {

    // Dateオブジェクトを作成
    var d = new Date(timestamp);

    var year = d.getFullYear();
    var month = (d.getMonth() + 1 < 10) ? '0' + (d.getMonth() + 1) : d.getMonth() + 1;
    var day = (d.getDate() < 10) ? '0' + d.getDate() : d.getDate();
    var hour = (d.getHours() < 10) ? '0' + d.getHours() : d.getHours();
    var min = (d.getMinutes() < 10) ? '0' + d.getMinutes() : d.getMinutes();
    var sec = (d.getSeconds() < 10) ? '0' + d.getSeconds() : d.getSeconds();
    var str = year + '-' + month + '-' + day + ' ' + hour + ':' + min + ':' + sec + '.000000000';

    return str;
}
```
Windows10でvimのNeoBundleを使用する

#はじめに
いまさら？と思われるかもしれませんが、Windows10でvimのNeoBundleを使えるように設定した際のメモです。
私のような素人にはややハードルが高かったですが、
使えるようになると便利さが少しずつわかってきますね。

ざっくりと次のような流れです。
1. コマンドプロンプトを使ってvimフォルダの下にNeobundleインストール
2. vimrcを編集してNeobundleを使う



Git for WindowsとkaoriyaVim7.4がインストールされている前提で記載させていただいています。
Gitのインストール方法は次のページに書いてくださっています。
[コマンドラインからGitを使う（for Windows）](http://qiita.com/taipon_rock/items/632c117220e57d555099)

#フォルダの作成とNeobundleのインストール
ネットに投稿されているvim情報はUnix環境が前提とされているものが多く、
Windows環境ではうまくいかないことがありますよね。
（生粋のvimmerはWindowsなど使わんのですかな・・）

例えばNeoBundleのインストール方法をググってみると
次のようにディレクトリを作成されている方が多いです。
`~/.vim/bundle`
これは「.vim」という名前フォルダを作って
そのさらに下に「bundle」という名前のフォルダを作りましょうという意味です。

ただし、Windows環境では
新規作成→フォルダ→名前変更
としても
.vimという名前をつけることができないと思います。
別名のフォルダを作成してもよいのですが、先人たちと同様に作ったほうが何かと便利です。

Windowsではコマンドプロンプトを立ち上げて、次のように打ち込めばよいです。
ここではvimをインストールしたディレクトリの下にNeobundleをインストールします。

```cmd.exeにて
cd C:\Program Files\vim74-kaoriya-win64
mkdir .vim\bundle
git clone https://github.com/Shougo/neobundle.vim .vim/bundle/neobundle.vim
```

うまくいけば次のように表示されます。
.
![image](https://qiita-image-store.s3.amazonaws.com/0/159523/2a2c5856-a7ad-5a0c-eabf-56b59e21b61c.png)


# vimrcの設定
vimrcの設定でも一難あります。
vimrcで、先ほどインストールしたneobundle.vimへのパスを追加するときに、
Windows流儀でフルパスを書いてもうまく通らないことがあります。
「C:」のコロンや「Program Files」の半角スペースが原因と思います。
このときneobundleへのパスが通っていないので、
`未知の関数です:neobundle#begin`
というエラーが出ます。

そこでパスを正しく通すために
vimrcで設定するneobundle.vimのパスの記述には「$VIM」を用います。
※vimのディレクトリ（C:/Program_Files/vim74-kaoriya-win64　= ＄VIM）にneobundleをインストールしたので。

次の内容をvimrcに追加することでneobundleが使えるようになります。
Shougo/unite.vimをインストールして用いる例です。

```vim:vimrc
filetype plugin indent off
if has('vim_starting')
    set runtimepath+=$VIM/.vim/bundle/neobundle.vim
    call neobundle#begin(expand('$VIM/.vim/bundle/'))
      NeoBundleFetch 'Shougo/neobundle.vim'
      NeoBundle 'Shougo/unite.vim'
    call neobundle#end()
endif
filetype plugin indent on
```

上記を記述してvimを再起動してShougo/unite.vimのインストールを尋ねられたら成功です。
vimにて
`:Unite file`
と打つとフォルダの構成が表示されます。便便便利ですね！
Excel でグラフや図形が見えない場合のチェックポイント

Excel でグラフが見えなくなったときの覚書。
ファイル→オプション→詳細設定の「表示」セクションにある、「ハードウェアグラフィックアクセラレータを無効にする」をチェック（有効化）すると、現象が改善される模様。
次世代jpegエンコーダのGoogle製「guetzli」とMozilla製「mozjpeg」を比較してみる

googleがguetzliをOSS化したので、以下の次世代Jpegエンコーダーを比べてみる
[Google/guetzli](https://github.com/google/guetzli) v0.1
[mozilla/mozjpeg](https://github.com/mozilla/mozjpeg) v3.1


各コマンドはこんな感じ

guetzli

```
./guetzli --quality 90 bees.png bees_gue90.jpg
```

mozjpeg

```
convert bees.png pnm:- | mozcjpeg -quality 90 > bees_moz90.jpg
```

## エンコード

試した画像はguetzliにサンプルとしてリンクされているこちらの蜂の画像
https://github.com/google/guetzli/releases/download/v0.1/bees.png

オリジナルサイズ： 177KB

| quality | guetzli | mozjpeg |
|:-:|:-:|:-:|
| 指定なし | 38KB | 16KB |
| 100 | 148KB | 75KB |
| 95 | 38KB | 35KB |
| 90 | 26KB | 25KB |
| 85 | 20KB | 20KB |
| 80 | error | 17KB |

※guetzliはdefault qualityが95, mozcjpegは75

※`./guetzli --quality 80 bees.png bees_gue80.jpg`　だと以下のようなエラーになる。

```
Guetzli should be called with quality >= 84, otherwise the
output will have noticeable artifacts. If you want to
proceed anyway, please edit the source code.
Guetzli processing failed
```

## 結果

いまのところ、mozcjpegが優秀
Cognosの導入がうまくいかないパターン② - DB2のOracle互換

Cognos BIやCognos Analyticsのセットアップで、色々なパターンでうまく行かない事がありますが、思い出した順に投稿します。

これも何度か経験しましたが、Content StoreにDB2を用いていて、Cognosの初期起動時にContent Storeに以下のメッセージで接続できないと言うエラーになります。

CM-CFG-5063 A Content Manager configuration error was detected while connecting to the content store. CM-CFG-5114 An error occurred while locking the content store database. Cause: Assignment of a NULL value to a NOT NULL column "TBSPACEID=5, TABLEID=5, COLNO=0" is not allowed.. SQLCODE=-407, SQLSTATE=23502, DRIVER=3.58.68 Stack trace: com.ibm.db2.jcc.am.no: Assignment of a NULL value to a NOT NULL column "TBSPACEID=5, TABLEID=5, COLNO=0" is not allowed.. SQLCODE=-407,
![image](https://qiita-image-store.s3.amazonaws.com/0/147246/207ff1ac-b032-8716-9422-9b849dbf4ca7.png)

これはDB2でOracle互換モードを使用している事が問題ですが、中々気がつきにくい事象です。

db2setコマンドで以下が設定されている場合、設定を削除して、DB2を再起動後、Cognos初期起動によりContent Storeのテーブルの再生成を行ってください。
DB2_COMPATIBILITY_VECTOR=ORA


Technoteもあります。
**"Assignment of a NULL value to a NOT NULL column "TBSPACEID=5, TABLEID=5, COLNO=0" is not allowed" when starting Cognos service for the first time, due to DB2 using Oracle compatibility mode**
http://www-01.ibm.com/support/docview.wss?uid=swg21677923
circleCIでyarnpkg組み込んだんだけど、気づいたらfailになってた

最近、circleCIにyarnを組み込んだ。

どっかのブログからコピペして一時期使えてたけど、
yarnのバージョンアップによりエラーが出るようになってしまった。


すでにディレクトリあるんだけど！！！
みたいなエラーメッセージがでてたけど、コピペして残すの忘れた。

とりあえず、いい感じで下記を組み込んでもらえれば動くと思います。

```yaml:circle.yml
machine:
  node:
    version: 7.2.0
  environment:
    YARN_VERSION: 0.18.1
    PATH: "${PATH}:${HOME}/.yarn/bin:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin"
dependencies:
  pre:
    - |
      if [[ ! -e ~/.yarn/bin/yarn || $(yarn --version) != "${YARN_VERSION}" ]]; then
        curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version $YARN_VERSION
      fi
  cache_directories:
    - ~/.yarn
    - ~/.cache/yarn
  override:
    - yarn install
```

# 参考資料
Using Yarn (an NPM alternative) on CircleCI  - CircleCI https://circleci.com/docs/2.0/yarn/
AWS LambdaからHLSストリームのスナップショットを撮る


## 環境

- AWS Lambda
- python 2.7
- livestreamer 1.12
- ffmpeg 2.4.2

## Installation 

- Livestreamerをローカルインストール

```bash
pip install livestreamer -t .
```

- Lambda用にffmpegのバイナリをダウンロード

```bash
$ wget https://github.com/imageio/imageio-binaries/raw/master/ffmpeg/ffmpeg.linux64 -O ffmpeg
$ chmod +x ffmpeg
```

### 撮り方

`lambda_function.py`

```python
import livestreamer
import time
import subprocess

def lambda_handler(event, context):
  url = "hlsvariant://serverIp/application/stream/playlist.m3u8"
  streams = livestreamer.streams(url)
  stream = streams["best"]
  fd = stream.open()
  data = ''
  while len(data) < 3e5:
    data += fd.read(100000)
    time.sleep(0.1)
  fd.close()

  fname = '/tmp/stream.bin'
  open(fname, 'wb').write(data)

  cmd = "./ffmpeg -i /tmp/stream.bin -vframes 1 snapshot.png -y"
  proc = subprocess.Popen(shlex.split(cmd),
          stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  res = proc.communicate()
  print(res[0])
```

#### 解説

- HLSストリームを300KBだけ読み込み

```python
url = "hlsvariant://serverIp/application/playlist.m3u8"
streams = livestreamer.streams(url)
stream = streams["best"]
fd = stream.open()
data = ''
while len(data) < 3e5:
 data += fd.read(100000)
 time.sleep(0.1)
fd.close()

fname = '/tmp/stream.bin'
open(fname, 'wb').write(data)
```

- ストリームのバイナリからffmpegで1フレームだけ出力

```python
cmd = "./ffmpeg -i /tmp/stream.bin -vframes 1 snapshot.jpg -y"
proc = subprocess.Popen(shlex.split(cmd),
      stderr=subprocess.PIPE, stdout=subprocess.PIPE)
res = proc.communicate()
print(res[0])
```

### デプロイ

- terraformでデプロイ

```bash
zip -r snapshot_livestream.zip *
```

```python
resource "aws_lambda_function" "snapshot_livestream" {
    filename = "snapshot_livestream.zip"
    source_code_hash = "${base64sha256(file("snapshot_livestream.zip"))}"
    description =  "Take a snapshot of livestream"
    function_name = "snapshot_livestream"
    runtime = "python2.7"
    timeout = 20
    memory_size = 1024
    role = "your_lambda_role"
    handler = "lambda_function.lambda_handler"
}

```

### 参考

- [python - Downloading the first frame of a twitch.tv stream - Stack Overflow](http://stackoverflow.com/questions/19011691/downloading-the-first-frame-of-a-twitch-tv-stream)
FaceAPI で顔認識するための準備メモ

Microsoft Cognitive Services Face API を使った顔認証に関する個人的なメモ。
https://azure.microsoft.com/ja-jp/services/cognitive-services/face/

# 事前準備
## Person Group の作成（Create a Person Group） 
ユーザの顔を登録するために、Person Group を作成する必要があります。
後続で作成する Person オブジェクトを束ねるグループオブジェクトです。

Person Group > Person > Face という流れで登録していきます。

## 作成した Person Group へ Person を新規作成（Create a Person） 
Person オブジェクトを作成し、 前述で作成した Person Group へ追加します。

## 作成した Person へ顔情報（画像）を追加（Add a Person Face） 
作成した Person オブジェクトに顔情報を追加します。
顔が含まれる画像を読み込み、 Person オブジェクトと紐づけます。
ここで永続ID（PersistedFaceId）を取得することができます。

## Person の PersonId と PersistedFaceId の関連付け（Upload person face） 
Person Id は Person オブジェクトの一意の ID。 PersistedFaceId は顔情報の一意の ID。
これらを紐づけるための処理ですが、実際には前述の顔情報追加時に関連付けされているため、不要。

## Person Group の学習開始（Train person group） 
顔パターンを学習します。
これにより、顔の特徴を学習し顔認識が可能となります。
 
## 学習状況の確認しつつ、完了するまで待機（Get Person Group Training Status） 
学習には時間がかかるため、学習状況を確認するための API が存在します。
Training Status が完了になるまで、顔認識ができません。

# 顔認証処理
## 顔検出（Detect）
カメラなどで撮影した画像から顔を検出（Detect）する。
顔が検出されると FaceId が取得できる。

## 顔識別（Identify）
取得した FaceId を使って、Person Group に登録されている顔情報を検索（Identify）する。
顔情報が検出されると PersonId が取得できる。

## ユーザ情報の取得（Get a Person）
PersonId を使って、ユーザ情報を取得する。
chromeのurl候補の削除方法

![スクリーンショット 2017-01-16 11.03.52.jpg](https://qiita-image-store.s3.amazonaws.com/0/32839/6d5fc692-a249-1cf7-46f0-16dd825ef5a1.jpeg)

こういうやつ

もう使わないページを候補にされて困ることありますよね。
だから消したい!!

っていうときは、macの場合。

+ 候補が出てきたら`↑`,`↓`キーで選択。
+ `shift` + `del`または、`shift` + `Fn` + `del`で消せます。

windowsでも消す方法あるからググってみるとよかろうかと。
[WIP] Elixir始めました。勉強メモ

プログラミングElixirを電子書籍で購入して勉強中なので、そのメモ第一段。

# install
[こちら](http://elixir-lang.org/install.html#mac-os-x)を参考にする。rvmやrbenvみたいにバージョン切り替えられるようにしておこかなと思って、今回は[kiex](https://github.com/taylor/kiex)を使う

```
> curl -sSL https://raw.githubusercontent.com/taylor/kiex/master/install | bash -s

# ~/.bashrcにいかを追加

test -s "$HOME/.kiex/scripts/kiex" && source "$HOME/.kiex/scripts/kiex"

source ~/.bashrc

> kiex list known
Getting the available releases from https://github.com/elixir-lang/elixir/releases

Known Elixir releases:
    0.7.2
    0.8.0
    0.8.1
    0.8.2
    0.8.3
    0.9.0
    0.9.1
    0.9.2
    0.9.3
    0.10.0
・・・・・・・・
・・・・・・・・・・
    1.3.0-rc.0
    1.3.0-rc.1
    1.3.1
    1.3.2
    1.3.3
    1.3.4
    1.4.0
    1.4.0-rc.0
    1.4.0-rc.1

> kiex install 1.4.0 
> kiex default 1.4.0
```

以上。インストールは簡単。

# 動作確認
コンソールを立ち上げて確認してみる。

```
> iex
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.4.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 3 + 4
7

iex(2)> String.reverse("aaaabbbbccc")
"cccbbbbaaaa"

iex(3)> String.upcase("aaabbb")
"AAABBB"

iex(4)> h IO.puts  # hでヘルプが出る

iex(5)> i "123" # 値の詳細が出る
```

コンソールを終了するときは「Control + c」で

```
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
```

のように聞かれるから「a」を選択すると終了する。
まずは最初の一歩だ。

#2章の内容をやってみる
comming soon
HoloLensの購入(クレジットカード)でトラブった際のベストプラクティス？

#日本での出荷作業が始まったようです(2017/01/13)

しかし私の使用しているクレジットカード会社より連絡が来ています。
”不正使用の疑いがる取引を停止しています”と、
そしてマイクロソフト ストアからも連絡が来ています。
”購入処理中に問題が発生しました”と、、、、

ええ、問題解決まで5~6時間もかかりました。
さらに2日間もかかって、、、

そこで学んだベストプラクティスを、これから HoloLens を購入するであろう同士諸君に伝える！
(あくまで私が学んだ方法なので、それで解決しない場合は検討を祈る！)
＊この方法はイリーガルでも、より問題を複雑にするものでも"無い"ので最初の一回を試してみる価値はあると思います。

#結論

人は信用するな、システムに任せろ！ です。

- まずクレジットカード会社に連絡を入れて、不正では無い自身の購入である旨を伝え、セキュリティで弾かれないようにします。
- この時点で言われると思います、”取引先(マイクロソフト)様にもう一度同じ購入処理を行って欲しい”と(企業間でやって頂けたら何も問題は起こらないのに、、)
- ここで注意です。ここで人に連絡してはいけません。問題が複雑化する"可能性"が大きいです。
- __マイクロソフト ストアよりメール(購入失敗)が来てるはずで、そのメールにはクレジットカードの情報を更新してとのリンクがあるはずです、そこに飛んで何も内容を変更せず、更新すれば良いだけです。__

はい、これだけです。
私はマイクロソフト ストアに連絡してハマりました。
(マイクロソフトさんの名誉のために言っておきますが、対応は丁寧でとても素晴らしかったのですが、結果だけが最悪でした)

#経緯

私がマイクロソフト ストアのクレジットカードの情報を更新した時点で問題は解決したはずなのですが、
ストアのオペレーターの方は、とにかくその注文をキャンセルして、新たな購入を作成したがります(笑)
(トラブったクレジットカードをもう一度使用する場合のマニュアルなんでしょうか？)

ここで素晴らしい事に、キャンセルと再購入処理をオペレーターの方がやってくれます。
しかし、この再購入処理で、またトラブったのが運の尽き、、、

翌日にマイクロソフト ストアより同じ内容の”購入処理中に問題が発生しました”メールが来ていました。
そうしたら、またクレジットカードでトラブってるって思いますよね？ね？

結論そうではなかった
この時点での正確な状況は(振り返ってみると)

- 最初の注文はキャンセルされていたが、マイクロソフトのキャンセルとはクレジットカード処理を行うが最終的な請求をしないことによる取引を成立させないことをキャンセルと言っていた。
- クレジットカード会社のキャンセルとは、クレジットカード処理のキャンセルの連絡をいれられる事を言っていた。
- 新たな購入は、マイクロソフト側のシステム側のみの問題で止まっていて、クレジットカード会社に何のやりとりも行っていなかった。
- キャンセルした(MS)、してない(クレカ)、購入処理がない(MS)、ある(クレカ)と定義が違う会社の状況と、私が購入出来ないないという事実、これが事態を複雑奇怪に推移させた。

そしてクレジットカード会社の方も、頑張ってマイクロソフト ストアに連絡を入れて解決を試みてくれます。
(しかしクレジットカード会社では何も問題も起きてないし、そもそもマイクロソフトとのやりとりすら発生してなかった)

そして運命は最悪の方向へ、、、
クレジットカード会社の方が、ストアではなくビリングサービスに本人が問い合わせればクレジットカードの取引履歴がわかるから、それで情報が詳しく分かると折り返し連絡をくれました。

勇んでマイクロソフト ビリングサービスへ連絡を入れます。
ここでの対応してくれた方が最悪でした。
(あくまで個人の感想です)

自身の保身と責任回避に終始する方でした。
確実でない事は何も答えれれない、わからない、あげくにマイクロソフトにはこう言ったトラブル(クレジットカード処理履歴まで含む問題)を解決する担当や部署はないとまで言い出しました(笑)
ここでの問答がとにかく時間がかかって無駄でした。

クレジットカード会社としては、購入がゴールではなく、取引履歴から会社の問題を解決したかったのでビリングサービスに連絡って行き着いたんでしょうけど、、

呆れてまたマイクロソフト ストアに連絡を入れなおしたのですが、ここでもこちらのオペレーターの方は素晴らしかったですね。
クレジットカードの処理まで含めた履歴や情報を教えてくれました。
(やっぱ出来るんじゃん)

で、何故かやりとりしている間に取引が正常に進んでいて、何故か解決したのですが
おそらくマイクロソフト　ストアからのメールで、クレジットカード情報の更新を何度かトライしている内にちゃんと処理が受け付けられたのではないか？との事でした、、、

#教訓

仕事できない人が絡むと、トラブルは余計大きくなる

#トラブルまとめ
- HoloLens購入のクレジットカードの決済で、不正取引の疑いチェックに引っかかる。
- クレジットカード会社に連絡して、購入できるように処理をしてもらう。(が再度の購入処理をお願いされる)
- マイクロソフト側で、購入キャンセル＆新規購入を勧められ、処理をお願いした。
- この新規購入がまたトラブった。
- しかもクレジットカードの問題ではなかった。
- しかし言葉の定義の違いによる、2社間の状態の違いで混迷を極める。
- 仕事できない人間が絡むと、問題が大きく、さらに見当違いの方向に進んでしまう！！

__人間による伝言ゲームは避けるべし！__

最終的な私のステータスとしては、HoloLensを1つ購入予定だが、確定していないクレジットカード処理上は2つ購入してる(笑)、それはマイクロソフトが1つしか請求しないことにより、処理が確定せずに1つだけの購入となる予定(クレジットカードの上限枠を圧迫している状態)、以上です。
togelack (slack + togetter みたいなやつ) を docker で動かしてみた

togelack が便利そうだったので、docker で動かしてみたメモ。

clone してディレクトリに入る。

```
$ git clone https://github.com/rutan/togelack.git
$ cd togelack
```

Dockerfile 作成。

```
$ vi Dockerfile
```

```
FROM ruby:2.2.4
WORKDIR /user/src/app
COPY Gemfile* ./
RUN bundle install
COPY . .
RUN rake assets:precompile
CMD bundle exec puma -C config/puma.rb
```

docker-compose.yml 作成。

```
$ vi docker-compose.yml

version: "2"
services:
  mongo:
    image: mongo
  app:
    build: .
    ports:
      - 3000:3000
    environment:
      SECRET_KEY_BASE: ${セキュアでランダムな文字列}
      RAILS_ENV: production
      MONGOID_ENV: production
      SLACK_TOKEN: ${あなたの SLACK TOKEN}
      SLACK_CLIENT_ID: ${あなたの SLACK CLIENT ID}
      SLACK_CLIENT_SECRET: ${あなたの SLACK CLIENT SECRET}
      SLACK_TEAM_ID: ${あなたの SLACK TEAM ID}
      SLACK_TEAM_NAME: ${あなたの SLACK TEAM NAME}
      MONGO_URL: mongodb://mongo:27017/togelack
    restart: always
```

ドッカーコンポーザップディー。

```
$ docker-compose up -d
Starting togelack_mongo_1
Recreating togelack_app_1
```

これだけで http://localhost:3000 に togelack が立ち上がった。シンプルで使いやすく便利そう。

Dockerfile と docker-compose.yml プルリクしてみようかな…。

## 参考資料

* [SlackのTogetter風アプリ「Togelack」をHerokuにデプロイする \- Qiita](http://qiita.com/ru_shalm/items/35100b527877cfe09b5e#_reference-c1aa5a6f960321384793)
* [Togetter的な社内Slackまとめサイトをつくった話 \- Qiita](http://qiita.com/ru_shalm/items/32160b23df535ed78967)
ショートカットを活用しよう - 9 - Ctrl + F10

# <kbd><kbd>Ctrl</kbd> + <kbd>F10</kbd></kbd> の効果
MS IMEでの話ですが。IMEの入力がONになっている場合、IME設定用のコンテキストメニューが表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/156225/f2ae375a-0def-dc1a-8b5c-2223eb455d2f.png)

ちなみに、システム辞書では標準でONになっていない、カタカナ語英語辞書と記号辞書はONにして利用しています。
![image](https://qiita-image-store.s3.amazonaws.com/0/156225/d8cee174-cf03-dbeb-f810-c8c439d6446a.png)

以上

|前回|方針|次回|
|:--|:--:|--:|
|[<kbd><kbd>Shift</kbd> + <kbd>F10</kbd></kbd>](http://qiita.com/rrryutaro/items/306247e6e878fb155462)|[記事の方針](http://qiita.com/rrryutaro/items/74d60a6e31ff149c5710)|[<kbd><kbd>Win</kbd> + <kbd>↑←↓→</kbd></kbd>](http://qiita.com/rrryutaro/items/c1a7e240ae710bcc28bc)|
GitHubから特定ディレクトリのみをエクスポートするためのブックマークレット

## ブックマークレット

以下をブックマークに登録し、ハイライトされたコマンドをコピーして、ターミナルで実行。

```javascript
javascript:(function(){var svn_url = document.location.href.replace("tree/master","trunk");var command = "svn export " + svn_url;var q = document.createElement("input");q.style.position="fixed";q.style.top="10px";q.style.left="10px";q.style.zIndex=999999;q.style.width="300px";q.type="textarea";q.value = command;document.body.appendChild(q);q.focus();q.select();})();
```

## 動作

どこかのリポジトリの子ディレクトリで、ブックマークレットを実行すると・・・

![SS 2017-01-16 8.29.04.png](https://qiita-image-store.s3.amazonaws.com/0/53489/fbe7c00e-2bc7-ca3b-5c4c-fa8bc393f751.png)

svn export のコマンドが画面左上に作られるので、それをコピーして、ターミナルで実行。

![SS 2017-01-16 8.30.24.png](https://qiita-image-store.s3.amazonaws.com/0/53489/fd5abfb2-2934-88e7-2aa2-20c4fa7a689b.png)

## 解説

GitHubには、Subversionのインターフェースもあって、SubversionはDirectory単位のエクスポートやチェックアウトが可能なので、それを使ってる。

ブックマークレットがやってる処理は以下の2つ。

- urlの"tree/master"を"trunk"に置換
- それを svn export のurlに指定して、画面上にテキストを表示
- GitHub以外で起動しても、意味のないコマンドができちゃうけど、そのエラー処理はやってない
- svnコマンドはインストールされている前提（手元のOSXでは知らない間に入っていた）

これくらい手動でしてもいいんだけど、勉強中は大量にサンプルを落としてきては、動作確認をしたいので、機会的にできるようにブックマークレット化。

## 背景

Xamarinの開発をやりはじめて、サンプルソースがいっぱいGitHubにあるのはわかったのだが、リポジトリ配下にいっぱいソリューション（プロジェクト）が、あって、「欲しいサンプルだけ取り出したい」ってシーンが多かった。

ブラウザ上の処理と、ファイルダウンロードって導線が作りづらいのだけど、「画面上にコマンドを表示して全選択」というところまでやってあげるのが、セキュリティ的な課題もなく、ちょうど良い気がする。
List, Set, Map

 ***** LIST *****
Normal Way -Java7

```java:list.java
 import java.util.*;
 import java.lang.*;
 import java.io.*;


public class Main{
	public static void main (String[] args) throws java.lang.Exception
	{
	ArrayList<String> al = new ArrayList<>();
	al.add("A");
	al.add("B");
	al.add("C");
	
	
	
	for(String a : al){
		System.out.println("This is the list: " + a);
	}
	
	Iterator<String> it = al.iterator(); //point at one before the list
	while(it.hasNext()){
		System.out.println("This is the list: " + it.next());
       // it.next() : get the next element
	}
}
}
```

Lamda -Java8

```java:list.java

class Main
{
	public static void main (String[] args) throws java.lang.Exception
	{
	List<String> ls = new ArrayList<>();
	ls.add(1);
	ls.add(2);
	ls.add(3);
	
//to show List 
	ls.stream().forEach(System.out::println);

//to convert List to a double array 
	ls.stream().forEach(i -> System.out.println(i * 2) );
	}
}


```

***** SET *****

```java:set.java
 import java.util.*;
 import java.lang.*;
 import java.io.*;


public class Main{
	public static void main (String[] args) throws java.lang.Exception
	{
	
	Set<String> alset = new HashSet<>();
	alset.add("A");
	alset.add("B");
	alset.add("C");
	
	for(String a : alset){
		System.out.println("This is the set: " + a);
	}
	
	Iterator itset = alset.iterator();
	while(itset.hasNext()){
		System.out.println("This is the set: " + itset.next());
	}
}
}
```

***** MAP *****

```java:map.java
 import java.util.*;
 import java.lang.*;
 import java.io.*;


public class Main{
	public static void main (String[] args) throws java.lang.Exception
	{
	
	Map<String, Integer> almap = new HashMap<>();
	almap.put("A", 123);
	almap.put("B", 234);
	almap.put("C", 345);
	
	for(String key : almap.keySet()){
		int value = almap.get(key);
		System.out.println( key + " has the number " + value);
	}
	

	Iterator<Map.Entry<String, Integer>> itmap = almap.entrySet().iterator();
	
	while(itmap.hasNext()){
		Map.Entry<String, Integer> entry = itmap.next();
		System.out.println("Key: " + entry.getKey() + "value: " + entry.getValue());
	}
	
	}
}
}
```

Lamda -Java8

```java:list.java

class Main
{
	public static void main (String[] args) throws java.lang.Exception
	{
	Map<String, Integer> items = new HashMap<>();
	items.put("A", 10);
	items.put("B", 20);
	items.put("C", 30);
	items.put("D", 40);

// To show List 
items.forEach((k, v) -> System.out.println("Item:" + k + " Count:" + v));

// To convert Map to a double Map
	items.forEach((k, v) -> System.out.println("Item:" + k + " Count:" + v * 2));
	
	}
}

```
無限捲動與換頁的操作體驗

看到 [這篇](https://medium.com/@dalpattapaniya/infinite-scrolling-vs-pagination-f237592f339a) ，是一篇比較無限捲動（也就是有載入更多功能的頁面）和換頁的操作體驗的文章，有一些心得就來寫一下吧！

## 無限捲動 / 載入更多 (Infinite-scrolling)

無限捲動比較適合在「不太需要定位現在位置」的情境之下使用，
例如：

- 瀏覽社群網站：Facebook, Twitter
- 瀏覽圖庫或搜尋結果：如 Dribbble, Pinterest, Google 的圖片搜尋

類似這一類的內容，使用者對「列表中的單一資訊」的重視度大於「當前在列表中的位置」，只要有辦法取得單一資訊的前往方法，都不是什麼太大的問題。

### 目前所在位置資訊 - Location Hash

當然，當使用情境中有需要用到列表中的位置資訊的話，
服務本身也需要提供前往該位置的方式。

像是 Google 的圖片搜尋，當捲動多頁一點、選中一個圖片的話，網址中會被新增一個 # 標示位置資訊：

```
#imgrc=TCzIUatmlfq74M%3A
```

方便使用者在分享給他人的時候，能夠前往期望的位置。

## 換頁 (Pagination)

和無限捲動相反，換頁的功能在「目前在列表中的位置」很重要的情境之下，就需要被用到。例如：

- 搜尋結果
- 商品列表
- 部落格文章列表
- 報表系統
- 下載列表 ...

但是只要有類似這樣的情境，基本上就會用到

```
我想問問看第幾頁的第幾項
```

當使用換頁的機能的時候，也必須注意要把換頁的操作設計的容易操作、在介面上容易辨識現在在第幾頁、容易前往自己想要去的頁數等。

前幾年有印象有看到一些部落格把他們家的列表用無限捲動的方式呈現，
當想要再看到某個有興趣的區塊，就一定都要「從頭」開始捲動，真的有點麻煩 ...

### 可是我還是想用無限載入 ...

這時候就要有辦法讓使用者，可以透過網址加上頁碼參數的方式，直接前往該頁，像是在網址加入 query string ：

```
?page=10
```

這樣就可以直接前往第 10 頁。

（當然在網站端也要去控制使用者輸入超過總頁數的頁碼的這件例外。）

## 注意點

### 切換環境

「無限捲動」對於不要讓使用者切換操作環境幫上很大的忙，
因為可以不用跳轉，就可以透過非同步載入讓下一頁的內容出現。

但是當適合「分頁」的網站，如部落格，想要以「無限捲動」呈現這個效果的話，
就必需要提供方便、顯而易見的方式讓使用者可以前往。

### 行動裝置上的 App

對於行動裝置來說，不要跳離目前環境顯然就更重要了。

這時候在分頁性質內容所需的「需要知道列表中的當前位置」這件事，
就比較被削弱了，
在 app 的操作環境、通常沒有「網址」這個元素。

原先在網頁環境有分頁功能的服務，切換到 app 上之後，通常就會以無限載入的方式呈現，
在 app 環境和操作習慣裡面，使用者會更加重視他看到「哪篇文章寫了什麼」，而不是「他看到第幾頁的第幾篇寫了什麼東西」，如 Tumbler 的 app 。

在行動裝置 app 的環境裡，還真的比較少看到有用到分頁機制的服務，
做得好的實例就要再找找看了。

今天就先到這裡唄 :smiley:
Windowsの小ネタ

意外と最近まで知らなかった、Windowsの小ネタを記載します。
（初歩なのかもしれませんが、、）

- Explorerを開き、適当なファイル・フォルダの上でShiftキーを押しながら右クリック。

　「パスとしてコピー」
　という項目が表示されます。

　ファイルやフォルダのパスをクリップボードにコピーすることができます。


- 同様に、フォルダの上でShiftキーを押しながら右クリック。

　「コマンドウィンドウをここで開く」
　という項目が表示されます。

　これを選択すると、コマンドプロンプトウィンドウが開きます。
PMP更新時に必要となるPDU取得数・ルール変更について

PMP更新時に必要となるPDU取得数・ルールが変更となりましたので、
下記の通り、纏めてみました。

## ①カテゴリー   A, B, C    [教育区分]
　A:  支部、PMI 登録教育機関（R.E.P.）、CoP（PMI 認定のスタディー・グループ）
　B:  大学におけるプロジェクトマネジメント教育など
　C:  自習

　旧[15PDU が必要] ⇒ 新[35PDU が必要]

　さらに、PMI タレント・トライアングルに記載されたサブ・カテゴリー
　・「リーダーシップ」： ８ＰＤＵ
　・「テクニカル・プロジェクトマネジメント」：８ＰＤＵ
　・「ストラテジック＆ビジネスマネジメント」：8PDU
　は必須  
　残り１１PDU はどのサブ・カテゴリーでも良い 

　※タレント・トライアングル：http://www.pmi.org/learning/talent-management-resources.aspx

##②カテゴリー D, E, F   [ギブバック区分] 
　D:  PM 知財の新規開発など 
　E:  PMI のボランティア活動（含む支部でのボランティア活動）
　F:  PM 実務（職場での PM 関連活動） 

　旧[45PDU まで(Fは最大15PDU)] ⇒ 新[25PDU まで(Fは最大8PDU)]



詳しくは
https://www.pmi-japan.org/pmp_license/renewal/ccr201512.php
を参照してください。
技術英語 > But now, it looks like we've finally reached [a tipping point]. / Game changer

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 384 / 12833)

> But now, it looks like we've finally reached **<font color=red>a tipping point</font>**.

https://www.merriam-webster.com/dictionary/tipping%20point
> :  the critical point in a situation, process, or system beyond which a significant and often unstoppable effect or change takes place

@ うちのパパが言うことには by 重松清さん
「大人買い」することについて
> おじさんはもうあの頃には戻れないから、ほんとうは、きみたちのことがうらやましくてしょうがないんだぜ。

<hr>
~~どこかのエンジニアが「いったん新しい技術を味わったら、その前段階には戻れない(戻りたくない?)」と言っていたが、発言者と正確な発言内容を忘れた。
エスカレーター? エレベーター?~~

@ スティーブ・ジョブズ全発言 by 桑原晃弥さん

> かつてスティーブ・ウォズニアックはゼロックスのパロアルト研究所で「未来に向けた一方通行のドアみたいなもので、そこを通ったら戻ってくることなんてあり得ない」と感じた。

[Q Accelerator](http://qiita.com/howdy39/items/e6136b8454099ebfef29)を使い始めて１週間弱。このツールがない状態には戻れない（戻りたくない）。

<hr>
関連して思い出したのは
Game changer
http://eow.alc.co.jp/search?q=game+changer
omniauth-google-oauth2 をローカル環境で使う

omniauth-google-oauth2 をローカル環境で使うときの注意点

# 認証機能を提供するプロジェクトは、Google+を有効にしておく

see: http://qiita.com/bino98/items/596b5cffeca7c104bd90

これをやっておかないと、Google からの応答が `invalid_credentials` になる。
Emailの情報を取るため？

# 認証情報は xip.io を経由してグローバルアドレスにしておく

ローカルアドレスは設定できないので、コールバックURLの設定を
http://192.168.33.10.xip.io:5000/auth/google_oauth2/callback
とかにしておく。

# ログイン画面表示時にも、 xip.io を経由する

ログイン画面が /login の場合
http://192.168.33.10:5000/login
ではなく
http://192.168.33.10.xip.io:5000/login
を使用する。そうでないと、リダイレクト時にローカルアドレスへのリダイレクトが発生して
"device_id and device_name are required for private IP"
のようなエラー画面になる。

スクリーンショット
<img width="698" alt="スクリーンショット 2017-01-16 3.43.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/47394/3bb25a62-bc58-6266-ed50-bb5c44394bee.png">

# 参考

Sinatra での使用方法
https://github.com/zquestz/omniauth-google-oauth2/blob/master/examples/config.ru
Windows 8のショートカット

#Windows 8のショートカット
![cac-phim-tat-trong-win-8.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/8e68324f-828e-2638-2abc-fd962542898b.jpeg)
Windowsエクスプローラでのショートカットは、何も変更Windows 7のショートカットで比較するので、この記事では、デスクトップとMetroUIインターフェイス上のショートカットの操作に焦点を当てます。

![cac-phim-tat-trong-win-8-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/81b20ea3-c952-9529-cb67-d0a187b42be5.jpeg)

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg): デスクトップからMetroUIへの移行   

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + C : チャームバーのツールバーを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + K : クイック設定パネルを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + H : クイックオープニングデバイステーブル

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + Q : クイックシェアパネルを開きます
 
-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + , : すばやく検索パネルを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + Tab : 透明ウィンドウがデスクトップ上で実行されています

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + E : Windowsエクスプローラを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + R : コマンドを書き込むためにRUNダイアログ・ボックスを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + X : システム管理のための高度なオプションを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + Home : 使用アクティブウィンドウ以外のすべての開いているウィンドウのサムネイル

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + Pause / Break : システムを開きます

-Windows![018_captureKey_win_F.jpg](https://qiita-image-store.s3.amazonaws.com/0/135064/d3e4cb69-d45f-8bcc-eb4d-215bcecc2672.jpeg) + PrtSc / SysRq : スクリーンショットを取ると自動的にフォルダに保存



以上です。
Ruby のcoerceメソッドで出来ること（備忘メモ）

## 背景
&nbsp;&nbsp;いま、Rubyの復習がてら、[プログラミング言語Ruby](https://www.oreilly.co.jp/books/9784873113944/)を読んでいます。その中で`coerce`メソッドの使い方として、「なるほど。そういうことしたいときに使えるのか」と思った例が出ていたので、忘れないようメモしておきます。


## 動作環境
OS: MacOS 10.11.6
Ruby: 2.2.6

## 基本動作の確認
&nbsp;&nbsp;まず、coerceの基本動作の確認。以下のように、`1 + 2/3`を計算するコードを書く。

```ruby
require 'rational'

x = 1 + Rational(2,3)

puts x    # => 5/3
```
&nbsp;&nbsp;上記で、`1 + Rational(2,3)`が評価される際に、Ratinalのcoerceメソッドが以下のように、（あるいは以下と同等の式によって）呼ばれている。

```ruby
Rational(2,3).coerce(1) # => [(1/1), (2/3)]
```
&nbsp;&nbsp;この内部の動きの説明として、以下、同著 *3.8.7.4 算術演算子の強制型変換* から引用

>coerceメソッドは、算術演算子から呼び出される。たとえば、Fixnumが定義している+演算子には、Rationalについての知識がないので、右辺がRatinalなら、どうすればそれを加算できるのかがわからない。corceは、この問題を解決する。数値演算子は、右辺の型の知識がなければ、その右辺のcoerceメソッドを呼び出し、引数として左辺を渡す。FixnumとRationalを加算するサンプルに戻ると、Ratinalのcoerceは、２個のRatinal値の配列を返す。そこで、Fixnumが定義する+演算子は。配列内の値の+演算子を呼び出せばよい。


&nbsp;&nbsp;上記のコード例だと、`Rational(2,3).coerce(1)`が、Ratinal値２つの配列`[(1/1), (2/3)]`を返してくれるので、`1 + Rational(2,3)`は、`Rational(1,1) + Rational(2,3)`を評価すればよいことになって、Ratinal値同士の加算に帰着する。

## 応用例

&nbsp;&nbsp;次に、本題の「なるほど。そういうことしたいときに使えるのか」の例です。
&nbsp;&nbsp;以下のような、XY座標上の点XYPointクラスを作成します。このクラスには、引数にスカラー値を期待する、`*`メソッドによるスカラー倍も定義します。

```ruby
class XYPoint
  attr_reader :x, :y

  def initialize x=0, y=0
    @x, @y = x, y
  end

  def to_s
    "(#@x,#@y)"
  end

  def *(a)
    XYPoint.new(a * @x, a * @y)
  end

end

p = XYPoint.new(2,3)

puts p * 10 # => (20,30)
```

&nbsp;&nbsp;ここで、XYPointをベクトルと見るとスカラー倍なら、倍する数10を `*`の左側にして、

```10 * p```

と書きたい。しかし、上記のコードで最後の行の、`point`と`10`をひっくり返して、

```ruby
puts 10 * p
```
にすると、以下のような「XYPointはFixnumに変換できない」旨のTypeErrorが発生します。

```ruby
in `*': XYPoint can't be coerced into Fixnum (TypeError)
```

&nbsp;&nbsp;そこで、```10 * p```を評価するときは、(XYPointの`*`を使う）```p * 10``` を評価するように、XYPointクラスに以下のcoerceメソッドを追加します。

```ruby
class XYPoint
  
  ・・・・（同上）・・・
  
  def coerce(a)
    [self, a]
  end
end
```
こうすると、めでたく以下のように、`10 * p`の結果`(20,30)`が表示されました。

```ruby
puts 10 * p # => (20,30)
```

## 参考
リファレンスマニュアル
[instance method Numeric#coerce](https://docs.ruby-lang.org/ja/latest/method/Numeric/i/coerce.html)



## 追記

> 変数名にpを使うと、Kernel#p と紛らわしいので変数名をpointni

という編集リクエスト（上記メッセージ文末の`pointni` は  `pointに`
の誤字かな？）を一部の方から頂き、その方のお顔を立てて差し上げる
意味あいで、ご要望に添って一度は`point` に修正しておりましたが、
Rails ガイドのサンプルコードにも

<img width="683" alt="スクリーンショット 2017-12-03 16.25.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/74659/b1b1273e-afeb-559f-69fb-861b193d7cb9.png">


という、変数名を `p` とする例がございますし、またこの投稿のコード例でも

```ruby
p p
```
というような、明らかに紛らわしいコードを書いているわけではないので、 変数名を `p` に戻させて頂きました。
何卒ご了承くださいますよう。
python3で外部のシェルスクリプト（ls）とかの返り値（と終了コード）を取得。

#1.やりたいこと
Python3から`ls`とか`pwd`を叩いて返り値をGetしたい。
いつも忘れるのでメモ
他の記事は少々古いので新たな気分で
lsなら [glob.glob](http://qiita.com/Kodaira_/items/229302c303a3cf31ca8c) 使えやとか聞こえてきますが、今回はスルーの方向で。

#2.書き方(command -> subprocess)
**command**.getoutput(cmd) [^1]
が
**subprocess**.getoutput(cmd)[^2] になっただけ

```python:shellの返り値Get！

# 3系ではcommandは廃止されたので代わりにsubprocess使う
from subprocess import getoutput  

ls = getoutput('ls')
print(ls)
 # lsの返り値（str）

pwd = getoutput('pwd')
print(pwd)
 # 現在ディレクトリの絶対パス（str）


top = getoutput('top') # 永遠に帰ってこない
```

---
2021/10/17 追記:
終了コードも欲しい場合は `getstatusoutput()` が使用できる[^3]。

```python
from subprocess import getstatusoutput

# 単純な ls で正常終了する
ls = getstatusoutput('ls')
print(ls)
# (0, '[ls の結果]')

# hoge というディレクトリが無いのでエラーになり、終了コードは `1` になる。
cd = getstatusoutput('cd hoge')
print(cd)  # hoge というディレクトリが無いのでエラーになり、終了コードは `1` になる。
# (1, '/bin/sh: line 0: cd: hoge: No such file or directory')

```


以上



[^1]: http://docs.python.jp/2/library/commands.html#commands.getoutput

[^2]: http://docs.python.jp/3.5/library/subprocess.html#subprocess.getoutput

[^3]: https://docs.python.org/ja/3/library/subprocess.html#subprocess.getstatusoutput
【今さら】AWS Configを設定してみた

今までスルーしてきたAWS Configの設定をようやくすることに決めたのでとりあえずメモ

### AWS Config
* 現在のAWSの設定内容の保存とそこからの変更履歴を監視してくれる
* ルールを設定することができ(Config Rule)、これから逸脱するやつは検出してくれる
  * 監査に最適！！

### とりあえず簡単に設定してみる
#### Get started
![スクリーンショット 2017-01-15 18.13.27.png](https://qiita-image-store.s3.amazonaws.com/0/98887/54b45a85-17a4-a775-32a9-76085a06a216.png)

#### Settings
* Resource types to record
 * 監視対象のリソースと保存先などを設定します
 * 設定しているリージョンの全操作とグローバルリージョン(IAMとか)を対象にします
* Amazon S3 bucket
 * Configで取得したデータの保存先バケットを設定します
* Amazon SNS topic
 * 通知用のSNSを設定します
* AWS Config role
 * Configが使うためのロールを設定します
 * S3へのPutObjectとSNSへのCreateTopicでよさそう

![スクリーンショット 2017-01-15 18.18.58.png](https://qiita-image-store.s3.amazonaws.com/0/98887/ec36dc0c-37df-deb9-6dc5-3c1094184288.png)


#### AWS Config rules
* Config rulesを設定する場合はここで「Add」にチェックを入れる
 * s3-bucket-versioning-enabled：S3のバージョニングが有効になってるかどうか
 * cloudtrail-enabled：CloudTrailが有効になってるかどうか
 * eip-attached：使われていないEIPがないかどうか
 * encrypted-volumes：EBCボリュームが暗号化されているかどうか
 * root-account-mfa-enabled：RootアカウントでMFAが有効になっているかどうか

![スクリーンショット 2017-01-15 23.29.41.png](https://qiita-image-store.s3.amazonaws.com/0/98887/b1ab4f97-eb2c-08a5-d9a5-3b8d717ef4cd.png)


#### Review
* 登録した内容の確認
 * 今回はConfigRulesに3つチェック入れました
* OKなら「Confirm」をクリック

![スクリーンショット 2017-01-15 23.45.58.png](https://qiita-image-store.s3.amazonaws.com/0/98887/1c3f9f6b-d98d-54e3-bda8-0025e74579bb.png)


### 作成後
* Rulesに追加する
  * 「Add Rules」で色々追加できそう

![スクリーンショット 2017-01-16 1.36.55.png](https://qiita-image-store.s3.amazonaws.com/0/98887/12178b02-2bf0-f5ef-dc4d-db12f79f814b.png)


### 終わりに
* とりあえず今回はここまで
* 「Add Rules」に色々追加して、追記予定
Node.js + PhantomJS + Seleniumでスクレイピングする

Node.js + PhantomJS + Seleniumでスクレイピングする
===============================================

とくに何の目的もなく、
「そうだ、スクレイピングしよう」
と思ったので、ここに書いておく。

以前にやったんだけど完全に忘れてたので自分への備忘録として。

なんでSeleniumをつかった！言え！
----------------------------

スクレイピング目的では`cheerio-httpcli`を使っているのを聞いたりするのだけれど、いまいちピンとこなかった。
あくまでスクレイピング専用、という感じだったし。

一方で、Selenium使えばブラウザの自動操作ができるから、

* ルーチンの自動化
* スクレイピング
* テスト

とかいろいろできるやん。
それぞれでツールの使い方覚えるのとかめんどいしSelenium一個でええやん！
という考えでSeleniumを使うことにしたんだった気がする。

手順
----

1. 適当にフォルダ作ってそこで作業開始
2. `npm i phantomjs-prebuilt -g`
3. `npm i selenium-webdriver --save`
4. index.jsを書く(下のはTypeScriptで書いたけど、そのあたりは脳内でJavaScriptに変換かけてくれ)
5. `phantomjs -w`(PhantomJSを起動して、操作を待ち受ける)
6. `node index.js`

```index.ts
// Seleniumの機能をインポート
import * as SeleniumWebdriver from "selenium-webdriver"

// ブラウザをつかうための設定。phantomjsはデフォルトだと8910番を使うので固定。
const driver = new SeleniumWebdriver.Builder()
    .forBrowser('phantomjs')
    .usingServer('http://localhost:8910')
    .build();

// ブラウザ処理はロード待ち描画待ちなどあるため、基本的にPromiseで値を返す。
// thenしまくるのは辛いのでasync/awaitを使うことで簡単になる。
(async function() {

  // ここの以下6行だけが、実際のスクレイピング。
  await driver.get('http://example.com');
  // jQueryみたいにDOM指定したいので関数として$を定義する。
  const $ = (x: string) => driver.findElements(SeleniumWebdriver.By.css(x))
  const xs = await $('h1');
  const x = xs[0];
  const text = await x.getText();
  console.log(text);

  // 終わったら閉じる。
  driver.quit();
  process.exit();
})();
```

終わりっ！閉廷！…以上！皆解散！
[翻訳]Chrome デベロッパーコンソール　意外と知られていない10の機能

[Things you probably didn't know you could do with Chrome's Developer Console](https://medium.freecodecamp.com/10-tips-to-maximize-your-javascript-debugging-experience-b69a75859329#.eoe9kd6pk)の抄訳。

# 1. jQueryが入っていなくても$$で同等のことができる

jQueryが入っていなくても`$$('.hoge')`, `$$('#hoge')`, `$$('tagName')`で同等のことができる（\$が2個であることに注意）。
$が1個の`$('.hoge')`も定義されているが、こちらは配列でなく1個の要素を返してくる。

# 2. ページを編集できる

```js
document.body.contentEditable=true 
```

とすると、ブラウザ上であたかもテキストエディタのようにページを編集できるようになる。
このモードにいるときはページ内の要素がクリックに反応しなくなるので、

```js
document.body.contentEditable=false
```

で元に戻せる。

# 3. 要素に結び付けられたイベントリスナを調べる

```js
getEventListeners($('#firstName'))
```

![image](https://qiita-image-store.s3.amazonaws.com/0/79394/c79f485f-d160-691d-4692-aa59f124ecea.png)


# 4. イベント発生を監視してログ出力

- `monitorEvents($('selector'))`で全てのイベントを監視
- `monitorEvents($('selector'),'eventName') `で指定のイベントを監視
- `monitorEvents($('selector'),['eventName1','eventName3',….]) `で複数のイベントを指定
- `unmonitorEvents($('selector')) `で監視解除

# 5. console.timeで所要時間を計測

```js
console.time('myTime'); //Starts the timer with label - myTime

for(var i=0; i < 100000; i++){
  2+4+5;
}

console.timeEnd('myTime'); //Ends the timer with Label - myTime

//Output - myTime:12345.00 ms
```

# 6. オブジェクトの配列の場合はconsole.logよりconsole.tableの方が見やすい

```js
var myArray=[{a:1,b:2,c:3},{a:1,b:2,c:3,d:4},{k:11,f:22},{a:1,b:2,c:3}]
```

のような場合は`console.table(myArray)`とすると

![image](https://qiita-image-store.s3.amazonaws.com/0/79394/9d10da7e-519f-25f7-4874-0e87b6411f96.png)


# 7. コンソールでもインスペクトができる

要素を右クリックして「検証」を選ぶ代わりに、コンソールで`inspect($('selector'))`としてもインスペクトできる。

# 8. dirで要素のプロパティの一覧を表示できる

```js
dir($('selector'))
```

# 9. $_で最後に評価した値を取得できる

```js
> 1+2
3
> $_
3
```

# 10. clear()でコンソールをクリアできる

```js
clear()
```

より詳しく知りたい方はこちら
[Chrome Command Line API Reference](https://developers.google.com/web/tools/chrome-devtools/console/command-line-reference)


---
訳者による番外

# 11. イベントに対してブレークポイントを設定できる

デベロッパーコンソール右端にあるEvent Listener Breakpointsでチェックをつけると、そのイベントのリスナーにブレークポイントを張れる。つまり、イベントが発生したときにブレークさせられる。

![image](https://qiita-image-store.s3.amazonaws.com/0/79394/b2d1da2f-bf71-2fe4-3cfe-cf6a8679df60.png)


# 12. JSのソース中に`debugger`文を書いておくとそこがブレークポイントになる

こんな感じ

```js
console.log("hello");
debugger;
console.log("world!");
```

# 13. Cmd + Option + Fで全てのJSやCSSファイル内をgrepできる

# 14. Cmd + Pで全てのJSやCSSファイルをファイル名で絞り込み検索できる
メモ帳アプリのメモ1


![スクリーンショット 2017-01-09 17.15.33.png](https://qiita-image-store.s3.amazonaws.com/0/39073/2b3c3875-197e-3e46-86da-e82eec097d62.png "スクリーンショット 2017-01-09 17.15.33.png")

#データベース

テーブルの情報を定義したMemoContractClass
データベースの操作をするためのMemoOpenHelperが必要

```java:MemoOpenHelper.java
public class MemoOpenHelper extends SQLiteOpenHelper {
    public static final String DB_NAME = "myapp.db";
    public static final int DB_VERSION = 1;

    public static final String CREATE_TABLE =
            "create table memos (" +
                    "_id integer primary key autoincrement, " +
                    "title text, " +
                    "body text, " +
                    "created datetime default current_timestamp, " +
                    "updated datetime default current_timestamp)";
    public static final String INIT_TABLE =
            "insert into memos (title, body) values " +
                    "('t1', 'b1'), " +
                    "('t2', 'b2'), " +
                    "('t3', 'b3')";
    public static final String DROP_TABLE =
            "drop table if exists " + MemoContract.Memos.TABLE_NAME;


    public MemoOpenHelper(Context c){
        super(c, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE_TABLE);
        sqLiteDatabase.execSQL(INIT_TABLE);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL(DROP_TABLE);
        onCreate(sqLiteDatabase);
    }
}
```



#非同期でデータを取得する
ListViewにアダプタを設置してデータを表示させていきたいのですが、その際にはCursorLoaderという仕組みを使うことが推奨されています。CursorLoaderを使うとデータベースに対して非同期に処理が投げられるので、データベースに問い合わせをしている間にActivityが固まってしまうことを防ぐことができます。

#CursorLoaderはデータベースに直接アクセスできない
ContentProviderという仕組みが必要
![スクリーンショット 2017-01-09 19.19.43.png](https://qiita-image-store.s3.amazonaws.com/0/39073/fb93478f-3bce-67a6-cd19-bb33493daa1c.png "スクリーンショット 2017-01-09 19.19.43.png")

ContentProvider は元々アプリ間でデータを共有するための仕組みで、これを使えば他のアプリにデータを公開して使ってもらうことができるようになります。

```java:MemoContentProvider.java
    public static final String AUTHORITY =
            "com.example.joji.mymemoapp.MemoContentProvider";
    public static final Uri CONTENT_URI =
            Uri.parse("content://" + AUTHORITY + "/" + MemoContract.Memos.TABLE_NAME);

    public static final int MEMOS = 1;
    public static final int MEMO_ITEM = 2;
    public static final UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, MemoContract.Memos.TABLE_NAME, MEMOS);
        uriMatcher.addURI(AUTHORITY, MemoContract.Memos.TABLE_NAME + "/#", MEMO_ITEM);
    }
```


#メモの編集や追加もしていくのでFormActivityという画面を追加