OmniAICreator/Qiita-1.07M huggingface dataset:
DDL スキーマの全テーブルをcsvに出力する Oracle11.2.0 以降

LOBなどcsvに落せないテーブルは考慮していない。
当SQLの結果をsqlplusにリダイレクトする。

```SQL:
--
--     ↓ あらかじめcsvを落とすディレクトリを指定する。ここにディレクトリを作ってディレクトリの中にテーブル毎のcsvを出力する
-- cd \log
-- sqlplus user1/pass1@orcl
--
-- history
--   2018/07/25  1行目に列名を入れる処理を追加
--
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD HH24:MI:SS' ;
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY/MM/DD HH24:MI:SSXFF' ;
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY/MM/DD HH24:MI:SSXFF TZR' ;
SET ECHO OFF
SET FEEDBACK OFF
SET HEADING OFF
SET LINESIZE 32767
SET PAGESIZE 0
SET TERMOUT OFF
SET TIMING OFF
SET TRIMSPOOL ON
SET VERIFY OFF
COLUMN CSV  FORMAT A32765
-- SPOOL pass includes CONNECT_IDENTIFIER, USER_NAME and SYSDATE
COLUMN USER_NAME    NEW_VALUE USER_NAME
COLUMN SYSTEM_DATE  NEW_VALUE SYSTEM_DATE
SELECT USER || '_' AS USER_NAME
     , TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS') AS SYSTEM_DATE
FROM DUAL ;
SPOOL table_to_csv_&&_CONNECT_IDENTIFIER._&&USER_NAME&&SYSTEM_DATE..sql
SELECT 'SET ECHO OFF' AS CSV FROM DUAL ;
SELECT 'SET FEEDBACK OFF' AS CSV FROM DUAL ;
SELECT 'SET HEADING OFF' AS CSV FROM DUAL ;
SELECT 'SET LINESIZE 32767' AS CSV FROM DUAL ;
SELECT 'SET PAGESIZE 0' AS CSV FROM DUAL ;
SELECT 'SET TERMOUT OFF' AS CSV FROM DUAL ;
SELECT 'SET TIMING OFF' AS CSV FROM DUAL ;
SELECT 'SET TRIMSPOOL ON' AS CSV FROM DUAL ;
SELECT 'SET VERIFY OFF' AS CSV FROM DUAL ;
SELECT 'SET DEFINE ON' AS CSV FROM DUAL ;
SELECT 'COLUMN CSV  FORMAT A32765' AS CSV FROM DUAL ;
          --  作成したディレクトリ下にcsvを作成する。
SELECT 'HOST mkdir table_to_csv_&&_CONNECT_IDENTIFIER._&&USER_NAME&&SYSTEM_DATE' AS CSV FROM DUAL ;
SELECT DISTINCT 'SPOOL table_to_csv_&&_CONNECT_IDENTIFIER._&&USER_NAME&&SYSTEM_DATE\' 
 || TC.TABLE_NAME || '.csv' || CONST.NL
 || '-- SELECT '  -- 1行目に列名を入れたい時はこの行を有効に
-- ↓ since Oracle11.2.0
 || '''' || LISTAGG(TC.COLUMN_NAME, ',')
        WITHIN GROUP(ORDER BY TC.COLUMN_ID)
        OVER(PARTITION BY TC.TABLE_NAME)
 || ''' FROM DUAL ;' || CONST.NL
 || 'SELECT '
-- ↓ since Oracle11.2.0
 || LISTAGG(CASE
                WHEN TC.DATA_TYPE IN('CHAR', 'VARCHAR', 'VARCHAR2') THEN
                    '''"'' || ' || TC.COLUMN_NAME || ' || ''"'''  -- 文字列はダブルクォーティングする
                WHEN TC.DATA_TYPE = 'NUMBER' THEN
                    'TO_CHAR(' || TC.COLUMN_NAME || ')'
                ELSE
                    TC.COLUMN_NAME
            END, ' || '','' || ')
        WITHIN GROUP(ORDER BY TC.COLUMN_ID)
        OVER(PARTITION BY TC.TABLE_NAME)
 || ' FROM ' || TC.TABLE_NAME || ' ;' || CONST.NL
 || 'SPOOL OFF' AS CSV
FROM USER_TABLES TA
INNER JOIN USER_TAB_COLUMNS TC
ON  TC.TABLE_NAME = TA.TABLE_NAME
WHERE
    TA.DROPPED = 'NO'  -- except trash box, since Oracle10.1.0
;
SELECT 'SET ECHO ON' AS CSV FROM DUAL ;
SELECT 'SET FEEDBACK ON' AS CSV FROM DUAL ;
SELECT 'SET HEADING ON' AS CSV FROM DUAL ;
SELECT 'SET LINESIZE 80' AS CSV FROM DUAL ;
SELECT 'SET PAGESIZE 20' AS CSV FROM DUAL ;
SELECT 'COLUMN CSV  CLEAR' AS CSV FROM DUAL ;
SPOOL OFF
```
参照[Oracle 定数](https://qiita.com/Papageno/items/7eb6b6207db3fce65e1a)
初めて作ったWEBサービスが3日で2000アクセス集めて思ったこと

#10秒でわかる内容まとめ
・ 小説家になろうのNAVERまとめみたいなサービスを作った
・「自分の詳しいもので、自分の欲しいもので、世間の需要のあるもの」
・「見た目が綺麗でなくてもアクセスしてもらえるもの」
・レイアウトより、機能より、まずはコンテンツ
・これで生きていきたいという決意表明

## 1, 何を作ったのか

[なろうまとめ](https://narou-matome.com)
**小説家になろうのNAVERまとめ**を目指して作りました。
それぞれが読んだお気に入りの小説を、お気に入りポイントと一緒に載せられるようになっています。

## 2, 何を思ってそれを作ったのか

**「自分の詳しいもので、自分の欲しいもので、世間の需要のあるもの」**
を目指して作りました。

**【自分の詳しいもの】**
個人開発では**初期コンテンツを自家生産できる**必要があると思います。

お客さんは「コンテンツを見るために来る」ので、
どれだけ綺麗な見た目、システムでもコンテンツがスカスカなら誰も見ないサイトになってしまいます。
魅力的なコンテンツを自家生産できる自分の詳しいジャンルに的を絞りました。


**【自分の欲しいもの】**
自分が欲しいものを作ることで、**自分を仮想のお客様**としてどんな機能、レイアウトが良いかを感じることができます。

また、細部のこだわりをする際に、
自分の好きなものでなければ「まぁ、いいか」と妥協する確率が上がります。

**【世間の需要】**
需要ないものを作っても意味がないので先に確かめるのが精神衛生上良いと思っています。

今回はブログで30個の関連記事を書いてgoogleからの検索流入があるかどうかを確かめました。
これが1記事につき5~50PV/日あったのでこのジャンルで上の検索順位を取れればまぁ流入が見込めるなと思って始めました。


# 3, 作っている時に思っていたこと

##・1人だけでもWEBサービス全然作れるな

PCで何かを作ること、それに世間様がアクセスできる状態にすることがここまで簡単だとは思ってもいませんでした。

**やってみたら意外と簡単でハードルがめっちゃ下がる**

そんな体験ができました。

##・スピード最重視

ノーテストコード、デザインはざっくり、
アイコン、ロゴもネットでざっくり作る、大変そうな機能は後回し。

**コンテンツの充実を最優先**しています。
まずはgoogleさんからアクセスをもらうこと、
その次に見た目を洗練させること、機能を充実させることだと思っています。

逆に言えば、
**「見た目が綺麗でなくてもアクセスしてもらえるものを作る」**
ということを大事にしています。


# 4, 作った後に思ったこと

##これだけやって生きていけたらめっちゃ幸せだ。
好きなものについてのWEBサービスを作って、
ゆるり収益を得て生きていく。
そんな未来が欲しいなぁと真剣に思いました。

Railsを作った人の以下の記事にかなり影響されています。
**無理に大きくするよりも少人数のグループでサービスを作って生きていこうぜ！**という内容です。
[次のfacebookを目指してなんの意味がある？　Ruby on Rails 作者が語る「お金を生み出して幸せになるためのたった１つの方法」](https://logmi.jp/6034)

##自分はプログラマーというより企画屋だ。
【だれ】の【どんな問題】を解決するため【なに】を作るかということを考えることが好きです。

その反面、プログラムを綺麗に書くということに偏執的な情熱を燃やせるほうではありません。
（もちろんなるべく綺麗なコードを書こうとはしますが。。。）

将来的には自分のサービスで収益をあげるようになって、
それでプログラマを迎え入れて一緒にサービスを作って遊ぶように暮らして生きたいと思います。

##当てるまでやる
不労所得で暮らしていけるレベルまで当てるまでは企画を出し続けます。

10万円不労所得を稼ぐサービスを5本持って、50万円/月というところをひとまず目指します。


#5, 不安だけど正しい道を歩いている

今現在、働いていた時の貯金で生きています。
日々減ってゆく貯金を見て不安にも思います。

それでも**正しい道を歩いている**感じがしています。
日々、自分で手を動かして何かを生産して前へ進んでいます。

半年後、1年後に
この記事を見て「レベル低いこと言ってんな〜」とか言えるようになっていて、
「月収100万超えたぞー」と言えるようになっていたいです。

#さいごに
こんな長い記事を読んでいただき、本当にありがとうございました。
**サービスを見て改善点をコメントいただけると嬉しい**です。

良いものを作りたい、そのための意見を聞きたいと思っています。
友達に見せたところ「色が暗い」と言われ改善中です笑

↓↓↓作成したサービス↓↓↓
[なろう廃人のすすめ](https://www.narou-osusume.com/)
pythonの組込み関数locals()

locals()はpythonの組み込み関数で，名前空間でローカルな変数を出力する機能があります．

```py
def a():
    x = 1
    def b():
        x = 3
        print (x)
        print(locals())
    def c():
        print (x)
        print(locals())
    b()
    c()
    print (x)
    print(locals())
```

関数a()を実行すると以下のように出力されました．

```
3
{'x': 3}
1
{'x': 1}
1
{'c': <function a.<locals>.c at 0x7efd7c27eae8>, 'b': <function a.<locals>.b at 0x7efd7c27e9d8>, 'x': 1}
```

# 追記

@shiracamus 様に「`vars()`を引数無しで使えば同じ結果を返す」事をコメント頂きました．
ありがとうございました．
なぜジェネリクスにしないと引数にできないのか？[Protocol 'b' can only be used as a generic constraint because it has Self or associated type requirements]

#初めに
ジェネリクスにしないとなんで引数にできなくてエラーになるんだろうと思っていましたが、久々にteratilをのぞいていたら同じようなことを疑問に思っている質問があったので向き合って見ました。:eye:

で実際に質問されていたもの
https://teratail.com/questions/135893

#再現したcodeの写真:camera:パシャっつ
※エラー内容違いますが…。

<img width="681" alt="スクリーンショット 2018-07-14 17.23.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/42ce0fa5-6dfb-430a-8dce-46422a0a2d13.png">

#エラー内容の抜粋
```.swift
Protocol 'b' can only be used as a generic constraint because it has Self or associated type requirements
```

#エラー内容google翻訳
```
プロトコル「b」は、自己または関連付けられたタイプの要件があるため、汎用制約としてのみ使用できます
```

#google翻訳の、'自己または関連付けられたタイプの要件があるため'←でここはどこなの
どうやら以下の部分みたいです。↓

```.swift
associatedtype freedom
```
https://qiita.com/mshrwtnb/items/2f947eb8422899b84dbc
で書かれているようにこのassociatedtypeとはこれを継承するところで初めて型を決められるということ。最初からこの型が決められないということ。

上記のコードでいうとbで初めてこれをIntとして使いますと言っています。

ここら辺で『あー、なるほど、型が決められていないから直で入れられないんだ』と思う方もいますが以下でもう少し詳しく……:mag_right:

#もう少し詳しく

```.swift
class vcvva{
    func abc(b:b){
        print(b)
    }
    
    
    func abc1<T:b>(b:T){
    }
}
```
なぜ上記の上の方だけでエラーが出るのか？

ここで、でもbで型決めているよね？？？と、思われた方いるのではないでしょうか？
ほらここ！

```.swift
typealias freedom = Int
```

そもそも以下の部分はclassやstructで書くものなのにprotocoleでも宣言できてしまうのですよね。

**protocoleのextensionでですが…**

そもそもprotocoleのextensionは継承するclassに反映される記述という考え(私自身が、いやきっとあっているはず…)

なので

```.swift
extension b{
    typealias freedom = Int //freedomはIntの型にすることにしました。
    
    func abc(a:freedom){
        print("\(a + 1)")
    }
}
```
こうやって書いている記述は以下の記述そのもの…無理やりすぎるのかな？

```.swift
class abc:b{
    typealias freedom = Int 

    func abc(a:freedom){
        print("\(a + 1)")
    }
}
```

…ってことは以下の記述だと、え？待ってbのfreedom型わからなくね？となるのです。

```.swift
class vcvva{
    func abc(b:b){
        print(b)
    }
}
```

で以下の記述だとbが継承されているクラスやらの指定だからあ、Tが継承されているクラスにfreedom型決めているから大丈夫だね！めでたし、めでたしとなるわけです。

```.swift
class vcvva{
    func abc1<T:b>(b:T){
    }
}
```

おい！こら何言っとんじゃ？違うだろそれ！という方は優しく指摘していただければと思います。:hatching_chick:
Python3で便利なパスワード作成

短いコードでパスワード作成します  
(なぜか[Gist](https://gist.github.com/kazukazuprogram/bebcb0fcd5ed6ef22b72067618b6ce2b)が反映されないので、コードを書きます)  

```Python3:pwmaker.py
import random, sys

def main(l):
    r = ''
    for x in range(l):
        r += random.choice(list('QWERTYUIOPASDFGHJKLZXCVBNM\
,.<>/\\?_;:]+*}@[`{}!"#$%&\'()=-~^|'))
    return r

if len(sys.argv) > 1:
    print(main(int(sys.argv[1])))
else:
    print(main(32))
```

実行方法は、
`python mkpasswd.py [文字数]`
または、
`mkpasswd [文字数]`(Windowsのみ)
です。
文字はランダムです。

リポジトリーは、
[kazukazuprogram/mkpasswd](https://github.com/kazukazuprogram/mkpasswd)
コンパイル済みは[こちら](https://github.com/kazukazuprogram/mkpasswd/blob/master/mkpasswd.exe?raw=true)

フォローお願いします!!!

2018/09/02 追記
何故か文字の一覧に小文字がなかったので修正しました。
[kazukazuprogram/mkpasswd](https://github.com/kazukazuprogram/mkpasswd)の方は、それを直したのと、クリップボードの自動でコピーする機能をつけました。
（-c で無効にできます）
気が向けば、ワンライナー版も作ってみようかと思います。
【Vue.js】モーダルを簡単に単一ファイルコンポーネントとして作る

Vue公式のサンプルにあるモーダルを単一ファイル化する

[Vue公式サイトのモーダル](https://jp.vuejs.org/v2/examples/modal.html)

```vuejs:@/components/parts/modal.js
<template>
  <transition name="modal">
    <div class="modal-mask">
      <div class="modal-wrapper">
        <div class="modal-container">

          <div class="modal-header">
            <slot name="header">
              default header
            </slot>
          </div>

          <div class="modal-body">
            <slot name="body">
              default body
            </slot>
          </div>

          <div class="modal-footer">
            <slot name="footer">
              default footer
              <button class="modal-default-button" @click="$emit('close')">
                OK
              </button>
            </slot>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: 'Modal'
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .5);
  display: table;
  transition: opacity .3s ease;
}

.modal-wrapper {
  display: table-cell;
  vertical-align: middle;
}

.modal-container {
  width: 300px;
  margin: 0px auto;
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
  transition: all .3s ease;
  font-family: Helvetica, Arial, sans-serif;
}

.modal-header h3 {
  margin-top: 0;
  color: #42b983;
}

.modal-body {
  margin: 20px 0;
}

.modal-default-button {
  float: right;
}

/*
 * The following styles are auto-applied to elements with
 * transition="modal" when their visibility is toggled
 * by Vue.js.
 *
 * You can easily play with the modal transition by editing
 * these styles.
 */

.modal-enter {
  opacity: 0;
}

.modal-leave-active {
  opacity: 0;
}

.modal-enter .modal-container,
.modal-leave-active .modal-container {
  -webkit-transform: scale(1.1);
  transform: scale(1.1);
}
</style>
```

main.jsでのグローバルコンポーネント登録

```javascript:@/main.js
import modal from '@/components/parts/modal'
Vue.component('modal', modal)
```

コンポーネントでの呼び出し

```vuejs:Component.vue
<template>
    <div class="row">
      <div class="test">
        <button id="show-modal" v-if="sameUser" class="waves-effect waves-light btn blue" @click="showModal = true">show Modal</button>
        <modal v-if="showModal" @close="showModal = false">
          <h3 slot="header">custom header</h3>
        </modal>
      </div>
    </div>
</template>

<script>
export default {
  name: 'Test',
  data () {
    return {
      showModal: false
    }
  }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
```
GoでたたくTCPソケット（前編）で学んだことのメモ

# GoでたたくTCPソケット（前編）で学んだことのメモ

[GoでたたくTCPソケット（前編）](http://ascii.jp/elem/000/001/276/1276572/)

## Go言語でHTTPサーバを実装する

`server.go`ファイル内

```Go
package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httputil"
	"strings"
)

func main() {
	//listen(network名：アドレス)
	//エラーハンドリングしてる
	//複数のゴルーチンは、リスナー上で同時にメソッドを呼び出すことができます。
	//リスナを用いて接続の待ち受け
	listener, err := net.Listen("tcp", "localhost:8888")
	if err != nil {
		panic(err)
	}
	fmt.Println("Server is running at localhost:8888")

	// 一度で終了しないためにAccept()を何度も繰り返し呼ぶ
	for {
		//Acceptを受け入れて、リスナーへの次の接続を返します。
		//リスナのAcceptメソッドを使用し、クライアントからの接続を待ちます。
		conn, err := listener.Accept()
		if err != nil {
			panic(err)
		}
		//goroutine（ゴルーチン）は、Go言語のプログラムで並行に実行されるもの
		// 1リクエスト処理中に他のリクエストのAccept()が行えるように
		// Goroutineを使って非同期にレスポンスを処理する
		// ここではconnを使った読み書きをおこなう
		go func() {
			//RemoteAddrは、リモートネットワークアドレスを返します。
			fmt.Printf("Accept %v\n", conn.RemoteAddr())
			// リクエストを読み込む
			//HTTPリクエストのヘッダー、メソッド、パスなどの情報を切り出す
			//NewReaderは、デフォルトのサイズのバッファを持つ新しいReaderを返します。
			request, err := http.ReadRequest(bufio.NewReader(conn))
			if err != nil {
				panic(err)
			}
			//httputil以下にある便利なデバッグ用の関数
			//リクエスト/レスポンスに含まれるヘッダーとボディのダンプしたバイト列を取得する
			dump, err := httputil.DumpRequest(request, true)
			if err != nil {
				panic(err)
			}
			fmt.Println("dump:\n", string(dump))
			//ProtoMajorとはプロトコルのバージョン番号ぽい　"HTTP/1.0"
			//ioutil 今回は入出力関連のユーティリティ関数が定義されているパッケージ
			//ioutil.NopCloser 関数は、引数の io.Reader に何もしない Close メソッドを付加して
			//io.ReadCloser インターフェースを満たすようにしたオブジェクトを返します
			response := http.Response{
				StatusCode: 200,
				ProtoMajor: 1,
				ProtoMinor: 0,
				Body:       ioutil.NopCloser(strings.NewReader("Hello World\n")),
			}
			// レスポンスを書き込む
			response.Write(conn)
			conn.Close()
		}()
	}
}
```

## HTTPサーバー立ち上げる

```
$go run server.go
```

## `http://localhost:8888/`にブラウザなどを使ってアクセス
コンソールに表示される内容

```HTTP
GET / HTTP/1.1
Host: localhost:8888
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: ××××××××××××××××××
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: ×××××××××××××××××××××××
```

## クライアントをつくる

`client.go`ファイル

```Go
package main

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
)

func main() {
	conn, err := net.Dial("tcp", "localhost:8888")
	if err != nil {
		panic(err)
	}
	request, err := http.NewRequest("GET", "http://localhost:8888", nil)
	if err != nil {
		panic(err)
	}
	request.Write(conn)
	response, err := http.ReadResponse(bufio.NewReader(conn), request)
	if err != nil {
		panic(err)
	}
	dump, err := httputil.DumpResponse(response, true)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(dump))
}

```

## ターミナルで確認

```
$ go run server.go
```

表示内容

```
Server is running at localhost:8888
Accept 127.0.0.1:56295
dump:
 GET / HTTP/1.1
Host: localhost:8888
User-Agent: Go-http-client/1.1
```

```
$ go run client.go
```

表示内容

```
HTTP/1.0 200 OK
Connection: close

Hello World
```
Kong Yaml Admin Configuration

[Kong](https://github.com/Kong/kong) への登録は Admin API 経由で行うことが可能だが自動化等考えると設定として記述できた方が都合が良い。

![kfig.png](https://qiita-image-store.s3.amazonaws.com/0/268412/d4ffd4b4-c347-01b6-c725-72780cac9f67.png)

検証として Yaml による Admin 設定が可能な [nokamoto/kfig](https://github.com/nokamoto/kfig) を作成する。

## kfig

Kong 1.13.x での検証を行う。

以下の Yaml により設定を行うことが可能。

```yaml
consumers:
  - username: nokamoto
    custom_id: nokamoto
    present: yes
    key_auths:
      - key: my-api-key
        present: yes

services:
  - name: mock
    url: http://mockbin.org
    present: yes
    routes:
      - hosts:
          - example.com
        protocols:
          - http
    plugins:
      - name: key-auth
        config:
          hide_credentials: yes
        enabled: yes
```

```shell
$ curl -s localhost:8001/consumers | jq .
{
  "total": 1,
  "data": [
    {
      "custom_id": "nokamoto",
      "created_at": 1531555411038,
      "username": "nokamoto",
      "id": "399b0359-5f37-4292-a6c7-3414815460b0"
    }
  ]
}

$ curl -s localhost:8001/key-auths | jq .
{
  "total": 1,
  "data": [
    {
      "id": "2042bda2-2699-4238-9b8c-5f3ea40caec0",
      "created_at": 1531555411121,
      "key": "my-api-key",
      "consumer_id": "399b0359-5f37-4292-a6c7-3414815460b0"
    }
  ]
}

$ curl -s localhost:8001/services | jq .
{
  "next": null,
  "data": [
    {
      "host": "mockbin.org",
      "created_at": 1531555411,
      "connect_timeout": null,
      "id": "30985b4f-aed8-4c78-9f8a-795bd04970c9",
      "protocol": "http",
      "name": "mock",
      "read_timeout": null,
      "retries": null,
      "path": null,
      "updated_at": 1531555411,
      "port": 80,
      "write_timeout": null
    }
  ]
}
```

## デザイン
Yaml は Admin API への出力に加えて _present_ フラグを定義する。

```yaml
consumers:
    - username: nokamoto
      custom_id: nokamoto
      present: yes
```

https://docs.konghq.com/0.13.x/admin-api/#consumer-object

```json
{
  "username": "nokamoto",
  "custom_id": "nokamoto"
}
```

_present_ が _yes_ の場合は [POST (or PATCH)](https://docs.konghq.com/0.13.x/admin-api/#create-consumer) により登録、 _no_ の場合は [DELETE](https://docs.konghq.com/0.13.x/admin-api/#delete-consumer) による削除で実装できる。

ただし [Route](https://docs.konghq.com/0.13.x/admin-api/#route-object) はユーザー定義の ID が提供されていないため、一度全ての情報を取得して差を計算する処理を実装する必要があり、 _present_ のような定義はできないため一貫性は維持できない。

また、プラグイン関係など [Admin API](https://docs.konghq.com/0.13.x/admin-api/) には記載されていない API も多くあるため、完全な Yaml 実装にはそれなりのコストが必要となる。

## 実装
テスト関連以外には特に記載することはない。

### Docker Compose
Kong Installation にはデータベースのマイグレーションの実行が含まれる。
これを [docker-compose.yaml](https://github.com/nokamoto/kfig/blob/134556544ad059d3d4d4204ab6ce52bf96e090f1/docker-compose.yaml#L8-L16) で定義する場合、kong の立ち上げとは別に kong-migration を実行する必要がある。kong の立ち上げは kong-migration が成功するまでは失敗し続けるため docker-compose 立ち上げの後に kong が正常な状態であるかを確認する必要がある。

### CircleCI
CircleCI の [limitations](https://circleci.com/docs/2.0/executor-types/#docker-benefits-and-limitations) により、 Machine Executor に設定することでしか解決できなかった。

> For instance, if you require low-level access to the network or need to mount external volumes consider using machine.
Deeplearning fast.ai Lesson1 Paperspaceのセットアップがうまくいかない

1—RECOGNIZING CATS AND DOGS
http://course.fast.ai/lessons/lesson1.html

講義の中では
```
curl http://files.fast.ai/setup/paperspace | bash 
```
とするように言われてますけどうまくいきません。

私は下記のようにしましたけど、どれが正しいのでしょうか。

http://files.fast.ai/setup/paperspace
のスクリプトをコピー(setup.shなど)して、
```sudo rm /etc/apt/apt.conf.d/*.*```　は削除
（本当は ```rm -r /etc/apt/apt.conf.d/*.*``` か？）

なお、```conda env update``` の最後（jupyter_contri 100% ）でハングアップしたようになるが、しばらく放置すると次が始まる。
PHPでURL指定して内容をもってくる関数[file_get_contents]サンプル


Amazonの公式サイトの内容をとってくるサンプルです。

```php:PHP
<?php

  $file="https://www.amazon.co.jp/";
  $json=file_get_contents($file,false,stream_context_create());
  echo $json;

?>
```

そのまますべて取ってくることができます。
正規表現と組み合わせると、画像だけ取得するなんてこともできます。
debian 9.4にrbenv環境を構築するメモ

**記述日時**:2018/07/14(土)
**OS**:Debian 9.4
**備考**:

* apt-getでrbenvをインストールするとバージョンが古いので、GitHubからクロンしてインストールします。
* GitHubからクロンしてインストールすると、rubyをインストールするとき、よくライブラリが足りなくて失敗していたので、メモしておきます。
* 最小構成でインストールしたばかりのDebian 9.4で検証しました。
* 参照したサイト：
[Basic GitHub Checkout](https://github.com/rbenv/rbenv#basic-github-checkout)/
[ruby-build](https://github.com/rbenv/ruby-build#installation)/
[rbenv-update](https://github.com/rkh/rbenv-update)


# 環境構築

## gitをインストール

```
sudo apt-get install -y git 
```

## 必須ライブラリのインストール
```
sudo apt-get install -y gcc libssl-dev libreadline-dev autoconf zlib1g-dev make
```
## rbenvのインストール

rbenvソースのクロン:
`git clone https://github.com/rbenv/rbenv.git ~/.rbenv`
環境変数の登録:
`echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc`
「rbenvをセットアップする処理」をターミナル起動時に実行させる設定の登録:
`echo 'eval "$(rbenv init -)"' >> ~/.bashrc`
環境変数の反映:
`source ~/.bashrc`　_`echo $(rbenv root)`でrbenvの格納先が出力されればOK_

## ruby-buildのインストール
renvでrubyをインストールするためのプラグインです。
上記の必須ライブラリはこのためにインストールします。
_[ruby-build/wiki](https://github.com/rbenv/ruby-build/wiki#suggested-build-environment)に必須ライブラリの説明がありましたが、インストールしてみると、情報が古いのか、いくつかのライブラリは見つかりませんでした。_

プラグイン用ディレクトリの作成:
`mkdir -p "$(rbenv root)"/plugins`
ruby-buildソースのクロン:
`git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build`
ソースの反映などはいらなくて、`rbenv install --list`を実行して、
インストールできるrubyのバージョンリストが出力されればOK

## rbenv-updateのインストール[オプション]
rbenvおよび関連プラグインをアップデートするためのプラグインです
rbenv-updateがなくても、rubyのインストール・バージョン管理などができます。
rbenvとruby-buildなどのプラグインを更新するたびに、各インストール先にcdして、`git pull`するのが面倒でしたら、
rbenv-updateを使ってもいいかと思います。

rbenv-updateソースのクロン:
`git clone https://github.com/rkh/rbenv-update.git "$(rbenv root)/plugins/rbenv-update"`

使用方法:`rbenv update`

## rbenvでrubyをインストール

インストール可能なバージョンの確認:
`rbenv install -l`
指定バージョンのrubyをインストール
`rbenv install 2.4.4`
rbenvでインストールされたrubyのバージョンの確認:
`rbenv versions`
インストールされたrubyをシェルに反映
`rbenv global 2.4.4`
rubyバージョンの確認
`ruby -v`
ミライアカリちゃんの独自プログラミング言語Akariを作ってみた【Brainf*ck】

# 概要

バーチャルYoutuber **ミライアカリ** ちゃんの独自プログラミング言語**Akari**を作ってみたという記事です。

[r-fxxk](https://github.com/masarakki/r-fxxk)というライブラリを使って、**Brainf\*ck**の派生言語という形で実装してみました。素晴らしいライブラリをありがとうございます。制作者様にはこの場を借りてお礼申し上げます。

Brainf*ck って何？という方は[こちら](http://ja.wikipedia.org/wiki/Brainfuck)をご参照ください。


# 経緯

- [0分で作れるBrainf*ck派生言語:シロ組さん専用のプログラミング言語「siro」を作ってみた](https://qiita.com/benisho_ga/items/50e674fded183a9e12f1) に感動して、自分も独自言語を作ってみたい！という気持ちが高まる。
- 大好きな[ミライアカリちゃんのLINEスタンプ](https://store.line.me/stickershop/product/11768/ja)が発売される。スタンプランキング１位おめでとう！
- これしかない！と思い、勢いで実装する。


## Akari言語の仕様

| Akari命令       | Brainf*ck命令 | 動作                                                         |
| --------------- | ------------- | ------------------------------------------------------------ |
| ピロリンッ      | >             | ポインタをインクリメントする。                               |
| 悪い子ちゃん    | <             | ポインタをデクリメントする。                                 |
| ハロー！        | +             | ポインタが指す値をインクリメントする。                       |
| ヤミ            | -             | ポインタが指す値をデクリメントする。                         |
| あ、カラスだ    | .             | ポインタが指す値を出力に書き出す。                           |
| おけまる        | ,             | 入力から1バイト読み込んで、ポインタが指す先に代入する。      |
| いきま→しょう！ | [             | ポインタが指す値が0なら、対応する ` 卍` の直後にジャンプする。 |
| 卍              | ]             | ポインタが指す値が0でないなら、対応する `いきま→しょう！` にジャンプする。 |

LINEスタンプのセリフを使わせていただきました。


## サンプルコード
とりあえずHello Worldのコードはこんな感じです。**HelloWorld.akari**というファイルを作って、以下をコピペしてください。

```
ハロー！ハロー！ハロー！ハロー！ハロー！ハロー！ハロー！ハロー！ハロー！
いきま→しょう！ピロリンッハロー！ハロー！ハロー！ハロー！ハロー！ハロー！
ハロー！ハロー！ピロリンッハロー！ハロー！ハロー！ハロー！ハロー！ハロー！
ハロー！ハロー！ハロー！ハロー！ハロー！ピロリンッハロー！ハロー！ハロー！
ハロー！ハロー！悪い子ちゃん悪い子ちゃん悪い子ちゃんヤミ卍ピロリンッ
あ、カラスだピロリンッハロー！ハロー！あ、カラスだハロー！ハロー！ハロー！
ハロー！ハロー！ハロー！ハロー！あ、カラスだあ、カラスだハロー！ハロー！
ハロー！あ、カラスだピロリンッヤミあ、カラスだヤミヤミヤミヤミヤミヤミヤミ
ヤミヤミヤミヤミヤミあ、カラスだ悪い子ちゃんハロー！ハロー！ハロー！
ハロー！ハロー！ハロー！ハロー！ハロー！あ、カラスだヤミヤミヤミヤミヤミ
ヤミヤミヤミあ、カラスだハロー！ハロー！ハロー！あ、カラスだヤミヤミヤミ
ヤミヤミヤミあ、カラスだヤミヤミヤミヤミヤミヤミヤミヤミあ、カラスだ
ピロリンッハロー！あ、カラスだ
```


## r-fxxkで実装
先ほど決めた仕様をr-fxxkに設定します。**akari.rb**というファイルを作って、以下をコピペしてください。これだけでインタプリタが完成します。

```ruby
Encoding.default_external = "UTF-8"
require 'r-fxxk'

# Akari言語の定義
class Akari < Brainfuck
  nxt "ピロリンッ"
  inc "ハロー！"
  prv "悪い子ちゃん"
  dec "ヤミ"
  opn "いきま→しょう！"
  cls "卍"
  put "あ、カラスだ"
  get "おけまる"
end

# 第一引数からソースコードを読み込む
program = ARGF.read

# ソースコードを表示
# puts program

# 実行して結果を表示
puts Akari.new.fuck(program)
```


## サンプルコードの実行
先ほどのHelloWorld.akariを実行してみます。実行にはRubyが必要です。

```
$ ruby akari.rb HelloWorld.akari
Hello, world!
```

ちゃんと Hello, world!と表示されました！


# まとめ

- ミライアカリちゃんのLINEスタンプを記念して独自言語を作ってみました。
- LINEスタンプにあるセリフを使ってコマンドを作ったから、LINEスタンプを押すだけでコーディングができるように開発環境を作れるかもしれません。やり方がまだわからないですが。。。
kotlinでspring-data-cassandraを利用しようとしているので備忘録

とりあえず、試して出てきた結果を書き残す

# CassandraRepository

## interfaceとして updateがない
+ 結局は、SpringData系って、RestもRedisも　XXTemplateに依存する形で進められており、Cassandraも例にもれず CassandraTemplateに依存しているみたい
+ JpaRepositoryを読むと、save(T) 時は、entityの存在確認をして、persist/mergeを使い分けているが、CassandraRepository(正確には[SimpleCassandraRepository](https://docs.spring.io/spring-data/cassandra/docs/current-SNAPSHOT/api/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.html)では、save時はinsertしかしていない
+ [CqlTemplate](https://docs.spring.io/spring-data/cassandra/docs/2.1.0.M3/reference/html/#cassandra.cql-template)で賄ってよが当面なんだろうなー
+ Cassandraの使い方次第だろうけど、DELETE/INSERTで今は事足りているけどダメな場合は、CassandraTemplateを引っ張り出そう

## @Query時に、JPAと同じような記載が出来ない
[@Query](https://docs.spring.io/spring-data/cassandra/docs/2.1.0.M3/reference/html/#repositories.query-streaming)をkotlin で以下のように実装すると怒られる

```kotlin:query
@Repository
interface MasterDao : CassandraRepository<GenreMaster, String> {

 @Query("SELECT count(genreId) FROM t_genre x")
 fun countById(id: String): Integer

Caused by: com.datastax.driver.core.exceptions.SyntaxError: line 1:35 no viable alternative at input 'x' (SELECT count(genreId) FROM [t_genre] x)

```

こっちにすると大丈夫

```kotlin:query
@Repository
interface MasterDao : CassandraRepository<GenreMaster, String> {

 @Query("SELECT count(genreId) FROM t_genre")
 fun countById(id: String): Integer

```

# 所感

ReactiveCassandraRepositoryを今後使いたいので、試しているけど、それがなければ、Jpaだけで進めていきたいんだよなー
spring-data-jpa との相性もあまり良いようには見えないところで考えると面倒なので。
Reactiveを考えなければ、今はまだ使わない方が良いのかもしれない..

もうちょっと要調査としよう
grepの出力をカンマで繋いで一行出力

## はじめに
Qiita初投稿です。緊張しますね。
表題のとおりの簡単な内容ですが、せっかくなので事例を交えて記事に残してみます。
なお、固有名詞については変えてます。


## サーバー環境
CentOS release 6.9 (Final)

## 場面設定
とあるアプリケーションにこんなログがあるとします。

```text:example.log
2018-07-14 00:00:01 [sample_job][success][target_id]1[value]100
2018-07-14 00:00:02 [sample_job][success][target_id]5[value]200
2018-07-14 00:00:03 [sample_job][error][target_id]10[value]300
2018-07-14 00:00:04 [sample_job][success][target_id]22[value]50
2018-07-14 00:00:05 [sample_job][error][target_id]14[value]780
2018-07-14 00:00:06 [sample_job][success][target_id]38[value]60
2018-07-14 00:00:07 [sample_job][success][target_id]7[value]450
2018-07-14 00:00:08 [sample_job][error][target_id]9[value]666
2018-07-14 00:00:09 [sample_job][error][target_id]45[value]777
```

こいつから 

```
10,14,9,45
```

という結果をどうにかして取り出したい、というのが目的です。
ここではこれを SQL の WHERE 句に貼り付けて使いたいという用途でした。

その際にどんなコマンドを使って抽出したのかを記事にしてみたいとおもいます。

## まず error の target_id だけを抽出
```sh
$ cat example.log | grep sample_job | grep error | awk -F [\]] '{print $4}' | awk -F [\[] '{print $1}'
```

うまく取り出せました。

```
10
14
9
45
```


## カンマで繋いで一行で出力する
`tr` を使ってスペースを置換していますが、その前の `xargs echo` がポイントです。`tr` で改行コードをカンマに置換する手もありますが、このほうが改行コードの差異に悩まされないのでおすすめです。改行コードを直接置換する場合、CR、LF、CRLF全てを想定する必要があるため面倒臭いので。

```sh
$ (id取得までのコマンド) | xargs echo | tr ' ' ','

10,14,9,45
```

あとはこんなふうにSQLに貼り付けてDBへ問い合わせしたりします。

```SQL
SELECT * FROM examples
WHERE id IN (10,14,9,45)
```


終わってみれば簡単な話なんですが、そういうものにかぎって意外と咄嗟には出てこないものですね:sweat:
もし似たような状況があればよかったら参考にしてください。

## 参考
- http://www.atmarkit.co.jp/ait/articles/1801/19/news014.html
- http://takuya-1st.hatenablog.jp/entry/2014/02/21/154039
- https://tech.nikkeibp.co.jp/it/article/COLUMN/20060227/230879/
- https://qiita.com/hitode7456/items/6ba8e2d58f9b8db9de11
Homebrew で複数パッケージのバージョンを切り替える方法

# `$ brew link` & `$ brew unlink` で切り替え

既に複数バージョンのパッケージをインストール済みの場合は、以下コマンドでだいたいうまくいくはず。

1回の切り替えで `unlink` と `link` にどちらも同じパッケージバージョンを指定するのがミソっぽい。

## 最新版への切り替え例

```
$ brew unlink [パッケージ名] && brew link --force --overwrite [パッケージ名]
```

コマンドの具体例:

```
$ brew unlink ansible && brew link --force --overwrite ansible
```

## 過去バージョンへの切り替え例

```
$ brew unlink [パッケージ名]@[バージョン番号] && brew link --force --overwrite [パッケージ名]@[バージョン番号]
```

コマンドの具体例:

```
$ brew unlink ansible@2.0 && brew link --force --overwrite ansible@2.0
```

# 複数バージョンのパッケージをインストールする

まだ複数バージョンをインストールしていない場合は、以下のような手順で実行する。

## まずはインストール可能パッケージの確認

まずは `brew search [キーワード]` で利用可能パッケージ・バージョンを探す。

### 例


```
$ brew search ansible

==> Formulae
ansible                                          ansible-lint                                     ansible@2.0  
ansible-cmdb                                     ansible@1.9                                      terraform-provisioner-ansible
```

- ansible 最新版
- ansible 2.0系
- ansible 1.9系

が使えそう。

- この例だと、あまり細かくパッケージのバージョンが分かれているわけではないのが分かる。
- ansibleというキーワードに引っかかって、ansible本体でないものも紛れているのが分かる。


## 複数のバージョンをインストール

### 最新版

`$ brew install ansible`

初回インストールしたバージョンはすぐに使えるようになる。

```
$ ansible --version
ansible 2.6.1
```

### 過去バージョン


- `$ brew install ansible@2.0`

過去バージョンをインストールしても、まだパッケージのバージョンは変わっていない。

```
$ ansible --version
ansible 2.6.1
```

# link する

複数バージョンのパッケージをインストールしている場合は link コマンドでバージョンを切り替える。

最新版を `unlink` して、過去バージョンを `link` してみる。

```
brew unlink ansible && brew link --force ansible@2.0
```

バージョンが切り替わったのが分かる。

```
$ ansible --version
ansible 2.0.2.0
```

# その後の切り替え

よく分からないところで怒られたりするので、冒頭に書いたとおり、以下のようなコマンドで切り替える。


```
$ brew unlink ansible && brew link --force --overwrite ansible
```

```
$ brew unlink ansible@2.0 && brew link --force --overwrite ansible@2.0
```

# 感想

いまだに `brew link` の仕組みがよく分からない。

# 環境

- Homebrew 1.6.15-7-g7c18efe
- Homebrew/homebrew-core (git revision 86e1c; last commit 2018-07-14)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Android Studioの各種設定をGithubで管理する

普段エディタやターミナルの設定などは全てGithubで管理するようにしていて(所謂dotfilesリポジトリ)、Android Studioのキーマップなどの設定も同じようにGithubで管理したいと思い調べていたところ、IntelliJが公式で用意してくれていることを知ったので試しました。

### 2018/07/17追記
本記事の手順はAndroid Studioに限らず全てのJetBrains製エディタで利用可能なはずです。
少なくともIntelliJ IDEAでできることは確認しました。

### 2018/07/20追記
**自動同期を無効にする設定はそれぞれのエディタでやっておく必要があります。これを知らずに別のエディタで開発していたら、リポジトリにたくさん変更がコミットされていた...。**

## やり方
[公式ドキュメント](https://www.jetbrains.com/help/idea/sharing-your-ide-settings.html)の通りやるだけですが、簡単に手順を以下にまとめます。

まず、設定ファイルを保存するためのGithubリポジトリを作成します。
例えばdotiflesリポジトリの一部のディレクトリを使うなどはできず、Android Studio設定を保存する専用のリポジトリとして作成します。

次に、Android Studioを開き、File > Settings Repositoryを開きます。

![貼り付けた画像_2018_07_14_15_02.png](https://qiita-image-store.s3.amazonaws.com/0/81715/6fc37fa1-aaf8-0a54-f12d-e602b42de01a.png)

GithubのURLを入力し、Overwrite Remoteをクリックすれば、設定ファイルがリポジトリに追加されます。
途中Githubのアクセストークンを要求されるので、それを事前に作成しておく必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/7797984a-ead1-8a54-c0c8-80189ecde176.png)

保存された設定ファイル。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/d0d95616-5cb3-03c6-9668-b80e251663fb.png)

## 自動同期を無効にする
デフォルトでは、Android Studioを閉じたりしたときに自動で設定をリポジトリと同期するようになっています。
自分はこれが嫌だったので、自動同期を無効にしています。
自動同期の無効化は、Preferences > Tools > Settings RepositoryでAuto Syncのチェックを外します。

![貼り付けた画像_2018_07_14_15_15.png](https://qiita-image-store.s3.amazonaws.com/0/81715/487b95ec-9b96-78d2-78fb-b81a50806d0d.png)
EC2 WindowsログインできるようになったらSlackにお知らせ

#目的
急いでEC2インスタンスを作成して使いたいときに、
Windowsパスワードがなかなか発行されずイライラするので作った

１.WindowsのコマンドからSlackにメッセージが送れることを確認する
２.インスタンス作成時のスクリプトで、パスワード変更が終わったらSlackメッセージを流す


#PowerShell でSlackにメッセージを送信する
必要なパラメータは・・・

- 送信者
- チャンネル
- コメント

で、Invoke-RestMethod コマンドで送信できる

```powershell
Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage" -Method POST -Body "token=【送信者のAPIトークン】&channel=【チャンネル】&text=【コメント】"
```
<details><summary> 例えばこんな感じで
</summary><div>
***送信者***　：HUBOTにする
SlackにHUBOTを入れる  https://slack.com/apps 👈ここから「HUBOT」を追加して **APIトークン** を取得します（詳細略）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185989/d8c7460e-c28f-a154-deea-7234d85474cc.png)
***チャンネル***　：#general　にする
***コメント*** ：「I’m Ready.」とする

```powershell
Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage" -Method POST -Body "token=【HUBOTのAPIトークン】&channel=general&text=I'm Ready."
```
</div></details>

--------

メッセージ文字列が固定だと面白くないので、割り当てられているプライベートIPを追加する

```text
Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/local-ipv4
```
これで取れるので、👇こんな風にすると

```powershell
$hoge = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/local-ipv4
$hoge ="token=【APIトークン】&channel=【チャンネル名】&text=I'm ready." + $hoge
Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage" -Method POST -Body $hoge
```
👇こんな感じになるます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185989/3b9f6195-89df-03a8-deeb-741e34557d07.png)


ちなみに、日本語を送りたい場合は、URLエンコードすれば良い
https://tech-unlimited.com/urlencode.html


#EC2作成時のスクリプトを設定(UserData の設定)
前提：作成するインスタンスからインターネット参照ができること

ステップ３の下部「高度な設定」を展開してスクリプトを書きます
![ppp.png](https://qiita-image-store.s3.amazonaws.com/0/185989/7a525472-7771-c7ca-53f4-92665357443a.png)

- タイムゾーンを変更
- Administratorパスワードを変更
- 終わったらSlackにメッセージ通知

```text
<powershell>
tzutil /s "Tokyo Standard Time"
net user Administrator Passw@rd123
$hoge = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/local-ipv4
$hoge ="token=【APIトークン】&channel=【チャンネル名】&text=I'm ready." + $hoge
Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage" -Method POST -Body $hoge
</powershell>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185989/3b9f6195-89df-03a8-deeb-741e34557d07.png)


#あとがき
UserDataでのWindows初期設定はもっと色々なことができるので
Slackで完了メッセージ送信は非常に有効かと思われる

ノシ
curlコマンドを実行するだけのDockerfile

# Dockerfile

```dockerfile:Dockerfile
FROM alpine:3.7
RUN apk update
RUN apk add curl
CMD curl -D - -s  -o /dev/null http://example.com
```

# ビルド／実行

```shell-session
# ビルド
$ docker build -t curl .

# 実行
$ docker run curl
HTTP/1.1 200 OK
Server: nginx/1.13.8
Date: Sat, 14 Jul 2018 05:56:39 GMT
Content-Type: text/html
Content-Length: 14
Last-Modified: Sat, 14 Jul 2018 05:42:03 GMT
Connection: keep-alive
ETag: "5b498d2b-e"
Accept-Ranges: bytes
```

# 使い道

ECSでcurlを定期実行するために利用した。
URLごとにコンテナを管理するのは大変なので、**タスクのスケジューリング**の**コマンドの上書き**を利用してURLを指定した。

```
curl,-D,-,-s,-o,/dev/null,http://xxx.xxx/xxxx
```

> 参考：
> https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs_run_task.html
> コンテナ定義で ENTRYPOINT が指定されていない場合は、引用符のない文字列のコンマ区切りリストである必要があります。
Sinatraの導入

# 目的
- Sinatraでの開発が可能な状態を作る手順を整理

# 前提
- Mac High Sierra
 - windowsでやる場合はvagrant上で
- ruby 2.4.1
(rubyが入っていない場合は、下部参照を確認)
(バージョンが変わらない場合は、下部参照を確認)
- sqlite3 3.19.3

# ゴール
- Sinatoraでの環境構築ができる
- Hello World がローカルで確認できる
- 次回
 - アプリを開発する、MVCの基本的な実装ができる
 - Herokuから公開できる

# 手順
## インストール
以下のgemをインストールする
- sinatra 
- sinatra-contrib 
- activerecord 
- sqlite3

```
gem install sinatra 
gem install sinatra-contrib 
gem install activerecord 
gem install sqlite3
```

## Hollow world表示まで
- 任意のディレクトリを作成し、rubyファイルを作成
- 今回は、`sinatora_study.rb` を作成

```ruby:sinatora_study.rb
require 'sinatra'
require 'sinatra/reloader'

get '/' do
  'Hello wolrd'
end
```
- requireでライブラリが読み込まれる、sinatraでフレームワークが読み込まれ
- sinatra/reloaderは、WEBRickを再起動しなくても、ソース変更がサーバに適用されるようにする（便利な機能）
- getリクエストで/（ルート）にアクセスがあった場合、このアクションが実行される
- 同じパスが設定されていた場合は、最初にマッチしたアクションが実行される


### 起動オプションを確認
 - -hコマンドで、

```
ruby sinatora_study.rb -h
$ ruby sinatora_study.rb -h
Usage: sinatora_study [options]
    -p port                          set the port (default is 4567)
    -o addr                          set the host (default is localhost)
    -e env                           set the environment (default is development)
    -s server                        specify rack server/handler (default is thin)
    -q                               turn on quiet mode (default is off)
    -x                               turn on the mutex lock (default is off)
```

- vagrantの場合、-oオプションでipを指定する必要がある。`ip -a` コマンドで確認できる
- ruby {ファイル名}　[オプション]　で起動
- 以下はmacで実行しているため、localhostでOK

```
ruby sinatora_study.rb
[2018-07-14 14:51:28] INFO  WEBrick 1.3.1
[2018-07-14 14:51:28] INFO  ruby 2.4.1 (2017-03-22) [x86_64-darwin17]
== Sinatra (v2.0.3) has taken the stage on 4567 for development with backup from WEBrick
[2018-07-14 14:51:28] INFO  WEBrick::HTTPServer#start: pid=34071 port=4567
```

## 確認
- ブラウザからアクセスする
- `http://localhost:{port}/`
- ポート番号は、`[2018-07-14 14:51:28] INFO  WEBrick::HTTPServer#start: pid=34071 port=4567` ここに表示されている

![スクリーンショット 2018-07-14 14.55.26.png](https://qiita-image-store.s3.amazonaws.com/0/57455/062aa1b6-9ce1-3042-47af-7cec062c15de.png)

- リクエストが行われると、サーバ側に以下のようなログが出力される

```
[2018-07-14 14:51:28] INFO  WEBrick::HTTPServer#start: pid=34071 port=4567
::1 - - [14/Jul/2018:14:53:04 +0900] "GET / HTTP/1.1" 200 11 0.0229
::1 - - [14/Jul/2018:14:53:04 JST] "GET / HTTP/1.1" 200 11
- -> /
::1 - - [14/Jul/2018:14:53:04 +0900] "GET /favicon.ico HTTP/1.1" 404 469 0.0008
```

# 参照
> - rubyの導入
> https://qiita.com/Arashi/items/689e91389235c25088a5

> - バージョンが変わらない場合
> https://qiita.com/opiyo_taku/items/3312a75d5916f6cd32b1
Kotlinまとめ - 基本的な文法 - 条件分岐, ループ

# 条件分岐
## if
書き方はJavaと同じ
Kotlinのifは式なので結果を代入できる

```Kotlin
val score = 70
val message = if (score >= 60) "合格" else "不合格"
println(message)
```
Kotlinには三項演算子がないが、`if-else`が式なのでこれで代用できる
`else if`をつなげることで三項演算子よりも更に多くの条件で分岐した結果を取得できる

## when
* Javaのswitch文の強化版
    * breakが不要
    * 条件分岐部分に定数以外を指定可能
* 値を返す`when`は基本的には`else`が必須
* `if-else`をつなげるよりは`when`のほうが見やすくなる

```Kotlin
when (x) {
    1 -> "one"
    2, 3 -> "two or three"
    else -> "unknown"
}

// 定数以外の指定
when (x) {
    1 -> "one"
    getInt() -> "getInt(): $x"
    in 1 .. 10 -> "1 <= x <= 10"
    else -> x.toString()
}
```

# ループ
## while
```Kotlin
// hello を3回出力
var count = 3
while (count-- > 0) {
    println("hello")
}

// Javaとの違いはdo-while内の変数をwhileの条件として使えること
do {
    val next = Math.random() < 0.5
} while (next)
```

## for
```Kotlin
for (要素名 in イテレータを提供するオブジェクト) {
    …
}

// 例
for (x in arrayOf(1, 2, 3)) {
    println(x)
}

// ラベル付き
// 普通にbreakするとyのループを抜けるだけだが、この場合はxのループも抜ける
// Swiftにもある
loop@ for (x in 1 .. 10) {
    for (y in 1 .. 10) {
        if (y == 5)
            break@loop
    }
}
```

### イテレータを提供するオブジェクトとは?
* `iterator()`メソッド、または拡張関数を持つオブジェクトのこと
* インターフェイスは以下  

```Kotlin
// 次の要素を返す
operator fun next(): T
// 次の要素があるかを返す
operator fun hasNext(): Boolean
```

---

[← 基本的な文法 - 型](https://qiita.com/hicka04/items/66d045bc1f0b5e9d9561) || [文法詳解 - 関数 →](https://qiita.com/hicka04/items/62cc5570ce869f8c24e8)
最近よく見る、複数行なJsonの正式名称

1行 = 1json で改行区切りでいっぱい並べられたjsonっぽいアレ

```
{"id":1,"name":"one"}
{"id":2,"name":"two"}
{"id":3,"name":"three"}
```

*.json とか拡張子もjsonで描かれることがよくあるけど、お前jsonじゃないだろ！
といつも思ってました。

といいつつ、じゃぁ、正式名称何よ？

正解：JSON Text Sequence の 一種。 
https://tools.ietf.org/html/rfc7464

なんか資料に書くときは、広義で、JSON-SEQとかいっておけば大丈夫だろ、と自分の中で納得。
terraformのbackendをs3にしてinitするまでの最低限の手順

# 概要
terraformのtfstateをs3で管理したいときの手順書です

terrformで使用するのユーザーの作成から`terraform init` するまでの手順をまとめました


# 手順

### awsユーザーの追加
まず、はじめに、aws cliを使えるようにするためにユーザーを追加しましょう

AWSのコンソールからIAMを選択します、ユーザーを追加をクリック

- 名前は適当にterraformerに設定
- アクセスの種類は「プログラムによるアクセス」にチェック、コンソールへのログインはしないと思うのでチェックしません

![20180714135652.png](https://qiita-image-store.s3.amazonaws.com/0/125774/487ce3ce-b3f1-7cd4-962c-fe6b1f535fe7.png)


次に、必要な権限をアタッチします。
s3へアクセスする権限が必要なので AmazonS3FullAccess権限 をアタッチします

![20180714135903.png](https://qiita-image-store.s3.amazonaws.com/0/125774/a075186c-4b29-9f3f-0151-931493de2741.png)


FullAccessでは権限範囲が大きいので、制限を強めにしたい場合は以下の公式URLを参考に権限を割り当ててください

[Backend Type: s3 - Terraform by HashiCorp](https://www.terraform.io/docs/backends/types/s3.html#s3-bucket-permissions)


### アクセスキーの取得
ユーザーの作成に成功すると、アクセスキー ID、シークレットアクセスキー の2つが表示されるのでそれを ~/.aws/credentials へ書き込みます

また、[terraformer] と表記している部分がprofile名になり、`aws --profile profile名` で呼び出すことで複数のアカウントを使うことができます

```text:~/.aws/credentials
[terraformer]
region = ap-northeast-1
aws_access_key_id = XXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXX
```

次に、credentials が正常に追加されたことを確認します

```shell
$ aws s3 ls --profile terraformer
```
とくにエラーにならなければ大丈夫です

### main.tfの作成
次に実際に実行するtfファイルを作成します

##### providerの設定

- awsを設定
- regionはアジアプシフィック(東京)
- provider-awsのモジュールのバージョンも指定できるので3.60.0に固定します
- profileは先ほど設定したterrformerを指定します、これでmain.tfファイル内にアクセストークンを書き込まずに済みます

##### terraformの設定

- versonを1.0.7を指定
- backendにs3を設定、このときのkeyにしてしたファイル名でバケットにアップロードされます

##### resourceにs3バケットを追加

- backendで要求したhoge-tfstateの名前でバケットを作成します


完成したmain.tfが以下になります

```main.tf
provider "aws" {
  region  = "ap-northeast-1"
  profile = "hoge-terraformer"
}

terraform {
  required_version = "~> 1.0.7"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.60.0"
    }
  }
  backend "s3" {
    bucket  = "hoge-tfstate"
    region  = "ap-northeast-1"
    profile = "hoge-terraformer"
    key     = "production.tfstate"
    encrypt = true
  }
}

resource "aws_s3_bucket" "tfstate" {
  bucket = "hoge-tfstate"
  versioning {
    enabled = true
  }
}

```

### terraformの初期化処理
```shell
$ terraform init

```
「Terraform has been successfully initialized!」と表示されていれば成功です、上記のコマンドでs3のバケットの作成から保存までやってくれます

最後にawsコンソールへログインして、s3バケットにtfstateが保存されていることを確認しましょう


以上の手順でtfstateをs3に保存する手順は終わりになります


## 備考
### Terraformのバックエンド用のS3バケットは、Terraformで管理してはいけない
> Terraform is an administrative tool that manages your infrastructure, and so ideally the infrastructure that is used by Terraform should exist outside of the infrastructure that Terraform manages.
https://www.terraform.io/docs/backends/types/s3.html

参考
https://nekopunch.hatenablog.com/entry/2018/03/28/100042

困るユースケースとしては、`terraform destroy` のような操作を行なったときに、stateがあるS3バケットも削除対象に入ってしまうので面倒、みたいな感じ
運用方法によりますが、`terraform destroy` みたいな処理を行うことは少ないとは思うので、一緒にしておいてもそんなに困ることはない気がしています

ちゃんとやるなら別のawsアカウントで管理しておくとかが良さそう
git push -u origin masterでrejectにハマる

#git push -u origin masterできない！！
N予備校Node.jsの序盤にて
ローカルで作ったファイルをgithubにアップするため、github上にリポジトリを作って


```
git push -u origin master
```
しかし

```
To github.com:○○○/my-first-node-js.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@github.com:○○○/my-first-node-js.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

```

#参考にした記事と対応方法
【git】git pushがrejectされたときの対応方法
https://www.softel.co.jp/blogs/tech/archives/3569

対応方法 3）fetch して rebase するを実行しました
```
git fetch    （リモートの変更を取ってきて）
git rebase origin/master
```
うまく行った…！

```
$ git push -u origin master
Counting objects: 14, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 1.55 KiB | 794.00 KiB/s, done.
Total 14 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
To github.com:tsu2626/my-first-node-js.git
   dadbbc3..70bd482  master -> master
```

もしかしてREADMEファイルのせいで差分ができてたのか？
結局、理由まではわからなかった

コメントお待ちしております
S3 Select が C# Lambdaから使えるのはいつだろう...

Athenaは課金が心配なので、同人とかだと、S3 Selectで済ませたいLambda実装が多々あるのだが、未だに Java/Pyhont/CLI 以外でサポートされる気配がないんだよねぇ。

https://aws.amazon.com/jp/about-aws/whats-new/2018/04/amazon-s3-select-is-now-generally-available/

C#側でS3からjson-seqを拾ってパースしてクエリしてー、、とか実装するのもなんだかなーと思いつつ、。。
SORACOM Beamを使用してSAP Cloud Platformへデータを送信 

※2019年7月現在、SAP CPのNEO環境のIoTサービスは利用できなくなっています。

#**目的**
SORACOMのサービスであるSORACOM Beamを使用して、SAP Cloud PlatformのIoTサービスへデータを送信する。

※詳細は以下のブログを参照
[SORACOM Beamを使用してSAP Cloud Platformへデータを送信 ](http://www.sapsumikko.jp/entry/2018/07/10/063000)

#**手順**
①SAP Cloud PlatformのIoTサービスの設定
②SORACOM Beamの設定
③Pythonファイルの作成/実行
④送信されたデータの確認


#**手順①SAP Cloud PlatformのIoTサービスの設定**
SAP Cloud Platformにログイン。

Cloud Platform Cockpitより、「モノのインターネット」を選択
サービスが有効であることを確認し、「サービスに移動」を選択
メッセージタイプ、デバイスタイプ、デバイスを順に登録


#**②SORACOM Beamの設定**
SORACOMの管理コンソールより、SORACOM Beamの設定
※「HTTPエントリポイント」を使用


<img src="https://qiita-image-store.s3.amazonaws.com/0/22526/63215b33-1756-a51f-705a-71994103884a.jpeg" width = 60%>

青線箇所は任意の文字列で。
 

ホスト名は「iotmms(SAP CPアカウントID).hanatrial.ondemand.com」
※私のSAP CPアカウントはトライアルアカウントなので、「～trial」

 

パスは「/com.sap.iotservices.mms/v1/api/http/data/(デバイスID)」

これで完了。以下赤枠がエントリポイント
![20180710000429.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/e56b4d02-3a40-5a44-c023-79633ab08475.jpeg)


#**③Pythonファイルの作成/実行**
```python:beamscpiot.py
import time 
import json 
import datetime 
import urllib3 

#SAP CP 
#oAuth Device
oauth_credentials = (デバイスのトークン) 

#Message Type ID
message_type_id = (メッセージタイプID)

#URL
http = urllib3.PoolManager() 
headers = urllib3.util.make_headers(user_agent=None) 
headers['Authorization'] = 'Bearer ' + oauth_credentials 
headers['Content-Type'] = 'application/json;charset=utf-8' 

url = 'http://beam.soracom.io:8888/scpiot'
urllib3.disable_warnings() 

 
#send data
timestamp = int(time.time())
value = 'Python to SCP IoT test(SORACOM Beam)'
	 
body = '{"mode":"sync", "messageType":"' + str(message_type_id) + '", "messages":[{"timestamp":'+ ' "' + str(timestamp) + '"'+ ', "value":'+ ' "' +  str(value) + '"'+ ' }]}' 
r = http.urlopen('POST', url, body=body, headers=headers) 

print(body) 
print(r.data) 
```
 
RaspberryPi側で「beamscpiot.py」を実行。

#**④送信されたデータの確認**

メッセージ管理サービスコックピットよりデータの確認
「保存されたメッセージの表示」を選択

以下の名称でテーブルが作成されている
「T_IOT_(メッセージタイプID)」

送信したデータが登録されていることを確認
![20180710002129.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/5d339600-dc87-c2be-965a-213a5bd7c528.jpeg)
Javascriptで数値のカウントアップ

Web開発用メモ。数値のカウントアップ。

<p data-height="265" data-theme-id="0" data-slug-hash="KBdbJX" data-default-tab="js,result" data-user="snst-lab" data-pen-title="CountUp" class="codepen">See the Pen <a href="https://codepen.io/snst-lab/pen/KBdbJX/">CountUp</a> by snst.lab (<a href="https://codepen.io/snst-lab">@snst-lab</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```html
<html>
<div id="countup">100 Likes</div>

<script>
setInterval(async function(){
  await $('#countup').text('100 Likes');
  await $('#countup').countUp(50,1000);
},4000);

const sleep = (time) => {return new Promise(resolve => {setTimeout(() => {resolve()}, time)})};
/**
* @int tick 刻み数
* @float timeout カウントアップ終了までのミリ秒数
*/
$.prototype.countUp = async function(tick,timeout){
    const countMax = this.text().replace(/[^0-9.]/g, "");
    const unit = this.text().replace(/[0-9.]/g, "");
         
    const time = timeout/tick;
    const step = countMax/tick;
         
    var count = 0;
    while(count < countMax){
          await sleep(time);
          this.text(Math.floor(count*1000)/1000 + unit);
          count += step;
    }
    this.text(countMax + unit);
}
</script>
</html>
```
GROWI のデータを丸ごとesa.io に移行する

個人用Wikiとして[GROWI(旧Crowi-plus)](https://growi.org/)をheroku上で運用していましたが、このたび[esa.io](https://esa.io/)に乗り換えることにしましたので移行方法を残しておきます。

## 概要
GROWIの内容をすべてesa.ioに移行します。

[esa.io公式ヘルプのQiita:Teamからの移行スクリプト](https://docs.esa.io/posts/102#Qiita:Team)を参考に、これをGROWI仕様に書き換えました。

GROWIのAPIは公式にドキュメントがありませんが、[GitHubにあるルーティングスクリプト](https://github.com/weseek/growi/blob/master/lib/routes/index.js)を参考にしました。


## 手順
### GROWIのAPIトークンを生成する

![スクリーンショット 2018-07-14 14.14.19.png](https://qiita-image-store.s3.amazonaws.com/0/70437/73726105-fa3c-e029-1eb7-5cb5f75fe85b.png)

GROWIを開き、画面右上の「ユーザ設定」から「API設定」のタブを開いてAPI Tokenを発行しておきます。

### esa.io のAPIトークンを生成する

esa.ioのユーザ管理ページのApplications（``https://[team].esa.io/user/applications``）から「Personal access tokens」の横のGenerate New Tokenをクリックします。

すると、以下のようなページが現れます。

![スクリーンショット 2018-07-14 14.25.56.png](https://qiita-image-store.s3.amazonaws.com/0/70437/ce5146d9-d697-ff0d-9b60-485163882a07.png)

初期状態ではReadのみにチェックが入っていますが、**Writeにもチェックを入れ、**Saveボタンを押すとトークンが発行されます。

**トークンは一度しか表示されません**ので、必ず控えておきましょう。

### 必要なGemを用意する
以下のようにして必要なGemをインストールします。

```bash
$ gem install esa json pp net
```

### スクリプトをコピペして適切に編集する
以下のURLに掲載しているスクリプトを手元に落としてきて、``TODO``と書かれている箇所を編集します。

https://gist.github.com/expajp/128b83220caaf9bc58963afa73d71903

### コンソール上で実行する
スクリプトが置いてあるディレクトリに移動し、以下のように実行すればおしまいです。

```
$ ruby import.rb
```

初期状態ではインポートされるデータがコンソールに表示されるだけになっています。

正しくデータが表示されているのを確認したら、スクリプト最終行の

```ruby
importer.import(dry_run: true, start_index: 0) 
```

の引数を``dry_run: false``に変更して再度実行すると実際にインポートが行われます。

**うっかり2回実行してしまうと、同じ記事が2つできてしまう**ので注意しましょう。

## ポイント
* データの取得箇所をAPI経由に変更した以外は、ほとんどQiita:Teamと同様の手順で実行できました
* カテゴリは基本そのまま維持されますが、**カテゴリのトップページはesaではREADMEになっている**ため、適宜手動で変更してください
* 回し者ではありませんが、楽しいesaライフを (\\( ⁰⊖⁰)/)

## 参考サイト
以下を参考にしました。

* [CrowiのAPIを使ってみた](https://blog-asnpce.com/technology/624)
* [growi/index\.js at master · weseek/growi](https://github.com/weseek/growi/blob/master/lib/routes/index.js)
* [dev/esa/api/v1 \#noexpand \- docs\.esa\.io](https://docs.esa.io/posts/102#Qiita:Team)
* [\(\\\\\( ⁰⊖⁰\)/\)](https://docs.esa.io/posts/63)