OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlin × joobyでREST API with API reference

![image.png](https://qiita-image-store.s3.amazonaws.com/0/110859/55d0117c-fcc2-1d74-99e5-e6970f392bf8.png)

## What?
シンプルで軽量なマイクロフレームワークのjoobyにKotlinで触れてみようと思う

## Why?
仕事だとSpringなので気分転換に

## Try
公式HP
https://jooby.org/

早速トライ
https://jooby.org/quickstart/

Kotlin gradle starterを試してみる
https://github.com/jooby-project/kotlin-gradle-starter

```sh
$ git clone https://github.com/jooby-project/kotlin-gradle-starter.git && cd kotlin-gradle-starter

$ ./gradlew joobyRun # hot reloadもしてくれる https://jooby.org/doc/devtools/#gradle-hot-reload
$ curl http://localhost:8080/
Hello Kotlin!

$ ./gradlew test # spekがstarterに入ってる
```

### REST APIのエンドポイントを追加する
https://jooby.org/doc/jackson/

```gradle:build.gradle
dependencies {
    ~~~
    compile "org.jooby:jooby-jackson:$joobyVersion"
    ~~~
}
```

```kotlin:App.kt
import org.jooby.json.Jackson

data class Hello(val hello: String)

class App : Kooby({
    use(Jackson())
    ~~~
    get("/hello/{name}") { Hello(param("name").value()) }
})
```

```sh
$ ./gradlew joobyRun
$ curl http://localhost:8080/hello/taro | jq
{
  "hello": "taro"
}
```

### API referenceを導入してみる
https://jooby.org/doc/apitool/

```gradle:build.gradle
dependencies {
    ~~~
    compile "org.jooby:jooby-apitool:$joobyVersion"
    ~~~
}
```

```kotlin:App.kt
import org.jooby.apitool.ApiTool

class App : Kooby({
    ~~~
    use(ApiTool().swagger().raml())
    ~~~
})
```

```sh
$ ./gradlew joobyRun
$ curl http://localhost:8080/swagger
$ curl http://localhost:8080/raml
```

#### Swagger
<img width="776" alt="スクリーンショット 2018-08-10 22.26.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/110859/ea19c568-c43f-037f-8ae4-becc2824514c.png">

#### RAML
<img width="766" alt="スクリーンショット 2018-08-10 22.26.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/110859/fe2b2db6-69c2-0de2-be34-80f17d6c1632.png">

## 感想
* 簡単
* 周辺ツールも結構ある
* ちょっとしたAPI作るぐらいなら良さそう
* Springよりかわいい
新人エンジニアの時に知っておきたかったこと[Git編]

## はじめに
この記事は[新人エンジニアの時に知っておきたかったこと](https://qiita.com/hirokisan/items/cd45d3f6e5fa688235fc)に含まれます。
他の記事は上記のリンクから遷移可能です。あわせてご覧ください。

## [Git](https://git-scm.com/)とは？
プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。

[Wiki](https://ja.wikipedia.org/wiki/Git)より

リモートサーバに置かれた中心となるリポジトリ（ソースコード）を手元のローカル環境にコピーします。
普段、作業する際にはローカル環境のリポジトリに変更を加えます。
そして、ローカル環境のリポジトリに加えられた変更をリモートサーバに置かれたリポジトリに反映します。

## なぜGitを使うのか？
### 他の作業者に影響を与えることなくソースに変更を加えられる
リモートサーバから手元のローカル環境にリポジトリ（ソースコード）をコピーし、
ローカル環境のリポジトリに変更を加えていくため、他の人と修正作業が競合することはありません。
ただし、ローカル環境で加えた変更をリモートサーバのリポジトリに反映する際には、他の人が加えた変更と競合する可能性はあります。
それを解決するためにmergeやrebaseをするのですが、Gitを調べていく中で理解することになるはずなので、心配は要りません。

### 過去に誰がどのような変更をソースコードに加えたのかが分かる
Gitでは過去に誰がどのような変更をソースコードに加えたのかが蓄積されます。
ソースコードの記述の意図がよくわからない時には過去の変更履歴を辿ることで意図を理解することができる場合があります。
また、バグが埋め込まれている場合、いつそのバグが埋め込まれたのかをトラッキングすることも可能です。

### その他の理由
Gitを使う理由に関してはいろんな方がいろんな主張をされているかと思います。
実際にGitを使いながら、気になった時にでも調べてみてください。

[Gitの良さが分からない？ ちょっとそこに座れ](https://www.kaitoy.xyz/2016/10/06/git-vs-subversion/)

## インストール
[Gitのインストール](https://git-scm.com/book/ja/v1/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

~/local/srcにソースを配置し、~/local/binにGitを配置します。

### 依存ツールのインストール

[依存ツール](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

CentOSの場合、以下のコマンドで依存ツールをインストールします。

```
$ yum install -y curl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel
```

### インストール

```
$ mkdir -p ~/local/src
$ cd ~/local/src
$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.7.0.tar.gz
$ tar zxvf git-2.7.0.tar.gz
$ cd git-2.7.0
$ ./configure --prefix=$HOME/local
$ make all
$ make install
```

### PATHを通す

.zshrcや.bashrcなどのシェルの設定ファイルに以下の設定を追加します。

```
export PATH=$HOME/local/bin:$PATH
```

## 設定ファイル

```
$ ~/.gitconfig
```

[gitで便利なエイリアス達](https://qiita.com/peccul/items/90dd469e2f72babbc106)

## 操作
基本的によく使うのはここら辺のコマンドだろうと思います。
よく使うコマンドに関しては、設定ファイルにaliasを設定することで、毎回入力する際の手間を減らすことに繋がるはずです。
ぜひ、aliasを設定してみてください。

```
$ git add
$ git checkout
$ git commit
$ git status
$ git branch
$ git pull
$ git fetch
$ git push
$ git merge
$ git rebase
$ git stash
$ git cherry-pick
$ git reflog
$ git log
$ git mergetool
$ git remote
```

こちらの記事が参考になります。

[【Git】基本コマンド](https://qiita.com/konweb/items/621722f67fdd8f86a017)

## Tig
gitに慣れてきたら、tigというツールも触ってみましょう。
コミット履歴や編集内容などが見やすいです。

[超絶便利なGitクライアントのtigのすすめ](https://qiita.com/vivid_muimui/items/7e7a740e6537749de0c0)

## インストール

~/local/srcにソースを配置し、~/local/binにtigを配置します。

```
$ mkdir -p ~/local/src
$ wget https://github.com/jonas/tig/releases/download/tig-2.3.3/tig-2.3.3.tar.gz
$ tar zxf tig-2.3.3.tar.gz
$ cd ./tig-2.3.3
$ ./configure --prefix=$HOME/local
$ make
$ make install
```


## まとめ
この記事ではGitを共有しました。
最初はGitの概念やコマンドに戸惑うこともあるかもしれませんが、とりあえず習慣的に使ってみましょう。
1つ1つわからないことを調べて普段から使うようにすれば、いつのまにか使えるようになっているはずです。
私もまだまだ深くは理解していませんが、他の開発者がどんなコミットをしているのか調べるのは結構楽しいものです。
ぜひ、触ってみてください。
ERROR: One or more PGP signatures could not be verified! への対処メモ

# 内容
Arch Linux で AUR のパッケージをインストールしようとした時，下記のようなエラーが出て失敗したので，その際の対処メモ．

```
==> Verifying source file signatures with gpg...
    aurman_sources git repo ... FAILED (unknown public key XXXXXXXXX)
==> ERROR: One or more PGP signatures could not be verified!
```

# GnuPGで公開鍵を入手
## 1. 鍵のインポート
公開鍵を公開鍵サーバからインポート．

```shell
# <KeyID> は上の (unknown public key <KeyID>) の値
$ gpg --recv-keys <KeyID>
```

## 2. 鍵の指紋を確認
鍵の電子指紋が正しいか確認．（レポジトリの```PKGBUILD```に```validpgpkeys=('VALUE')```として書いてある）

```shell
$ gpg --fingerprint <KeyID>
```

## 3. 鍵への署名
その鍵を信用するものとしてサイン．（ここは必要ないかも）

```shell
$ gpg --lsign-key <KeyID>
```

## 4. 鍵を表示
鍵が正しくインポートされているか確認．

```shell
$ gpg --list-keys
```

# 上記で上手くいかない場合

設定ファイルが保存されている```$(GNUPGHOME)/.gnupg```（デフォルトは```~/.gnupg```）の所有権を確認．

```shell
$ ls -la ~/
...
drwx------   5 root root    4096 Aug  5 14:28 .gnupg
...
```

所有権がrootになっていたので，ユーザに変更．

```shell
$ chown <username>:wheel ~/.gnupg
```

# 参考
- https://bbs.archlinux.org/viewtopic.php?id=191954
- https://wiki.archlinux.jp/index.php/GnuPG
- https://superuser.com/questions/954509/what-are-the-correct-permissions-for-the-gnupg-enclosing-folder-gpg-warning
(Laravel) fillを使ってモデルの複数カラムを更新する

公式マニュアルではモデルを更新するとき、プロパティを指定して値を入れる方法が紹介されている。

https://readouble.com/laravel/5.5/ja/eloquent.html

```php
$flight = App\Flight::find(1);

$flight->name = 'New Flight Name';

$flight->save();
```

しかし、これは更新したいプロパティが複数あるときは、つらつらと並べないといけない。

そんなときは`fill`を使うと便利。

```php
$flight->fill(['name' => 'New Flight Name'])->save();
```

Arrayで指定できるので以下のようにすることもできる。

```php
public function update(Request $request)
{
    $flight = App\Flight::find($request->id);
    $flight->fill($request->all())->save();
}
```

こうすればいちいちプロパティを指定せずに済むので便利ですね。
新人エンジニアの時に知っておきたかったこと[tmux編]

## はじめに
この記事は[新人エンジニアの時に知っておきたかったこと](https://qiita.com/hirokisan/items/cd45d3f6e5fa688235fc)に含まれます。
他の記事は上記のリンクから遷移可能です。あわせてご覧ください。

## [tmux](https://github.com/tmux/tmux)とは？
>tmuxはターミナルマルチプレクサーです。複数のターミナルを一つのスクリーン内に作成し、操作することができます。

>バックグラウンドで処理を実行中に一度スクリーンから離れて後から復帰することも可能です。

[readme](https://github.com/tmux/tmux/blob/master/README.ja)より

## tmuxの何が便利なのか
バックグラウンドで動くため、ターミナルアプリでウィンドウを閉じてもすぐに同じ内容のウィンドウを再開できます。

たとえば、どこかのサーバーにログインして作業している際にネットワークが切れた場合にtmuxを使用していれば、ネットワークが切れる前の状態で作業を再開できます。

## インストール
### 依存
[readme](https://github.com/tmux/tmux/blob/master/README.ja)に書かれている依存ツールが必要になります。
インストールの前に依存ツールを用意しておきましょう。

### インストール
[source](https://github.com/tmux/tmux/releases)

試しにtmux2.6をインストールしてみます。
ソースは~/local/srcに配置し、tmux2.6は~/local/binに配置します。

```
$ mkdir -p ~/local/src
$ cd ~/local/src
$ wget 'https://github.com/tmux/tmux/releases/download/2.6/tmux-2.6.tar.gz'
$ tar zxvf tmux-2.6.tar.gz
$ cd tmux-2.6
$ ./configure --prefix=$HOME/local
$ make
$ make install
```

### 設定ファイル
`.tmux.conf`という設定ファイルがあります。

キーバインド等の設定が可能です。

[達人に学ぶ.tmux.confの基本設定](https://qiita.com/succi0303/items/cb396704493476373edf)

## 操作
操作に関しては以下の記事が参考になります。

[tmuxの使い方](https://qiita.com/vintersnow/items/be4b29652ff665c45198#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C)

## [tmuxinator](https://github.com/tmuxinator/tmuxinator)を使うともっと便利に
tmuxで起動するセッションを予め設定しておき、そのセッションを一発で起動してくれます。

### インストール

```
$ gem install tmuxinator
```

もし、使用するgemとrubyのバージョンがtmuxinatorのバージョンと合わない場合、tmuxinatorのバージョンを指定すればインストール可能です。

```
// 例
$ gem install tmuxinator -v "0.9.0"
```

### 設定
[設定ファイル](https://github.com/tmuxinator/tmuxinator/tree/master/completion)

```
$ mkdir -p ~/.tmuxinator
$ cd ~/.tmuxinator
$ wget https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.zsh
$ echo 'source ~/.tmuxinator/tmuxinator.zsh' >> ~/.zshrc
```

### 確認
以下のコマンドで設定をインストール状況を確認できます。

```
$ mux doctor
```

<img width="299" alt="スクリーンショット 2018-07-30 22.57.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/97975/bc332fb7-a6e0-9428-7fb5-8ba54549fafe.png">

Yesとなっていればインストール完了です。


### 使い方
以下のコマンドを実行すると、プロジェクト用の設定ファイルが作成されます。
$projectをあなたの好きな名称に変更してください。

```
$ mux new $project
```

[readme](https://github.com/tmuxinator/tmuxinator)を参考にして設定ファイルを設定してみてください。

設定が終わったら、以下のコマンドでセッションを起動します。

```
$ mux $project
```

## まとめ
この記事ではtmuxをご共有しました。
初めてtmuxを触った時には、これを使うと何がいいんだろうと感じました。

ところが、しばらく触ってみると、その便利さを実感するようになりました。
tmuxinatorと合わせて使うことで、一発で作業環境を用意することが可能になります。
とても便利です。

ぜひ、早い段階から導入してtmuxの利用を習慣化してみてください。
きっと作業効率が上がるはずです。
Windows+VSCode上でReact開発環境を構築

今更感が否めないけど触ってみたかったので取り敢えず作った開発環境に関する自分向けの手順書

#対象
- 取り敢えず触ってみたい
- WindowsPCで開発している
- VSCodeをエディタとして使用している（VSCodeならでは部分はほぼないけど）

# 準備するもの
- WindowsPC
- [Node.jsインストーラ](https://nodejs.org/ja/)

# 1.Node.jsをインストールする
1. インストーラをダウンロードしておく（LTS版の最新で問題ないはず）
2. ダウンロードしたインストーラを実行
3. 下記画面が出てくるので、インストールを済ませる（デフォルト設定のままNext連打で問題ないはず）

![node.png](https://qiita-image-store.s3.amazonaws.com/0/268011/7861dcb4-88ac-4e06-8d1d-7df266b728bc.png)

4.コマンドプロンプトから下記コマンドを実行し、パスが通っていることを確認

```cmd
node -v
npm -v
```

#2. create-react-appをインストール
1. 作業用の任意のフォルダを作成し、右クリック⇒「Open With Code」を選択
2. 「Crtl+@」で表示されるターミナル画面で下記コマンドを実行<br>
 
    ```cmd
    npm install -g create-react-app
    ```

3. ターミナル画面で下記コマンドを実行し、プロジェクトを作成

    ```cmd
    create-react-app <任意のプロジェクト名>
    ```

4. 「Happy hacking!」が表示されれば成功
5. ターミナル画面で下記コマンドを実行する

    ```cmd
    cd <先ほどのプロジェクト名>
    npm start
    ```

6. ブラウザが立ち上がり、「React App」ページが表示されれば成功

#3. 試しに「sample/src/App.js」を触ってみる
わざとエラーを発生させると？
下記のようにdivに対する閉じタグの「/」を削除してみる

```javascript:sample/src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      <div>
    );
  }
}

export default App;

```

VSCode上にはエラーの詳細が表示され、
![vscode.png](https://qiita-image-store.s3.amazonaws.com/0/268011/1e25ecdc-b4f1-0cf5-8189-db97a0bbf6ea.png)

ブラウザ上にはコンパイル失敗の旨が表示される。
![chrome.png](https://qiita-image-store.s3.amazonaws.com/0/268011/ad7bb9bd-97b7-c59c-f00e-24ddd615a235.png)

わかりやすい！

# 参考
[facebook/create-react-app](https://github.com/facebook/create-react-app)
[コマンド一発でReactの開発環境を構築してくれるFacebook製ツール「create-react-app」](https://mae.chab.in/archives/2910)
[React開発環境のセットアップで挫折し、create-react-appに救われた件](https://qiita.com/yamachan360/items/efcff4bd14fe623807ab)
RubyでEnumerable.eachの進捗を表示するメソッドを実装

こういうの
<img src="https://qiita-image-store.s3.amazonaws.com/0/50391/f5556631-ba62-cbb2-28d2-7496e9d1eb69.gif" alt="each_with_progress" width="320px">

## 環境
- Ruby 2.5.1

## 実装
進捗を標準出力に表示する`Enumerable.each_with_progress`メソッドを、新たに追加します。

```ruby:index.rb
module Enumerable
  def each_with_progress(&block)
    self.each_with_index do |element, index|
      print "\r#{index + 1}/#{self.length}"
      block.call(element, index)
    end
    print "\r\n"
  end
end
```
`print`文を変更すれば、割合表示にしたり色々できると思います。

### 呼び出し側のコード
```ruby:index.rb
puts "# program start"

['a','b','c'].each_with_progress do |elem|
  sleep 1
  print " #{elem}"
end

['a','b','c'].each_with_progress do |elem, index|
  sleep 1
  print " #{index} -> #{elem}"
end

puts "# program end"
```

### 実行結果

```bash
$ ruby index.rb
# program start
3/3 c
3/3 2 -> c
# program end
```

## Enumerableで実行可能にする
上記の例は、配列など`length`メソッドが定義されているクラスでしか使えません。

Enumerableで`length`が実装されていないクラス(例えば範囲オブジェクトなど)では、`length`の代わりに`Enumerable.count`を使います。

```ruby:index.rb
module Enumerable
  def each_with_progress(&block)
    length = self.respond_to?(:length) ? self.length : self.count

    self.each_with_index do |element, index|
      print "\r#{index + 1}/#{length}"
      block.call(element, index)
    end
    print "\r\n"
  end
end
```

こうすることで、Enumerableモジュールを継承しているオブジェクトで実行可能になります。

### 呼び出し側のコード
```ruby:index.rb
puts "# program start"

sum = 0
(1..10000).each_with_progress do |elem|
  sum += elem
end
puts sum

puts "# program end"
```

### 実行結果
```bash
$ ruby index.rb
# program start
10000/10000
50005000
# program end
```

## 参考
- [count \(Enumerable\) \- Rubyリファレンス](https://ref.xaio.jp/ruby/classes/enumerable/count)
- [【Ruby】標準出力でかっこよく進捗を表示する \- 元ひよっこSEがフルスタックエンジニアを目指すブログ](http://bluenotefit.hatenablog.jp/entry/2018/01/14/225324)
- [Rubyにおけるsize, length, countの違いについて \- Qiita](https://qiita.com/tacumai/items/28100326874dae9e5f5c)
オブジェクト配列の値渡し(extend on NodeJS)

# 一次元配列の値渡し
Array.slice()かArray.concat()を使えばよい。
[JavaScriptで配列のコピー（値渡し）](https://qiita.com/takahiro_itazuri/items/882d019f1d8215d1cb67)

ただし、値渡しできるのは**文字列**か**数値**のみ。
**オブジェクトはできない**。
[Array.prototype.slice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)

>- もし参照されたオブジェクトが修正されたら、その変更は新しい配列と元の配列の両方に現れます。
- 文字列や数値 (String オブジェクトや Number オブジェクトではなく) については、slice は文字列や数値を新しい配列にコピーします。一方の配列の文字列や数値に変更を加えても、他方の配列に影響はしません。

# オブジェクト配列はどうする？
[JavaScriptのオブジェクトを扱うとき、=はただの値渡しではない](https://woshidan.hatenablog.com/entry/2014/09/06/002003)
>オブジェクトの場合、値渡しされるのはポインタ(参照の値渡し)。

>- Jqueryの$.extend()を使う

## NodeJSではjquery.extend()は使えない
~~$ npm install jquery~~
~~var $ = require('jquery')~~
~~$.extend({},object)~~

NodeJSで使おうとすると、
**<font color="red">extend is not a function</font>**と怒られる。

## [Node.jsで$.extendを使いたい!!!](https://qiita.com/PianoScoreJP/items/e88c3485b1a28ef90ace)

```
$ npm install extend
```

```js
var extend = require('extend')
//targetObjectにobject1,object2をマージするやり方
extend(targetObject, object1, object2);

//新規にオブジェクトを生成したいときは空のオブジェクトにマージする
extend( {},{値渡ししたいオブジェクト} )
```
[GitHub](https://github.com/justmoon/node-extend)
Xを立ち上げずにmpvを利用する

非常にニッチな状況だと思いますが、Xを立ち上げずに動画を再生したい機会がありました。
スペックもそんなに高くないため、なるべくCPU使用率も減らしたい。

## 結論

以下のコマンドで再生可能です。(hwdecは各自環境に合わせる)

```
(GPUあり)
 $ mpv -vo gpu -gpu-context drm -hwdec=vaapi sample.mp4

(GPUなし)
 $ mpv -vo drm sample.mp4
```

## 初めに試した方法

mplayerの頃からFrameBufferを利用して再生する機能がありますが、FrameBufferであるためCPUを利用したMemory Copyが走ってCPU使用率が非常に高いです。

```
 $ mplayer -vo fbdev sample.mp4
```

mpvで同様のことをしようとすると、以下のコマンドで再生できます。

```
 $ mpv -vo drm sample.mp4
```

こちらもDirect Rendering Managerを利用してXなしにvideo出力が出来ますが、非常にCPU利用率が高いです。


## HW支援機能を使う

GPUがある場合、OpenGL/OpenGL ESを使って描画を高速化することができます。`-vo gpu`オプションを使うと利用できますが、デフォルトではX用のgpu contextを選択しようとするため、コンソール上からは利用できません。GPU/DRMを組み合わせて使うオプションを指定すると再生が可能です。

```
 $ mpv -vo gpu -gpu-context drm sample.mp4
```

また、video codecのHW decodeをサポートしている場合、HW支援機能を使うことができます。vaapiを利用してHWデコードを行う場合、以下のコマンドで利用できます。

```
 $ mpv -vo drm -hwdec=vaapi sample.mp4
```

## トラブルシューティング

- Q. 再生できません！
    - mpvの最新版を使うと解決する可能性があります。私の環境だと0.28.2では再生できず、git cloneして最新版を利用しました。


## 参考資料

- [VIDEO OUTPUT DRIVERS - mpv.io](https://mpv.io/manual/master/#video-output-drivers)
- [GPU renderer options - mpv.io](https://mpv.io/manual/master/#gpu-renderer-options)
購入したスマート LED の Android 向け操作用アプリをリバースエンジニアリングして不具合修正＆機能追加を試みた結果……

# 経緯

*もう爆音のアラームで目覚めたくない* :alarm_clock:

そう思いタイマー機能で時間になると照明が点灯するスマート LED を購入してみることにしました。これで毎朝心地よく起きれるようになるのでしょうか！？

![3B4F10D7-6197-4745-A049-EC5D997B6F66.png](https://qiita-image-store.s3.amazonaws.com/0/6881/28ec4cfc-3dc2-f907-acf9-a9c721ddd1b1.png)

# 市場

日本でスマート LED の購入を検討すると [Philips](https://www.philips.co.jp/) の [Hue](https://www2.meethue.com/) が候補に挙がると思います。
渋谷と赤坂にある家電量販店に足を運んでみたところ、スマート LED の取り扱いは [Hue](https://www2.meethue.com/) オンリーでした。
これはブルーオーシャンなのでしょうか :ocean:

# [Hue](https://www2.meethue.com/) について

ルーターを介して [Hue](https://www2.meethue.com/) を Wi-Fi 接続することでスマホから輝度変更やタイマー設定などを行うことができます :sparkles:

# 個人的事情

実家住まいであれば迷わず [Hue](https://www2.meethue.com/) をポチっていたと思いますが、現在 Wi-Fi 無しの格安シェアハウスに居住しているため、[Hue](https://www2.meethue.com/) をブリッジと接続させることができません :cry:
引っ越したりネット契約すればいい話ではありますが、私は Bluetooth 接続のできるスマート LED を探す道を選びました :railway_track:

# 競合製品

某 EC サイトで検索してみると多くの眉唾物が存在しているということが分かりました。
スマート LED をネット検索しても [Hue](https://www2.meethue.com/) 以外の情報がほぼ見つからなかったので１つ１つ吟味していくことにしました。
タイマー機能付きで Bluetooth 接続ができる安くて良さげな製品があったのですが、操作用 Android アプリをインストールして起動してみたところ連絡先・位置情報・ストレージへのアクセスを許可しないと利用できないというヤバめな仕様で、確認すると :flag_cn: 製品というパターンが多かったです。
レビューで :star: ５の絶賛コメントしか並んでいない等怪しい商品を見抜く選球眼が養われたと思います :eyes:
スマート LED 市場は未だ成熟していないということでしょうか。

# 勇気を振り絞って :money_with_wings:

電球の選定にも疲弊してきたので取り敢えず買ってみて粗悪品であればクーリングオフしようと思い￥ 10,000 の中古品をお買い上げしてみました :purse:

## 決め手 :raising_hand:

- 海外 YouTuber がレビュー動画を上げていた
    - 存在はしているらしい
- :flag_us: 製品っぽい
- そこそこのお値段なのでしっかりしているはず

# 開封の儀 :package:

思いの外ちゃんと届きました :truck:
E26 の LED 専用クリップライトを仕入れて電源を入れると、なんと光が灯りました :bulb:

# スマホから操作できるのか :iphone:

所持している Android 6.0.1 の [Nexus 7 (2013)](https://www.asus.com/jp/Tablets/Nexus_7_2013/) と iOS 11.4.1 (15G77) の [iPhone 5s](https://support.apple.com/kb/SP685) に専用アプリをインストールして Bluetooth 接続を行ってみましたが…… Android・iOS 版共にタイマー機能が備わっているにも関わらず全く動作しませんでした :innocent:
:flag_jp: で使うからダメなのでしょうか？
特に Android アプリは電源 ON/OFF 以外のボタンはタップしても全く反応がありませんでした :angel:

# 自力でバグを修正できるのか :space_invader:

日頃 Android アプリ開発を生業としているので、apk を抽出して dex2jar と JD-GUI でアプリのソースコードを入手できれば、手元でデバッグして明るさ調整やタイマー機能を実装できるのではと思うに至りました :thought_balloon:

## リバースエンジニアリングの方法について :book:

- https://speakerdeck.com/toastkidjp/droidkaigi-2018
    - https://www.youtube.com/watch?v=0g2awN1CNuU

# `classes-dex2jar.jar` の中身は :mag:

[ProGuard](https://developer.android.com/studio/build/shrink-code) によりコードの難読化が施されていたため諦めました :end:

<img width="712" alt="スクリーンショット 2018-08-05 16.56.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/6881/014e2d04-4714-bc28-eaf5-445414715923.png">

# 展望 :telescope:

アプリにアップデートが降ってくることを期待します :pray:
もしくは指定の時間になると端末の指定の位置をタップしてくれるアプリがあれば利用してみたいと思います。

# 後日 :sunrise_over_mountains:

購入した EC サイトで 3rd パーティの出品者に返品リクエストを送信したところ、検品作業が行き届いていなかったのと取り寄せ元が在庫切れということで、全額返金かつ商品は返送しなくてもいいという神対応をしていただけることになりました。
結果として手元に高価なスマート LED が残ることになったので、Android または iOS で指定時間に指定位置をタップできるアプリを自作してみようかと思います :desktop:
deviseの導入ですでにあるモデルに追加する場合

新規に作成したプロジェクトへのdeviseの導入は以下を参照してください。
https://github.com/plataformatec/devise#getting-started

# deviseの導入ですでにあるモデルに追加する場合

すでにあるモデルにdeviseを導入する場合

今回は`User`モデルがすでにあり、そこにdeviseを適用する。

導入前

```ruby:db/schema.rb
  create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "email"
    t.string "password"
    t.string "userName"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
```

## 導入手順

基本的には新規モデルの作成時と変わらないの3. deviseのインストールまでは新規導入手順と同じ

1. Gemfileにdeviseの追加
2. bundleのインストール
    3. `bundle install`
3. deviseのインストール
    4. `bin/rails generate devise:install`
4. deviseでモデルの作成
    5. `bin/rails g devise User`
6. マイグレーションファイルの編集
7. データベースのマイグレーション
    8. `bin/rails db:migrate`

以降は通常のdevice導入後と変わらないはず。。。

## deviseでモデルの作成

コマンドはdeviseでモデルの作成と同じ。
テーブルの新規作成か変更かはrailsが判定してくれる。

## マイグレーションファイルの編集

今回追加されるカラムはマイグレーションファイルを見れば分かる。
この中ですでにあるものがあるとマイグレーションに失敗するのでそれを取り除く。
今回は`email`。
（`password`も取り除く必要があるかと思ったが、`encrypted_password`だったので、とりあえずなにもしない）

```ruby:20180805072136_add_devise_to_users.rb
# frozen_string_literal: true

class AddDeviseToUsers < ActiveRecord::Migration[5.2]
  def self.up
    change_table :users do |t|
      ## Database authenticatable
#      t.string :email,              null: false, default: "" # 不要なのでコメントアウト
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      # Uncomment below if timestamps were not included in your original model.
      # t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end

  def self.down
    # By default, we don't want to make any assumption about how to roll back a migration when your
    # model already existed. Please edit below which fields you would like to remove in this migration.
    raise ActiveRecord::IrreversibleMigration
  end
end
```
AppleScript：備付トラックパッドの有効無効を切り替える

実行環境 macOS High Sierra 10.13.6

```applescript:
if running of application "System Preferences" then
	quit application "System Preferences"
	delay 1
end if
tell application "System Preferences"
	reveal anchor "Mouse" of pane id "com.apple.preference.universalaccess"
	activate
	tell application "System Events"
		tell process "System Preferences"
			click checkbox 3 of window 1
			set valueCheckBox to value of checkbox 3 of window 1
		end tell
	end tell
	quit
end tell
```
Rails こまごま メモ

# こまごまとしたことを書き連ねるよ

## submitボタンの二度押し防止
bottunやらformを作るヘルパー関数に`data: { disable_with: '送信中' }`を入れる

```erb:form_forの中で
<%= f.submit '運営者に意見を送る', class: 'btn btn-default',
    data: { disable_with: '問い合わせ中...' } %>
```

```erb:ボタンタグの中で
<%= button_tag type: "submit, data: { disable_with: '送信中' } do %>
        投稿する
<% end %>
```
shellscriptによるsshログインの自動化

少し前の記事で、ssh \<tab>とtabをたたくと、.ssh/configに記載したホスト名で補完してくれるscriptができ、ちょっと丁寧めに紹介しました。
-> https://qiita.com/hidaro/items/384cc8dd156364cb035f

これはそれの続きとなります。次はsshログインを自動化しましょう。

```~/assh.sh
#!/bin/bash

passwd=`grep '  #'$1'pass' ~/.ssh/config | awk '{print $2}'`
cr="\n"

expect -c "
  spawn ssh $1
        expect \"password:\"
        send $passwd$cr
  interact
"
```

このスクリプトに関してはほぼ以下の記事を見れば内容がよくわかると思います。
http://www.uetyi.com/server-const/entry-158.html
expectに関して非常にわかりやすかった記事です。

加えて、"assh"と叩くだけで実行できるように、.bashrcにはエイリアスを追記しておきます（assh = Auto SSHの略）

```~/bashrc.
alias assh=". ~/assh.sh"
```
ちなみにassh.shのパスは好きなとこに置き換えて大丈夫です。

sshに自動でログインするためには、ホストに対応したpasswordが必要です。
このpasswordは、~/.ssh/configに記載しています。

```~/.ssh/config.
Host sshhost
        HostName hogehost
        User hogeuser
        Port 22
        #sshhostpass hogepassword
```
※独自に編み出した方式なので、もっといいのあったら教えてください

ちなみに`assh.sh`においては、

```assh.sh
passwd=`grep '  #'$1'pass' ~/.ssh/config | awk '{print $2}'`
```
この一文でpasswordをgrepして抽出しています。

とはいえ、いちいちこんなものを`~/.ssh/config`に記入していくのは面倒すぎますね。

登録を楽にするためのスクリプトも用意しました。

```rssh.sh
#!/bin/bash

echo -n 'Host -> '
read Host
echo -n 'username -> '
read username
echo -n 'hostname(FQDN or IP) -> '
read hostname
echo -n 'port -> [22] '
read port
if [ -z "$port" ] ; then
  port='22'
fi
echo -n 'password ( or passfrase ) -> '
read password
if [ -z "$password"] ; then
  password='defaultpassword'
fi
echo -n 'key path -> [] '
read keypath
if [ -z "$keypath"] ; then
  keypath='none'
fi

echo >> .ssh/config
echo 'Host '$Host >> .ssh/config
echo '  HostName '$hostname >> .ssh/config
echo '  User '$username >> .ssh/config
echo '  Port '$port >> .ssh/config
if [ -n "$keypath" ] ; then
  echo '        IdentityFile '$keypath >> .ssh/config
fi
echo '  #'$Host'pass '$password >> .ssh/config

cr="\n"

expect -c "
  spawn ssh $Host
        expect \"password:\"
        send $password$cr
  interact
"
```
対話式で~/.ssh/configの内容を作成できるscriptです（rssh = Register SSHの略）。

ちなみに情報が正しければそのままログインできます。
consoleへの出力はこんな感じ

```console.
user@sshcliant:~$ rssh
Host -> test
username -> hogeuser
hostname(FQDN or IP) -> hogehost
port -> [22]
password ( or passfrase ) ->
key path -> []
spawn ssh hogehost
hogeuser@hogehost's password:
Last login: Sun Aug  5 15:46:18 2018 from sshclient
```
`.ssh/config`への追記内容はこんな感じ。

```.ssh/config.
Host test
        HostName hogehost
        User hogeuser
        Port 22
        IdentityFile none
        #testpass defaultpassword
```

これで、rsshで登録し、その後はassh \<hostname>と打つと自動ログインできるようになりました。
しかも assh \<tab>で自動補完が効きます。

最後まで読んでくださいましてありがとうございました。
お役に立てていれば幸いです。

次は鍵認証にも対応したいですね。とはいえexpectで分岐させるだけなので簡単にできるはず...

#鍵認証も実装しました。

```~/assh.sh
expect -c "
  spawn ssh $1
  expect \"password:\" {
    send $passwd$cr
  } \"passphrase\" {
    send $passwd$cr
  }
  interact
```

## 追記

https://github.com/tarohida/auto_ssh_utils

ソースコードをGitHubにて公開しました．MITライセンスで公開しますので，ライセンスの範囲内にてご自由にどうぞ．
AWS Glue のジョブ作成における Tips 

# 目的
AWS Glue を触る中で躓いた点をまとめて整理する。

# Glue ジョブスクリプト作成 Tips
## ジョブプロファイルは有効にする
データの抽出・変換処理のパフォーマンス向上のために、ジョブプロファイルは有効化を選択しておく。
メトリクスは CloudWatch から参照できる。
リソースが有効活用されているかを確認しながら、コストも含めてジョブの設定・スクリプトを最適化していくことができる。

## Glue の自動生成ジョブは処理が重い
Glue のジョブ作成時に、 「このジョブ実行」の選択肢で 「AWS Glue が生成する提案されたスクリプト」を選択すると、 指定した設定をもとに一連の処理を実行するスクリプトが自動生成される。
しかし、クローラーで作成したテーブルを使ってジョブを作るとテーブルの全データを temporary ディレクトリにコピーするようで、大量データを扱う際には効率が悪い。

なので、例えば s3 から csv データを取得する場合には、可能であれば pySpark の read 処理をそのまま使う方が早く済む。

```python
df = spark.read.option("delimiter",",").csv("s3://mydata/xxx",header=True)
```

## Glue のジョブパラメータを利用するには「--」をつける
Glue のジョブを実行する際にジョブのパラメータを指定できる。
このとき、 GUI で操作している場合でも「--」をつけてジョブパラメータを入力する必要がある。
<img src="https://qiita-image-store.s3.amazonaws.com/0/269590/a181162c-2e84-95bd-c733-75e6aa3a2983.png" width=50%>
この場合、ジョブスクリプト上では下記で入力パラメータを取得できる。

```python
args = getResolvedOptions(sys.argv, ['JOB_PARAM'])
param = args['JOB_PARAM']
```

「--」をプレフィックスに入れずにパラメータを設定するとどうなるかというと、無視される。
無視されるので、ジョブスクリプト上でパラメータを取り出す処理で指定したパラメータを取得できずにエラーとなる。
コマンドラインからならともかく、画面から入力する場合も「--」を入力しなければならないのはちょっと違和感あるものの、このような仕様らしい。

## ジョブパラメータに現在時刻を設定する
Glue の内部での実行環境は linux 上のようなので、ジョブパラメータの値に`` `date "+%Y-%m-%d` ``と入力すればパラメータ自体に現在時刻を設定することができる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/269590/904eacb4-becf-3dff-0cff-80f1960a4a95.png" width=50%>

とはいえ、 ジョブスクリプト内で現在時刻を取得する処理を実装すればほとんどのケースで困らないはず。
この方法で現在時刻を取得するのは Glue 内部の実行環境に依存してしまうので、余程のことがない限りやらない方が良い。

# Glue ジョブ設定 Tips
## DPU を変えると何が変わるのか？
Spark の最大 executer 数が変化する。
具体的には

```python
spark.dynamicAllocation.maxExecutors
```

のパラメータが変更される。
ただし、 DPU に指定した数字がそのまま最大 executer 数になるわけではない模様。
ほかにも変化があるかもしれないが、 表面的には DPU が増えると executer 数が増えて処理速度のアップが処理内容によっては期待できる。

## Glue の Spark オプション
Spark オプションでメモリは 5GB、コア数は4コアで固定されている様子。

```shell
 --conf spark.executor.memory=5g
 --conf spark.executor.cores=4
```

Glue を使う上で Spark の設定変更はできないので、メモリ不足などでジョブが失敗する場合はスクリプト側を変更するしかなさそう。

# Glue ジョブ入出力データ Tips
## 出力ファイル名は指定できない
Glue のジョブスクリプトで結果出力のファイル名を指定する機能は特にない模様。
Spark をベースにしているので当然といえば当然か。

## 出力ファイルを1つにまとめる
Spark と同様、 partition を1に指定すれば出力ファイルは1つになる。
しかし、当たり前のことだが partition を分けないことによるパフォーマンスの悪化は避けられない。
また、出力結果を Redshift などで取り込むことを考えると、ファイルが複数に分散されているメリットのほうが大きい。

なので、余程の理由がない限り出力ファイルを1つにまとめない方がよさそう。

# さいごに
何度か Glue を触ってみて、少しづつ便利さと不便さがわかり始めてきた。
今のところ一番残念に思っているのは python は version 2.7 しかサポートしていないところ。
いつか version 3.6 もサポートされるんだろうか。。。
Mac版のPhpStormを日本語化する

先日JetBrainsが50%セールを行っていたので、そのタイミングでPhpStormを買ってみた。
せっかくなので[こちら](https://www.willbrains.jp/page/4)のサイトを参考に日本語化する。


# 環境
| OS | バージョン |
|:------------------|:--------|
| macOS High Serria | 10.13.6 |
| PhpStorm | 2018.2 |

# 前提条件
- PhpStormがインストール済みであること

# 手順
2通りの手順があるようだ。

 1. Pleiadesインストーラーで簡単日本語化
 2. 手動コピーと設定ファイル編集で日本語化

Windows、Macの場合はElectronで作られた日本語化用のインストーラーが付属しているらしく、日本語化は簡単らしい。 
今回は 2. の「手動コピーと設定ファイル編集で日本語化」で行ってみる。

## Pleiadesダウンロード
以下サイトからMac版のPleiadesをダウンロードする。
http://mergedoc.osdn.jp/#pleiades.html

## PleiadesをPhpStormのpluginsディレクトリにコピーする
ダウンロードしたファイルを解凍すると、「plugins/jp.sourceforge.mergedoc.pleiades/」ディレクトリが確認できる。この「jp.sourceforge.mergedoc.pleiades」をディレクトリごとコピー先へコピーする。

▼ コピー元
<img width="341" alt="ダウンロード後.png" src="https://qiita-image-store.s3.amazonaws.com/0/167094/e5a536c7-9158-4a11-2a24-1dcbabb1ed73.png">

```text:コピー先
$ /Users/(ユーザ名)/Library/Preferences/PhpStorm2018.2/plugins
```
※ PhpStorm2018.2の中にpluginsディレクトリが存在しない場合、pluginsディレクトリを作成してコピーする。


## カスタム VM オプションファイルを編集する
以下のVMオプションファイルを開く。

```text:VMオプションファイルPATH
$ /Users/(ユーザ名)/Library/Preferences/PhpStorm2018.2/phpstorm.vmoptions
```

以下内容をファイルに追記する。

```text:追記内容
-Xverify:none
-javaagent:/Users/(ユーザ名)/Library/Preferences/PhpStorm2018.2/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
```

※ VMオプションファイルに「-Xverify:none」が記述済みの場合、この行の追記は不要。

## PhpStorm再起動
PhpStormを再起動すればメニューなど日本語化されている。

自分の場合はこれで日本語化できた。
Checking the point if internal among three points with python

```python
import matplotlib.pyplot as plt
import numpy as np
import sys
import random

pa=[random.randint(-10,10),random.randint(-10,10)]
pb=[random.randint(-10,10),random.randint(-10,10)]
pc=[random.randint(-10,10),random.randint(-10,10)]
x=float(sys.argv[1])
y=float(sys.argv[2])

def contains(g, p): 
  n = len(g)
  x = False
  for i in range(n):
    a = np.array(g[i]) - np.array(p)
    b = g[(i+1)%n] - p 
    if (np.linalg.norm(np.cross(a,b)) < np.finfo(np.float).eps \
        and np.dot(a,b) < np.finfo(np.float).eps):
        return 1
    if (a[1] > b[1]):
        b,a = a,b 
    if (a[1] < np.finfo(np.float).eps and np.finfo(np.float).eps < b[1] \
        and np.cross(a,b) > np.finfo(np.float).eps):
        x = not(x)
  if (x):
      return 2
  return 0

print(pa,pb,pc)
print(contains(np.array([pa,pb,pc]),np.array([x,y])))
left = np.array([pa[0],pb[0],pc[0],pa[0]])
height = np.array([pa[1],pb[1],pc[1],pa[1]])
plt.plot(left, height)
plt.plot(x,y,'bo')
plt.show()
```
* example
<img width="540" alt="スクリーンショット 2018-08-06 17.32.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/147303/26c5826a-0b33-acf2-4f78-6d01de643006.png">

# Refs.  
https://qiita.com/adad/items/b6842af8778ddff10d77  
http://www.geisya.or.jp/~mwm48961/koukou/area1.htm  
https://note.nkmk.me/python-random-randrange-randint/
JXA + Amazon Dash ButtonでiTunesを遠隔操作してみた

2018年夏、猛暑過ぎますね。
今日も引きこもりが捗ります、 @shIbaInu42 です。
最近はお仕事で作業プロセスを自動化したり、
自宅でも自動化に思いを馳せたりしています(**自動化は大事、板東は英二**)。
今回は [JXA(Javascript for Automation)](https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html) と [Amazon Dash Button](https://www.amazon.co.jp/Amazon-Dash-Button-%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5-%E3%83%9C%E3%82%BF%E3%83%B3/b?ie=UTF8&node=4752863051) でMacのアプリケーションを遠隔操作したいと思います。

# 目次
- 1. 目的
- 2. 準備するもの
- 3. 作成と実行
- 4. まとめ

# 1. 目的
帰宅時、ソファに座った状態で「**iTunes(on Mac)の音楽をすぐ鳴らしたい**」という私の欲望を満たすこと。

# 2. 準備するもの

- Amazon Dash Button
- JXAとDash Button のNodeモジュール(↓のインポートを実行)  

```script:Command
npm i dash-button
npm i jxa
```
- Dash Buttonを開発用にセットアップ  
→　[参考](https://qiita.com/dkawashi/items/e6621c4b712b509c73ec)

# 3. 作成と実行

## 作成(コーディング)

「Dash Buttonが押されたらiTunesを再生/一時停止する」というコードを書く。
【※】5行目の物理アドレスの取得方法は[コチラ](https://qiita.com/takustaqu/items/8539b33780c9675c8657)を参照ください。

```Javascript:remoTunes.js
//
//  remoTunes let us remotely control iTunes via ARP
//  [Author]: @shIbaInu42

// Physical address of Dash button
const PHYSIC_ADDR = "XX:XX:XX:XX:XX:XX";

// initialization of valuables
var dBtn = require("dash-button");
var iBtn = new dBtn(PHYSIC_ADDR);
var macApp = require("jxa").Application;
var iTunes = macApp("iTunes");

iBtn.addListener(
  () => {
    iTunes.playpause();
  }
);
```

## 実行

作成が完了したら、実行します。
  
```script:Command  
node remoTunes.js
```  
※ハードウェアアクセスの権限がなく、permission deniedされたら`sudo node remoTunes.js`してください
  
実行確認した動画を次に示します。
動作はこんな感じになります(↓)

[![実行確認の動画](http://img.youtube.com/vi/LQko3503RB0/0.jpg)](http://www.youtube.com/watch?v=LQko3503RB0)

※流れている音楽は[踊ってばかりの国](http://odottebakarinokuni.com/)の「！！！(チック・チック・チック)」

# 4. まとめ

JXAとAmazon Dash Buttonを使ってダイナミックにiTunesを操作してみました。
たった数行でダイナミックな操作ができるようになりました、便利な世の中になったものです。。。

なお、iTunesの操作は他にもトラック情報を取得したり等、様々なコトができますし、
さらに、JXAはiTunesだけでなくFinder等のMacのアプリケーションをコードで操作できるようになります(！)。
自宅や会社で無駄なコトがあったら自動化してみましょう。

**「Mac厨は嫌いだよ！世の会社を見てみろ！Windows一択だ！」**

という方はJScriptデビューすることをオススメします。
日本の生産性アゲていきましょう。
kintone かんたん検索 プラグインを作った話

## はじめに

### kintone プラグインについて
* プラグインを使うことで、カスタマイズなしでアプリの機能を拡張できる
* 有料で販売しているサイトも多いが、今回は自社用に作ったものを無料で公開する
    * リポジトリ：https://github.com/tonio0720/kintone-easy-search
    * リリース：https://github.com/tonio0720/kintone-easy-search/releases
* 参考：[kintone プラグイン開発手順](https://developer.cybozu.io/hc/ja/articles/203455680-kintone-%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E9%96%8B%E7%99%BA%E6%89%8B%E9%A0%86)

### 課題
* kintone標準の検索・フィルター機能がイケてない
* アプリ内で検索する場合、検索対象となる項目を指定したうえでキーワードを入力する必要がある
* 顧客マスタでは「会社名」、「氏名」、「メアド」などに対して、一括でキーワード検索ができると良い

### やったこと
* あんまり知られていないが、下記のようにURLにクエリを書くことで表示するレコードの条件を指定できる機能がある
    * https://{subdomain}.cybozu.com/k/{appid}/?query={query}
    * 参考：[URL内のクエリで、表示するレコードの条件を指定](https://developer.cybozu.io/hc/ja/articles/202388664-URL%E5%86%85%E3%81%AE%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%A7-%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9D%A1%E4%BB%B6%E3%82%92%E6%8C%87%E5%AE%9A)
* この機能を使い、複数の項目をOR条件で繋いだクエリでレコードを絞り込みたい
    * e.g. "会社名 like XXX or 氏名 like XXX or mailaddress like XXX"
* これをプラグイン化することで、アプリごとに検索対象とする項目を可変にしたい

## 導入方法
### プラグインをダウンロード
[Github](https://github.com/tonio0720/kintone-easy-search/releases)からプラグインをダウンロードする
![easy-search-11.png](https://qiita-image-store.s3.amazonaws.com/0/272803/eccc1ce6-bf1a-0732-7c39-fcde2491ca9d.png)


### プラグインをインストール
参考：[kintoneにプラグインをインストールする](https://jp.cybozu.help/k/ja/admin/system_customization/add_plugin/plugin.html)

### アプリに追加
かんたん検索を使いたいアプリの設定画面へ
![easy-search-3.png](https://qiita-image-store.s3.amazonaws.com/0/272803/803e0e88-078d-fa0a-4ad9-9c1fb23c0d92.png)

プラグイン→プラグインの追加→かんたん検索プラグインを選択→追加
![easy-search-4.png](https://qiita-image-store.s3.amazonaws.com/0/272803/d472b4cd-9d86-98d3-7ebf-11c1ee86c907.png)
![easy-search-5.png](https://qiita-image-store.s3.amazonaws.com/0/272803/11cfd4fb-4bde-3daa-cbdf-9154d15cd265.png)

### 検索項目を選択
ネジマークからプラグインの設定画面へ
![easy-search-6.png](https://qiita-image-store.s3.amazonaws.com/0/272803/a0dc459b-894e-2d73-4258-0a4f6b96606b.png)

検索対象としたいフィールドをチェックし、保存→アプリを更新
※検索項目が多いとクエリが長くなりエラーになる（10~15個まで）
![easy-search-12.png](https://qiita-image-store.s3.amazonaws.com/0/272803/815bb75e-6e9c-bd14-4088-ab6c2c91e7aa.png)

## 使ってみよう
### 一覧に検索ボックスが表示される
![easy-search-9.png](https://qiita-image-store.s3.amazonaws.com/0/272803/562fcb77-c1d8-d3ee-5adb-34da6f511c63.png)

### 「太郎」で検索すると・・・
![easy-search-7.png](https://qiita-image-store.s3.amazonaws.com/0/272803/a9925fd2-dffd-0fc0-6f2f-b5045263c618.png)

### ドロップダウン項目での検索が可能
![easy-search-10.png](https://qiita-image-store.s3.amazonaws.com/0/272803/71a2ff42-b0e2-4c99-808c-4d1a169d075c.png)
※関連レコードやサブテーブルでの検索も可能
フォースとともにあらんことを…ヨーダ記法について

有名なプログラミング記法のひとつに、**”ヨーダ記法”**と呼ばれる記法があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159675/53b0f310-015b-0abc-2c7e-846edc0cd24a.png)

<br/>
スターウォーズに出てくるあのヨーダです。
<br />
例えば、こんなif文があったとします。
変数 value の値が100かどうかを判定するif文です。

```java
if(value == 100) { 
  // valueが100のときにする処理
} 
```
ヨーダ記法では、これを以下のように書きます。ifのカッコ内に注目してください。

```java
if(100 == value) { 
  // valueが100のときにする処理
} 
```
<br />
ifのカッコ内が`if(value == 100)`から`if(100 == value)`に変わっています。
<br />
ヨーダ記法では、定数（100）と変数（`value`）を倒置させて記述します。
<br />
つまり、順番を入れ替えるわけです。

##処理結果はどちらも同じ。だが…
2つの例はどちらの書き方で実行しても結果は同じです。
<br />
一般的には`if(value == 100)`と書く人が大多数だと思います。
<br />
でも、その書き方だとこういう間違いをしてしまうことがあります。

```java
/*  "==" が "="になってる！ */
if (value = 100){
  // 処理
}
```

<br />
`value`と`100`を比較したいのに、これでは`value`に`100`という値を代入してしまっています。
<br />
しかし、このコードはコンパイルが通ってしまいます。何のエラーも吐いてくれません。
<br />
なぜなら、`value=100`は”変数valueに値100を代入する”という処理として成立してしまっているからです。
<br />
でも、ヨーダ記法で同じ間違いをしてしまったときはどうでしょう？

```java
/*  "==" が "="になってる！ */
if (100 = value){
  // 処理
}
```
<br />
この場合はコンパイラがしっかりエラーを吐きます。
<br />
だって、`100＝value`なんて処理は無理ですもんね。
<br />
つまり何が言いたいかというと…
<br />
<span style="color: #ff0000">ヨーダ記法のほうがミスを未然に防げる</span>ということです。


##しかし、技術は進歩している…

ヨーダ記法はコンパイラが見落としてしまうミスを防ぐことができます。
<br />
しかし、現代のコンパイラは`if (value = 100)`のようなifの中に代入処理が入った記述を見つけると警告を出してくれます。
<br />

```java
if(value = 100) { }...
// Using the result of an assignment as a condition without parentheses ←コンパイラによる警告
```

ヨーダ記法を使わずとも、コンパイラがエラーに気づいてくれるようになったのです。
<br/>
かわいそうなヨーダ記法…。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159675/f6007388-b2e5-433f-c31e-1672ac97001a.png)
<br/>
<br/>
今はもう使う必要のない記法ですが、定数と変数を倒置させるという先人たちの発想そのものは見習うべきだと感じました。
AWS SESをLambdaから使う

# 何をするか
- AWS SESの利用を開始する
- AWS Lambda(Python)からAWS SESを起動する
- 5分くらいでできる

## AWS SESの利用を開始する
SES ConsoleからEmail Addresses　を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217144/d8100a47-8622-c70f-104d-6496c3a9341a.png)

Varify a New Email Address を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217144/e0750de3-2a81-287f-eacb-2810e0054003.png)

送信したいアドレスを入力して完了すると、そのアドレスに検証用のURLが送られるので、URLに遷移して検証完了
アドレスを選択して「Send a Test Email」でテストメール送信できる

## AWS Lambda(Python)からAWS SESを起動する

以下のLambdaを作成
- ランタイム：Python3.6
- ハンドラ：qiita.lambda_handler
- 実行ロール：AmazonSESFullAccess


```python:qiita.py
import boto3

def ses_send_email(_from, _to, _subject, _body):
    _ses = boto3.client('ses', region_name='us-west-2')
    _response = _ses.send_email(
        Source=_from,
        Destination={'ToAddresses': _to},
        Message={
            'Subject':{
                'Data': _subject,
            },
            'Body': {
                'Text': {
                    'Data': _body,
                },
            }
        }
    )

    return _response

def lambda_handler(event, context):
    _from = 'from@example.com' # fromは予約語で使えない
    _to = ['to@example.com'] #配列
    _subject = 'Subject: 件名'
    _body = 'Body:　本文'
    _response = ses_send_email(_from, _to, _subject, _body)
    return _response

```

## 実際のサービスに使うために　※後ほど記事化
- SESをサンドボックスの外に出す
- mail送信処理のLambda共通関数化
- CloudFormation（AWS SAM）化
MacにComposerをインストールし、guzzlehttpを入れてみた

既存のPHPコードを保守するためにgitからローカルにコードを落としてきたが、
普段使っているローカルPCで一度もPHPを触ったことが無く、ライブラリが全く入っていなかった。

今回はMacにComposerをインストールして、ライブラリを一つ入れるところまでを記録に残しておく。
ちなみに普段PHPを触る機会はほぼ0なので、Composerも初めて触るPHP初心者。

# 環境
| OS | バージョン |
|:------------------|:--------|
| macOS High Serria | 10.13.5 |

# 手順
## Composerインストール

```shell-session:インストール
$ cd ~/
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
$ composer -V
```

## Composer設定

入力する内容は以下2項目。入力値は適宜変更する。
他はenterを押すのみ。

| 項目        | 入力値      |
|:------------|:------------|
| description | xxxxxx      |
| license     | proprietary |


```shell-session:設定
$ composer init

  Welcome to the Composer config generator

This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [xxxxxx/xxxxxx]:
Description []: xxxxxx
Author [xxxxxx <xxxxxx@xxxxxx.Xxxxxx>, n to skip]: 
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []: proprietary

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:

{
    "name": "xxxxxx/xxxxxx",
    "description": "xxxxxx",
    "license": "proprietary",
    "authors": [
        {
            "name": "xxxxxx",
            "email": "xxxxxx@xxxxxx.Xxxxxx"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]?
```

これで.composerディレクトリ、composer.jsonが生成される。
composer.jsonの中身は先ほど入力した内容が反映されている。

```json:composer.json
{
    "name": "xxxxxx/xxxxxx",
    "description": "xxxxxx",
    "license": "proprietary",
    "authors": [
        {
            "name": "xxxxxx",
            "email": "xxxxxx@xxxxxx.Xxxxxx"
        }
    ]
}
```

composer.jsonを.composerの下へmvし、今回はguzzlehttpを入れてみる。

```shell-session:ライブラリ追加
$ mv ./composer.json .composer
$ cd .composer
$ composer require guzzlehttp/guzzle
```

composer.jsonを見ると追加したライブラリが反映されている。

```json:composer.json
{
    "name": "xxxxxx/xxxxxx",
    "description": "xxxxxx",
    "license": "proprietary",
    "authors": [
        {
            "name": "xxxxxx",
            "email": "xxxxxx@xxxxxx.Xxxxxx"
        }
    ],
    "require": {
        "guzzlehttp/guzzle": "^6.3"
    }
}
```

この後composer.jsonをチェックして、「is valid」と出ればOK。

```shell-session
$ composer validate
./composer.json is valid
```

guzzlehttpが.composer/vendorの下に展開されている。

```shell-session
$ ls vendor/
autoload.php composer     guzzlehttp   psr
```

手順はここまで。

# 補足

PHPエディタって何が良いか周りに聞いてみたが人それぞれだった。
自分の場合はPCにeclipseが入っていたので、そのまま使ってみた。
eclipseにプロジェクトをインポートしたところ、
ライブラリパスが通っていないエラーが表示されたので今回の手順を行った。
実施後はエラーが消えたのでおそらく出来ているはず。
App Extensionのバージョンを自動で揃える (CFBundleVersion Mismatch)

# CFBundleVersionとCFBundleShortVersionString Mismatch の自動対応方法 

- App Extension(画像付きPush や WatchKit Extension)を使ってるアプリで、申請する際に出てくる、下記の警告の自動対応したいから書いた記事

## 警告内容

```
CFBundleVersion Mismatch
CFBundleShortVersionString Mismatch
```
- [ContainingAppとExtensionのバージョンはそろえる](https://qiita.com/nagasakulllo/items/44fefbe5d61fb11edd24)

## Sync Bundle Version

- [Xcodeのrun scriptで、iOSアプリのビルド番号を手軽に自動採番する](https://qiita.com/nerd0geek1/items/0289946b949d4dc3bda0) を参考にXcode Run Script を追加する
- 下記の部分を書き換える
 - 親アプリのInfo.plist `path/to/Info.plist`
 - ExtensionのInfo.plist `path/to/ExtensionInfo.plist`
- **Run Scriptは 揃えたい対象のExtensionに書く事！**
 - Project > Target > Extension > Build Phases

```sh:SyncBundleVersion
#!/bin/bash
build_number=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "path/to/Info.plist")
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $build_number" "path/to/ExtensionInfo.plist"

build_number=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "path/to/Info.plist")
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $build_number" "path/to/ExtensionInfo.plist"
```

### 実行内容
1. 親アプリのCFBundleVersionを取得(path/to/Info.plist)
2. ExtensionのCFBundleVersionを上書き(path/to/ExtensionInfo.plist)
3. 親アプリのCFBundleShortVersionStringを取得(path/to/Info.plist)
4. ExtensionのCFBundleShortVersionStringを上書き(path/to/ExtensionInfo.plist)

## 終わりに
- 単純にExtensionのInfo.plistのBundle versionに親アプリの環境変数を入れられたら解決なのだけども、標準だと見つからなかった
- 他の方法があれば教えてください
plotのtips

それぞれの列で正規化する処理

```python
for i in range(0, len(dfNewRc.columns)):
    dfNewRc.iloc[:, [i]]=dfNewRc.iloc[:, [i]].apply(lambda x: (x-x.mean())/x.std(), axis=0)
```
naの数字を埋める方法

```python
dfNewRc[['adjust','Sales','Sales_old']].fillna(method='bfill').plot()
```
図の大きさを調整する方法

```python
df.plot(figsize=(15, 6))
```
x軸の目盛りについては、以下のようにすると無理矢理体裁を改善できる

```python
plt.xticks(x4.index,['2015/09','2015/12','2016/03'], rotation=90)
```
[spring-boot]IntelliJのspring assistant pluginでapplication.ymlを補完する

IntelliJでspring-bootを利用したアプリケーションを開発している方、ConfigurationPropertiesにyamlを利用しているでしょうか？
yamlでPropertiesを書く時に補完が出ないかな〜と悩んでいて調べたところ、IntelliJのPluginで`SpringAssistant`というPluginが存在することを知りました。
この記事では導入の仕方と使い方をまとめたいと思います。
PluginのDocumentは[こちら(spring-assistant)](https://plugins.jetbrains.com/plugin/10229-spring-assistant)

# できること
公式ドキュメントをみる限り、classpath配下のjarの中に含まれている、`@ConfigurationProperties`が付いているクラスのプロパティ情報を収集してきてくれて、補完を出してくれるみたいです。
試しに、自分のプロジェクト(jar化していない)でやってみたのですが、残念ながら補完候補には上がりませんでした。


# 導入方法
導入方法と言っても２ステップですが...
## plugin
以下の方法でPluginを導入します。
※他のPluginと同じ導入方法です。
[Preference] -> [Plugins] -> [Browse repositories...] -> 検索バーで`spring assistant` を入力 -> [install]

## 再起動
IntelliJを再起動すれば、使えるようになります。

# 使い方
導入したらあとは、`application.yml`を開いてPropertiesを記入していくだけです。

![spring_assistant.gif](https://qiita-image-store.s3.amazonaws.com/0/253035/6471ceea-6f3f-1319-c1c6-970680429048.gif)

# 最後に
せっかくIntelliJを利用しているので、こういったかゆい部分のPluginはどんどん入れて活用していきたいですね！

# 参考資料
[Spring Assistant](https://plugins.jetbrains.com/plugin/10229-spring-assistant)
Docker上でMySQLにログインする

自分用メモです。

コンソールから直接MySQLの中身を見に行くときの手順。

まずは

```
docker ps
```

を、投げてコンテナIDを確認する。

```
CONTAINER ID        IMAGE               COMMAND          CREATED             STATUS              PORTS                  NAMES
833a83481bcd        mysql:5.7           "docker-entrypoint.s…"   3 hours ago         Up 2 hours          3306/tcp                 rails_db_1
```

以下のコマンドを投げる

```
docker exec -it コンテナID mysql -u root -p
```

パスワードを求められるので、database.ymlに記述したパスワードを入力すればOK。
PIN発行/認証もついている2要素認証

ずっと前に投稿しましたが、改めて見ると内容が薄かったので再度投稿し直します

世の中には沢山の2要素認証があります。”2要素”ですので、異なる要素を2つ用意してそれぞれ認証を行えば2要素認証のできあがりですが、モバイル向けではインフォビップ社の2要素認証がコスト的、テクニカル的に良かったので選定しました。

弊社で採用した2要素認証の概要
--------------------------
相手に届く携帯番号がどうかを調べ相手に届くと分かった場合、1要素目で認証ＯＫとします。

次に、インフォビップが発行するPIN番号を1要素目に入力した携帯番号宛てにSMSか音声架電で送ります。ユーザーは、受け取った/聞いたPIN番号をアプリ内のBoxにそのPIN番号を入力すると、インフォビップ社が正しいPIN番号かどうかを見極め、その結果を弊社へ送り返し、弊社が2要素目を認証したとユーザーへ連絡するプロセスとなります。

1要素目をスキップして、2要素目のみの認証も行えるようです。世界的な金融会社、ゲーム会社、無料チャットアプリでも使用されているにも関わらず強固なセキュリティーを維持する仕組みを持っているようです。高い技術力に裏打ちされた証拠だと思います。


1）全て自社製品だからサポート窓口もひとつの会社を選びました。
-------------------------------------
複数社みましたが、よくよく聞いてみると、提案したSI会社やベンダーが複数社の製品を仕入れてそれらを組み合わせていることがわかりました。2要素認証は常に稼働して何かあったときは即座に対応する用必要があるので、複数社に問い合わせをしていると時間がかかってしまいます。また、契約内容も各社ばらばらなので、ややこしいと思いました。結局1社で全て自社製品の会社にしました。

2）コストができるだけ安い会社を選びました。
-------------------------------------
各社よく見ると、SMSが1通10円から15円、音声が1分単位で課金など、いずれも費用対効果を出せるとは思いませんでした。結局初期月額がなく、SMSが半分以下の価格、音声が1秒単位であるものを選びました。

3）モバイル向けでユーザーが用意する物がない会社を選びました。
-------------------------------------
モバイル向けを探していて、ユーザーに手間がかからないようにしたかったので、GoogleのPINアプリのように機種変更したり、バックアップコードをなくすと使用できなくなる心配もないよう考えました。その結果、PINコード発行と認証も行ってくれるところを選びました。


4）気軽に答えてくれる会社を選びました。
-------------------------------------
2要素認証は、API開発が必須です。最初、API Key、Session Loginなどがわからないときに、気軽に日本語で聞けて数時間以内に答えてくれる会社を選びました。そのおかげで短期間で開発が終わり、じっくりと社内品質保証面にも時間を割けることができました。

5）海外でも実績があり先進性がある会社を選びました。
-------------------------------------
IT（ソフトウェアー）業界は、海外が断然進み、数年後に日本がまねる体質があります。アメリカの5年後のビジネスを行っている会社やアメリカで流行っていることをすぐ真似る会社もありますが、イノベーションもへったくれもないことがよく分かります。中途半端に事業撤退するのはこの為でしょう。（日本のIT（ソフトウェアー）業界で受託開発やSESから脱却することがないのはこのためだと個人的には思っています。反面日本の組み込み業界は部品ですが世界が頼るようなイノベーションがあると思います。Amazonは、EC業界ですが、AIやその他技術分野に多額の投資を行いイノベーションを追求しています）そのため、海外で実績があり世界の業界内でトップクラスの会社を選びました。
npm install/yarn addでブランチを指定する


# url#branch名でOK
gitのURLにハッシュ+ブランチ名で、指定したブランチでインストールできる。

## npm
```
npm install https://github.com/adamjmcgrath/react-native-simple-auth.git#more-providers
```

## yarn
```
yarn add https://github.com/adamjmcgrath/react-native-simple-auth.git#more-providers
```

## package.json
```
    ...
    "react-native-simple-auth": "https://github.com/adamjmcgrath/react-native-simple-auth.git#more-providers",
    ...
```
情報処理安全確保支援士を取得するための学習ログ　その1

# 初めに
この度、自分のスキルアップのために情報処理安全確保支援士の資格を取ることになりました。セキュリティに関する知識が乏しいため、勉強をしていくなかで普段の業務のセキュリティに関する知識を吸収することも目的としています。

# 本ブログの目的
このブログは、僕が情報処理安全確保支援士の勉強に使っている参考書[「うかる！情報処理安全確保支援士2018年版」](https://www.amazon.co.jp/情報処理教科書-情報処理安全確保支援士-2018年版-上原-孝之/dp/4798154180)の内容を自分で振り返るためのアウトプットの場にしようと思います。

# 1.1情報セキュリティの概念のまとめ
セキュリティとは、「守らなければならない大切なものが、危害や損傷を受けない正常な状態にあること」である。情報セキュリティとは、「企業や組織の重要な財産である情報のセキュリティを確保し、維持すること」である。
情報セキュリティ対策は、「物理的セキュリティ」と「論理的セキュリティ」の二つに大別される。

# 用語解説
「用語解説」で出てきた用語を自分で調べなおしてまとめます。

## サイバー攻撃
ネットワークを介して、個人や会社のパソコンやシステムに対して破壊や改ざん、窃盗などを行うこと。別名をサイバーテロという。
## バイオメトリック認証システム
個人の身体的特徴を用いた認証システムのこと。iPhoneの指紋認証など。
## 瞬停（しゅんてい）
瞬間的な停電のこと。1秒以内の停電のことをいう。
どのような問題があるかは未調査。
## UPS
Uninterruptible Power Supplyの略。無停電電源装置のこと。
急な停電が起きてもシステムの急停止を防ぐことができる。
## マルウェア
悪意のあるソフトウェアのこと。
ウイルスやランサムウェアなどの総称。

# 理解度チェックテスト
Q1.ISMSで特徴づけられている、情報セキュリティを維持する三つの事項を挙げよ。
Q2.情報セキュリティ対策は大きく分けると、何と何の二つに分類できるか。 
Q3.論理的セキュリティを三つに分けると、どのように分類できるか。
Oracle Master Bronze 12c SQL基礎まとめ

#前提条件
読者対象：Oracle Master Bronzeに興味を持っている人、受験しようとしている人
内容：Oracle Masterについて、Oracle Master Bronzeについて

##Oracle Masterとは
日本オラクルが運営する「オラクル認定資格制度」。
Oracle製品に関する技術力を客観的に評価する、公式の技術者認定資格の一つ。
データベースとミドルウェア／Java認定資格に含まれる。
##Oracle Master Bronzeとは
「Oracle Enterprise Managerなどを活用し、データベース管理者として必須となる管理者業務を行うための知識があることを証明する」資格。
Bronze→Sliver→Gold→Platinumとランクが分かれている。下位の資格を取得しないと上位の資格は受験ができない。
##Oracle Master Bronzeを取得するためには
- 12c SQL基礎
- Bronze DBA 12c

の2つの試験に合格することが必要。
12cとは、Oracleのバージョンのこと。バージョンごとに試験が用意されている。
2018年8月現在最新バージョンは12cである。
###SQL基礎の試験について
試験時間 120分
出題数　75問
出題形式　多肢選択式
合格ライン　65%
試験料　13,600円

####試験内容

- 概要
- SQLのSELECT文の使用によるデータの取得
- 単一行関数の使用による出力のカスタマイズ
- 変換関数と条件式の使用
- グループ関数の使用による集計データのレポート
- 結合の使用による複数の表のデータの出力
- 結合の使用による複数の表のデータの出力
- 副問合せの使用による問合せの解決
- 集合演算子の使用
- DML文の使用による表の管理
- データ定義言語の概要

##参考文献
「オラクルマスタースタディガイド ORACLE MASTER Bronze Oracle Database 12c[12c SQL基礎]（試験番号：1Z0-061）完全詳解＋精選問題集」SBクリエイティブ株式会社