OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS7の構築

~~毎回調べるのがめんどくさいので~~自分用に備忘としてまとめます。

## 謝辞
たくさんのサイトを参考にさせていただきました。
どの部分を参考にしたかわからなくなることを避けるため、項目ごとに参考にしたサイトを記載しています。
ありがとうございます☻

## 前提

* OS:CentOS7 1804 minimal
* ネットワーク設定が完了していること

また、今回の手順はLAN内部のサーバ構築手順なので、外部公開するサーバの場合は、より強固なセキュリティ設定（SELinux導入、firewalldでのフィルタリング）を検討してください。

## SELinux無効化
```  
# vi /etc/selinux/config
SELINUX=enforcing
↓
SELINUX=disabled
```  
変更後、再起動します。

## SSH
### セキュリティ設定
```  
# vi /etc/ssh/sshd_config
【rootログイン禁止】
＃PermitRootLogin yes
↓
PermitRootLogin no

【パスワード認証禁止】
#PasswordAuthentication yes
↓
PasswordAuthentication no
ChallengeResponseAuthentication no # デフォルトだが念のため

【空のパスワードでのログイン禁止】
#PermitEmptyPasswords no
↓
PermitEmptyPasswords no

【サービス再起動】
※万が一ログインできなくなった場合に備え、既存のセッションはそのままにしておく
# systemctl restart sshd
```  
参考：[そこそこセキュアなlinuxサーバーを作る](https://qiita.com/cocuh/items/e7c305ccffb6841d109c)

## ログインユーザ設定
### wheelグループへの追加
sudoを有効にするため、 wheel グループに任意のユーザを追加します。

```  
# usermod -G wheel user
```  
セッション切断・再接続後、 sudo が使えます。

## 時刻（NTP）設定
```  
$ sudo vi /etc/chrony.conf
【変更前】
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
【変更後】
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst

server 172.53.12.6
server 172.53.12.5
$ sudo systemctl restart chronyd
$ sudo chronyc -a makestep # 強制的に時刻同期する
```  
参考：[CentOS7のNTP設定](https://qiita.com/yuki476/items/4b08e79022605198d9b9)

## yum
### （プロキシ設定）
社内でプロキシ設定が必要な場合は、以下を実施します。

```  
$ sudo vi /etc/yum.conf
↓追加
proxy=http://proxy:8080/
```  

### リポジトリ追加
エンタープライズで信頼性の高い EPEL リポジトリを追加します。

```  
$ sudo yum -y install epel-release
```  

### ユーティリティ追加
minimalに含まれていない各種コマンド・ユーティリティを追加します。

```  
$ sudo yum -y install \
lsof \
vim \
bash-completion \
bind-utils \
net-tools \
psmisc \
traceroute \
tree \
wget
```  
参考：[CentOS 7 の初期設定でやっておくべきこと](https://qiita.com/bezeklik/items/0622fbaf7d33dd95d005#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB-pc-%E3%81%A7%E3%81%AE%E6%93%8D%E4%BD%9C)

## bashrc
crontabの恐怖のオプション **-r** を安全にします。
様々な方法がありますが、aliasでお手軽に設定しておきます。

```  
$ sudo vim /etc/bashrc
↓ 最後尾に追加
alias crontab='crontab -i'
```  
参考：["crontab" -r でいきなり削除しないようにする @LCD -Linux Command Dictionary- 【山澤】](http://www.rep1.co.jp/staff/200vcxg/217rav/crontab_-r_lcd_-linux_command.htm)

## 最後の仕上げ
```  
$ sudo yum -y update
```  

## おわりに
必要に応じて修正する可能性があります。
至らない点があればご指摘 & 編集リクエストお願いしますm(_ _)m
【Python】atomのUnicodeEncodeError, UnicodeDecodeErrorを防ぐ

# 目次
- [問題](#問題)
    - [1. UnicodeEncodeError](#1-unicodeencodeerror)
    - [2. UnicodeDecodeError](#2-unicodedecodeerror)
- [解決法](#解決法)
- [ちなみに](#ちなみに)
- [参考](#参考)

# 問題
atomの「script」パッケージなどを使ってpythonを実行すると，`UnicodeError`が発生する。

## 1. UnicodeEncodeError
「unicode型」→「str型」変換の際に発生するエラー

```py
print('こんにちは')
```
```
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
```

## 2. UnicodeDecodeError
「str型」→「unicode型」変換の際に発生するエラー

```hello.txt
こんにちは
```
```py
with open('hello.txt') as f:
    f.read()
```
```
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)
```


# 解決法
atomのロケール設定を`ja_JP.UTF-8`に統一してあげましょう。
init.coffee（メニューバー「Atom」>「Init Script.../起動スクリプト...」）に以下を追記して再起動

```init.coffee
process.env.LANG = "ja_JP.UTF-8";
```


# ちなみに
「script」パッケージのロケール設定のみ`ja_JP.UTF-8`にする場合は，
メニューバー「パッケージ」>「Script」>「Configure Script」で以下のように設定して実行すればOKです。
![スクリーンショット 2019-03-14 23.04.41.png](https://qiita-image-store.s3.amazonaws.com/0/231104/fa2e081c-0477-827d-cdcb-3d898913ccab.png)


また，起動スクリプトに以下のように書き込む対処法がよく見られますが，この方法だと問題2が解決できませんでした。

```init.coffee
process.env.PYTHONIOENCODING = "utf-8";
```


# 参考
http://hikm.hatenablog.com/entry/20130328/1364492471
C++ Builder 10.2 Tokyo > E2015 'std::pow(long double, int)'と'std::pow(double, int)'の区別が曖昧 > 対処

```txt:動作環境
Rad Studio 10.2 Tokyo
```

XE4で実装していたプロジェクトを10.2 Tokyoでビルドしようとしたら、以下のエラーとなった。

> E2015 'std::pow(long double, int)'と'std::pow(double, int)'の区別が曖昧

関連コードでは以下の計算を使っている。
ここで、pwrは変数名。

```cpp
pow(10, pwr)
```

### 対処

以下のようにコードを変更した (小数点の追加)。

```cpp
pow(10., pwr)
```

これによりdouble型として認識されるようになり、「曖昧」でなくなった。
【提案】シンプル&強力なUIViewControllerのテンプレートを作って見た

iOSのネイティブアプリのアーキテクチャーほど議論が尽きないものはない！

と思います。

普通にiOSのネイティブ開発を始めると、基本的には、ViewControllerが肥大化していきます。
それを防ぐために、MVVCとクリーンアーキテクチャーとか色々なデザインパターンが生まれては、消え、試しては消え、みたいな感じになっているのが現状ではないでしょうか？

ぶっちゃけ・・・

initData()
initViews()
updateData()
updateViews()

この４つを定義して、使い回すだけで結構いい感じになるのではないでしょうか？

もしよければどうぞ！わかる人だけわかってくださいw

```
import UIKit

class TemplateViewController: UIViewController {
    // 一回だけ呼ばれる
    override func viewDidLoad() {
        super.viewDidLoad()
        initData()
        initViews()
    }
    
    // 毎回呼ばれる
    override func viewWillAppear(_ animated: Bool) {
        // 画面が呼ばれるたびにデータが変わる可能性がある場合は、initData()とinitViews()をこちらにおく
    }
    
    // レイアウト処理終了
    override func viewDidAppear(_ animated: Bool) {
        // 画面が表示された後で実行する処理はこちら
    }
    
    func initData(){
        // データの初回読み込み
    }
    
    func initViews(){
        // Viewの初回設定
    }
    
    func updateData(){
        // データの再読み込み
    }
    
    func updateViews(){
        // Viewの再読み込み
    }
}
```
シンジ「綾波はなぜAngularを使うの？」レイ「絆だから」

衝動的に書いてしまいました。反省してます。
この記事はAngularのことを紹介しそうで**全く紹介しない記事**です。

(※なぜか『新世紀エヴァンゲリオン』の一部ネタバレが含まれるので注意してください)

# 決戦、第3新東京市 マイナンバー対応

ミサト「シンジ君」
シンジ「はい」
ミサト「初号機で**品質管理**を担当」
シンジ「はい」
ミサト「レイは零号機で**フレームワーク**を担当して」
レイ　「はい」

リツコ「ソフトウェア開発プロジェクトは地球の自転、磁場、重力の影響を受け、直進しません」
リツコ「その誤差を修正するのを、忘れないでね」
リツコ「正確に、フェーズを完全な状態で終わらせるのよ」
シンジ「そんなこと、まだ練習してないですよ」
リツコ「今は余計なことを考えないで。一撃で撃破することだけを考えなさい」

レイ　「私は…私は初号機を護ればいいのね」
リツコ「そうよ」
レイ　「分かりました」

シンジ「これってデスマーチかもしれないね」
レイ　「どうしてそういうことを言うの？」
レイ　「あなたはプロジェクトを成功させるわ」
レイ　「わたしが守るもの」

シンジ「綾波はなぜ[Angular](https://angular.jp/)を使うの？」
レイ　「絆だから」
シンジ「父さんとの？」
レイ　「[日本ユーザー会](https://community.angular.jp/)のみんなとの」
シンジ「強いんだな、綾波は」
レイ　「私にはほかに何も無いもの」

レイ　「じゃ、寝袋買っておいてね」

ミサト「シンジ君、日本中のJavaScript、あなたに預けるわ」
シンジ「はい！」
ミサト「最終安全装置、解除！」
マコト「撃鉄起こせ！」
マコト「8、7、6、5、DOMの状態管理に高エネルギー反応！」
リツコ「何ですって！？」

ミサト「ミスった！」
ミサト「第二射、急いで！」
マヤ　「グローバルスコープに再び高エネルギー反応！」
ミサト「まずい！」

～レイ、Angularでシンジを庇う～

シンジ「綾波！」
リツコ「Angularがもたない！」

～無事にプロジェクト終了～

シンジ「綾波！大丈夫か！綾波！」
シンジ「別れ際に寝袋買えなんて、悲しいこと言うなよ」
レイ　「何泣いてるの？」
レイ　「ごめんなさい、Angularで組むとき、どんな顔をすればいいのか分からないの」
シンジ「笑えばいいと思うよ…」

おしまい

前作はコチラ：[そんな…どうして…？さやかちゃん、async/awaitでPromiseから人を守りたいって、そう思って魔法少女になったんだよ。](https://qiita.com/almiraj/items/2da97f6cc36143f29f8a)
Android 4系をサポート終了することにした話とその周辺調査

# 概要
現在担当させてもらっているAndroidアプリのSDKを21まで引き上げる、つまり、
Android 4.4 KitKat以前を閉じることになりました。
ちょっとポエム寄りになりますが、その辺りの確認方法などをまとめます。

# 背景

### WebView問題
詳しくは[こちら](https://web.bridge-net.jp/blog/2187/)などにまとめられていますが、
Androidは5系と4系以前ではWebViewのベースが異なります。

- 4.3以前
    - WebKitベースのWebView（WebKit WebView）
    - Googleサポート打ち切り済
    - css3/JavaScriptほぼ非対応
- 4.4
    - ChromiumベースのWebView（Chromium WebView）
    - アップデートがOS依存 = バージョン固定
    - css3/JavaScript一部非対応
- 5系以降
    - ChromiumベースのWebView（Chromium WebView）
    - アップデートが端末から切り離されている
    - 最新Chromeとほぼ同様の機能が使える

現在担当しているアプリでもWebViewを使う箇所が多くあり、
jQueryの一部機能がうまく動かず、サーバー側でワークアラウンドで入れるといったことがありました。
このような状態では新機能の開発の度に4系のチェックも必要になり、開発陣への負担が大きくなってしまいます。

### Android 4系使用ユーザ率

アプリ使用ユーザのOS毎の割合を確認しましょう。
`Google Analytics -> レポート -> ユーザ -> デバイスとネットワーク -> デバイス`
もしくは
`Google Play Console -> 統計情報`
から確認できます。

よく言われる目安は、4系以下の合計割合が5%未満、というところです。
弊社アプリも5%以下になっていました。
この割合に対してテストなどのリソースを割く必要があるか、という点も考えるポイントの一つです。

### 世間的な流れ

[Twitterアカウント 「minSdkVersion」のツイート](https://twitter.com/minSdkVersion)
[Androidアプリ の minSdkVersion を21にした話 (クックパッド開発者ブログ)](https://techlife.cookpad.com/entry/2018-05-15-android-minsdkversion-21)
[【重要】Android OSのバージョン 5.0未満をご利用のお客さまへ (メルカリ)](https://jp-news.mercari.com/2018/04/27/android/)
[Android 4系のサポートを終了した話 (Sansan Builders Box)](https://buildersbox.corp-sansan.com/entry/2018/12/14/113000)

この他、ヤフオク、Chatwork、ラクマなど、多くのアプリが4.4以下をサポート終了しています。
やはりセキュリティ面の強化という部分が大きいみたいです。

# 移行まで

### 1. メンバーの説得
ディレクターさん中心に、開発効率、セキュリティ強化を目的に、閉じるという話をしました。
4系以下のユーザ割合もそこまで多くなかったので、すんなり移行することになりました。

### 2. ユーザへの告知
公式サイトに4系以下を閉じる旨を記載します。
サーバー側で通信を遮断するといったことはまだ予定していないですが、今後新機能を使うことができなくなる、ということで、困惑するユーザさんもいると思います。
そのため、弊社では昨年末ぐらいに告知し、今月のリリースタイミングで閉じることになりました。
(ちょっと告知期間が長いですが、もう少し準備周到であれば1ヶ月程度でも良さそうです)

### 3. リリース対応
エンジニア側はSDKバージョンを21に引き上げるだけです。
また、Build.VERSIONを見て、4系で処理を分けているところがあれば、削っておきましょう。

```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  //5系以上の処理
} else {
  //4系以下の処理
}
```


# おわりに
Androidは年々サポート対象OSが増えて開発者に厳しい現状ですが、
今後も年末〜年度末には見直しをかけながら、少しずつ切っていきましょう。
Windows10環境でPHPを読み込ませてみる

PHPは通常サーバーで初めて動作するサーバーサイドの言語。ローカルなPCでは動作しない・・・
これを仮想環境やXAMPP等を使わずPHPをWindows10上で動作させる備忘録です。

# えっ、XAMPP入れなくていいの？

PHPにはビルトインウェブサーバーというWEBサーバーをローカルPC上で立てる機能があるのでこれを使います。

ちょっとPHPで作ったプログラムを検証したいけどXAMPPを入れてサーバーを立てて・・・などの手間が省けるかも。

## PHP for Windows を入れる

公式サイトからWindows用バイナリを入れる
https://windows.php.net/download

タイプはThread Safeでいいと思う。

指示に従ってインストールを進めてください。

終わったらコマンドプロンプトを起動し、

```
php -v
```
と打ってみて、バージョン情報が出てくればインストール成功です。

## ビルトインサーバーを立ち上げる

まずコマンドプロンプトで検証用PHPファイルのあるディレクトリまで移動します

```
cd example
```

次に以下のコマンドを打ちます

```
php -S localhost:8000
``` 
サーバーが立ち上がると以下のメッセージが出るはずです

```
PHP 7.2.0 Development Server started
Listening on http://localhost:8000          
Document root is C:\Users\ringo\example
Press Ctrl-C to quit.
```

`Listening on~`と出てるとこがURLなのでこれをコピペしてブラウザに貼り付けましょう


ん？


> Not Found
> The requested resource / was not found on this server.

ファイルが見つかりませんよと出てきました。
これはインデックス(index.html)にあたるファイルがディレクトリ内に無いのでこんなメッセージが出てきます

気にせずこのアドレスの後に検証したいhtmlやphpのファイル名を打ってファイルを開きましょう

```
http://localhost:8000/counter.php
```

**PHPファイルの内容が期待通り表示されましたか？**

もし画面が真っ白で表示されなかったりしたらさっきの`コマンドプロンプト画面`を確認。ログがずらっと出てるのでエラーが出てる箇所を確認しながら修正しましょう

検証が終わってサーバーを停止する場合は`Ctrl+C`キーを押すと戻ります

>P.S
>ローカル上でWordpressを使いたい方、データベースサーバーを別途動かさないといけないのでSQliteを使うか素直にXAMPPを使いましょう
[iOS][Swift] WKWebViewにcookieをセットする


# WKWebViewにcookieをセットする方法

cookieにセットするキーと値をDictionaryに入れておく

```swift
var cookies = Dictionary<String, String>()
```

[参考](https://stackoverflow.com/a/50612861)

```swift
            var request = URLRequest(url: URL(string: "https://example.com/")!)

            // Cookieを追加する
            var hTTPCookies = [HTTPCookie]()
            for (key, value) in cookies {
                hTTPCookies.append(MyClass.makeCookie(key: key, value: value))
            }

            let headers = HTTPCookie.requestHeaderFields(with: hTTPCookies)
            for (name, value) in headers {
                request.addValue(value, forHTTPHeaderField: name)
            }
            webView.load(request)
```

DictionaryからCookieを作成するクラスメソッド

```swift:MyClass
    class func makeCookie(key:String, value:String) -> HTTPCookie{
        let cookies = HTTPCookie(properties: [
            .domain: "example.com",
            .path: "/",
            .name: key,
            .value: value,
            .secure: "FALSE",
            .expires: NSDate(timeIntervalSinceNow: 31556926)
            ])!
        return cookies
    }
```
【PostgreSQL】一行前の値や次の行の値を参照するには？

昔、メモとして残しておいたのを、こっちでも書き直し。
http://tomofumi.blog.jp/archives/7986782.html

結論から書くと LAG() OVER() を使用する事で解決可能。

## サンプル
こんな感じのテーブルがあったとする。

| id | status |
|---|---|
|1|1|
|2|1|
|3|1|
|4|1|
|5|1|
|6|1|
|7|0|


~~~
-- 上記テーブルをWITHで仮想テーブルで作成
WITH A( id, status ) AS (
    SELECT 1, 1 UNION ALL 
    SELECT 2, 1 UNION ALL
    SELECT 3, 1 UNION ALL
    SELECT 4, 1 UNION ALL
    SELECT 5, 1 UNION ALL
    SELECT 6, 1 UNION ALL
    SELECT 7, 0
)
SELECT * FROM a;

~~~
![6dc4850c6715c52cf968dfea0cf331b9.png](https://qiita-image-store.s3.amazonaws.com/0/39934/ff2128f2-71b2-083d-f6a9-26f3f0a634dd.png)

LAG OVERを実行してみる。

~~~
WITH A( id, status ) AS (
    SELECT 1, 1 UNION ALL 
    SELECT 2, 1 UNION ALL
    SELECT 3, 1 UNION ALL
    SELECT 4, 1 UNION ALL
    SELECT 5, 1 UNION ALL
    SELECT 6, 1 UNION ALL
    SELECT 7, 0
)
SELECT
    *,
    lag( status ) OVER( ORDER BY id )
FROM a;
~~~
実行結果は以下のようになる
![1e3f5dbe6a32a3bc1680249e6dc58fc3.png](https://qiita-image-store.s3.amazonaws.com/0/39934/66d047ad-8218-a87a-013f-ae9dbdf61b08.png)

1行目のLAGの結果は前の行がないので、nullとなっている。
2行目以降、OVERの条件で並び変えた結果の1行前のデータを表している。

## LAGとOVERの説明
~~~
LAG( arg0, [arg1, arg2] )
arg0 ... 前の行を確認したいカラム名を記述
arg1 ... 省略可能、何行前の値を参照したいか（デフォルト:1）次の行の値を取りたいなら、ここは-1になる
arg2 .... 前の値がない（1行目の時）どんな値を表示したいか(デフォルト:null)カラム名指定も可能。カラムを指定した場合、現在の行数のカラムの値を表示する
~~~
ちなみに2行前の値を取りたい場合、arg1に2を設定する事で可能。
同様に2行先の値を取りたい場合は、arg1に-2を設定する事で可能となる。

~~~
OVER([省略可能：ORDER BY カラム1[, カラム2, ... カラムn ]])
OVER([省略可能：PARTITION BY カラム1[, カラム2, ... カラムn ]])
~~~

ORDER BYを使用した場合、ソート対象項目を指定する。
PARTITION BYを使用した場合、グループ化対象項目を指定する事が出来る。
※ どちらもメインのSQLで適用した表示順を適用する前の結果を元に前の行（あるいは先の行）を参照してくれる。



OVERには、複数条件を記述することが可能
例えばこんなテーブルがあったとして

~~~
WITH A( id, group_id, status ) AS (
    SELECT 1, 1, 1 UNION ALL 
    SELECT 2, 2, 2 UNION ALL
    SELECT 3, 2, 3 UNION ALL
    SELECT 4, 1, 4 UNION ALL
    SELECT 5, 1, 5 UNION ALL
    SELECT 6, 3, 6 UNION ALL
    SELECT 7, 1, 7
)
SELECT
    *
FROM a;
~~~
上記仮想テーブルの構造はこんな感じね
![0a14a9c925182074719ef6e6e35eeb9a.png](https://qiita-image-store.s3.amazonaws.com/0/39934/adaed992-6dcb-cc4d-3b43-bdf2e121778e.png)

これにPARTITION BY でグループ化を行い、ORDER BYで並び替えするとこんな感じ。


~~~
WITH A( id, group_id, status ) AS (
    SELECT 1, 1, 1 UNION ALL 
    SELECT 2, 2, 2 UNION ALL
    SELECT 3, 2, 3 UNION ALL
    SELECT 4, 1, 4 UNION ALL
    SELECT 5, 1, 5 UNION ALL
    SELECT 6, 3, 6 UNION ALL
    SELECT 7, 1, 7
)
SELECT
    *,
    lag( status ) OVER( PARTITION BY group_id ORDER BY id )
FROM a;
~~~
![5c478e986fa6a15c4c2d6e8b4370eeb4.png](https://qiita-image-store.s3.amazonaws.com/0/39934/8a292363-74f2-d455-fb53-2e54dc4b0a55.png)
RHEL7 で ホームディレクトリ直下のディレクトリ名を英語化する方法

RHEL に リモートデスクトップで接続した際に日本語のディレクトリができてしまった場合は、以下のコマンドで英語に変換できます。

```
​LANG=C xdg-user-dirs-gtk-update​​
```
RHEL7 に Windows の ディスクをマウントする方法

### Sambaのインストール

```
yum install samba-client samba-winbind cifs-utils -y
```

### Linux 上で 参照したい Windows の フォルダーを共有

フォルダー右クリック(例：**SharedDir**) ➡ プロパティ ➡ 共有

### マウントコマンド実行

```
mount -t cifs -o uid=LinuxUser,gid=LinuxGroup,user=WinUser //xxxxx.co.jp/SharedDir /mnt/LinuxMountDir
````
超初心者向け・SQLでの親テーブル・子テーブルの考え方

##前提
Qiita初投稿です！
ここでは
「親テーブルと子テーブル、どっちがどっちか分からん…」
「SQL文書いてて訳分かんなくなった！」
という人向けに、その考え方を超簡単に説明します。
今回はmacOSのterminalを使っています。

DB初心者のため、何か間違いがあればご連絡ください…。

##親テーブル・子テーブルとは？
複数のテーブルでデータベースを管理する時、
各テーブルを紐づける**「外部キー」**を使うことが出来ます。
この時
「親テーブル・子テーブル」にあたるテーブルがどれかによって
「どのテーブルの、どのカラムが外部キーになるのか？」が分かります。

外部キーの役割については調べると沢山出てくるので、ここでは割愛します。
要は外部キーを使って便利な制約を設定できる、という感じです。

一応文字で説明すると、

**外部キーを設定して参照する側は子テーブル、参照される側は親テーブル**

ということですが、
分かりづらいと思うので（私自身分からなかったので）具体例で見ていきましょう。

##具体例
例えば、社員を管理するデータベースにおいて
下の名簿テーブルに「社員ID、氏名、部署ID」の項目があるとします。
この時
「部署IDを、部署テーブルの『部署ID』に関連付けしたいな」
という場合に外部キーを利用します。

**名簿テーブル**

|社員ID|   氏名    |  部署ID  |
|:----:|:--------:|:--------:|
| 001  |  佐藤 実   |   B03    |
| 002  |   田中 隆  |    A02   |
| 003  |  島田 花子 |    A02   |
| 004  |  山田 太郎 |    A01   |

**部署テーブル**

|部署ID|    部署名  |
|:-----:|:--------:|
| A01  |   開発部   |
| A02  |   営業部   |
| B03  |    総務部  |


この時、

*田中さんと島田さんの部署が知りたい！
→名簿テーブルの部署IDだけでは何の部署か分からない…。
→名簿テーブルから外部キー「部署ID」を使って部署テーブルの部署ID[**A02**]を参照
→営業部だと分かった！田中さんと島田さんは営業部だ！*

という流れが起きます。

上で書いた「参照する・される」でいうと、

- 「名簿テーブル」が「部署テーブル」を参照している
- 「部署テーブル」は「名簿テーブル」に参照されている
- 参照する時、「部署ID」を使っている

ということですね。

以上の点から、

**親テーブル：部署テーブル
子テーブル：名簿テーブル
外部キー：部署ID**

となります。

※おさらい：
**外部キーを設定して参照する側は子テーブル、参照される側は親テーブル**

##コードで確認
実際にコードで確認してみましょう。

**部署テーブル作成**

```terminal:親テーブル「department」
create table department(
 departmentID int,
 departmentName varchar(255),
 primary key(departmentID)
)engine=InnoDB;
```

**名簿テーブル作成**

```terminal:子テーブル「user」
create table user(
 userID int,
 name varchar(255),
 departmentID int,
 primary key(userID),
 foreign key(departmentID)references department(departmentID)
)engine=InnoDB;
```

この時、子テーブルである名簿テーブルの作成時に「`foreign key(外部キー)...`」を使って外部キーを設定することができます。

親テーブルで外部キー設定しようとするとエラーが出てうまく出来なかったりするので、
つまずいたら
「親テーブルと子テーブルは合っているか？」
を一度ゆっくり考えてみることをお勧めします。

外部キーについての分かりやすい記事は[こちら](https://www.sejuku.net/blog/54072)がオススメです。
CakePHP3のi18nFormat関数で大文字Yを使ってハマった

# 何が起こったか？
CakePHP3にて、「(FrozenTime型)日付」から「年」を取得する処理に怪しい動作を発見しました。

```php:date.php
use Cake\I18n\FrozenTime;
:
$time = new FrozenTime('2019-03-12');
echo $time->i18nFormat('YYYY-MM-dd')."\n";  # => 2019-03-12 が表示される

$time = new FrozenTime('2019-12-31');
echo $time->i18nFormat('YYYY-MM-dd')."\n";  # => 2020-12-31 が表示される!?
```

実際のコードでは年度を ` $time->i18nFormat('YYYY')` で取得しようとしていて、年末12/29～12/31あたりにおいて想定通りの年が取得できていませんでした。

# CakePHP公式マニュアルでは？
- [日付と時刻](https://book.cakephp.org/3.0/ja/core-libraries/time.html)

日付を取得するには `$time->i18nFormat('yyyy-MM-dd')` というふうに y を小文字にするのが正しそうです。
大文字 Y を使ったサンプルはみつかりません。

とはいえ `$time->i18nFormat('YYYY-MM-dd')` でもそれっぽい値が取得できていますね。何が違うのでしょうか？

# 'y' と 'Y' の違い

- [i18nFormat with CakePHP 3 - Why does YYYY produce a different year than yyyy?](https://stackoverflow.com/questions/27695883/i18nformat-with-cakephp-3-why-does-yyyy-produce-a-different-year-than-yyyy)

>"Uppercase Y is the year that the week of the timestamp in, in "Week of Year" based calendars. "
→ （大文字のYは、「Week of Year」ベースのカレンダーで、タイムスタンプの週が入った年です。）

2019年12月29日は、カレンダーで表示させると2020年の第1週でもあるため、大文字Yが2020を返したようです。

# まとめ
CakePHP3のi18nFormat関数を使って日付を取得したいときは、`$time->i18nFormat('YYYY-MM-dd')` ではなく `$time->i18nFormat('yyyy-MM-dd')` を使いましょう！

# 確認環境
CakePHP 3.4.7
PHP 7.0.32
WindowsServer2016のサービスでOfficeオートメーションを使う

# サービスでオートメーションは基本使えない
使えないんだってさ。で、色々と調べてたら**CreateProcessAsCurrentUser**というキーワードに辿り着くんだけど、実はこれもダメなんです。普通には動くんだけど、実はログオフ状態だと動かなくなるです。

# ExcelもWordlもPowerPointも軒並みエラー
```
ファイル 'hoge.xlsx' にアクセスできません。次のいずれかの理由が考えられます。

• ファイル名またはパスが存在しません。
• ファイルが他のプログラムによって使用されています。
• 保存しようとしているブックと同じ名前のブックが現在開かれています。
```

```
hoge.ppt
プログラムの実行を続行するための十分なメモリがありませんでした。
```

```
hoge.docx
オブジェクト参照がオブジェクト インスタンスに設定されていません。
```

まあそもそもやっちゃだめなんでしょうね。
これをなんとかしましょう。

# まずDesktopフォルダが必要
```
C:\Windows\System32\config\systemprofile\Desktop
C:\Windows\SysWOW64\config\systemprofile\Desktop
```

こいつらがなければ作ります。

# 管理者権限のあるアカウントをサービスで指定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117698/a56c1693-efb2-f211-8fd6-d45f5d1f1aba.png)

# コンポーネントサービスでも設定
>「コンソール ルート」‐「コンポーネント サービス」‐「コンピュータ」‐「マイコンピュータ」‐「DCOM の構成」

ここから目的の項目を見つけ出して右クリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/117698/820c1dc9-8b5c-9cb3-06ce-664c68c515b5.png)

「ID」タブの「このユーザー」を選択して管理者権限のあるアカウントを設定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117698/cc5a0d80-0e3b-e7f3-915f-7b90dbcb4848.png)

以上。
これでログオフされてても動かせます。

セキュリティがどーのこーのとか、Officeのライセンス違反にならないようにとか、そういう話はちゃんとやって下さいね、と。
javascriptで前日比のパーセントを表示

今日の値と昨日の値の前日比の出し方。

```.js:javascript

// 今回は例として、352と350の比較します
var today = 352;
var yesterday = 350;
var result01 = (today - yesterday) / yesterday * 100;
console.log(result01); // 結果 0.5714285714285714

var n = 2 ;	// 小数点第n位まで残す
var result02 = Math.floor( result01 * Math.pow( 10, n ) ) / Math.pow( 10, n );
console.log(result02); // 結果 0.57
```
【PL/SQL】MERGE=INSERT+UPDATE

#MERGE=INSERT+UPDATE
レコードの新規作成と更新を1文で記述することができます。
##やりたいこと
**WKテーブル**

|       EMP_CD(主キー) |    EMP_NAME    | 
|:-----------------:|:------------------:|
|              E111111 |        aaa        |
|              E222222 |        bbb        |

**TGTテーブル**

|       EMP_CD(主キー) |    EMP_NAME    | 
|:-----------------:|:------------------:|
|              E111111 |        ddd        |

⇒レコードのがすでに存在すれば更新、存在しなければ新規作成を行います。
　実行結果は以下のようになります。

**MERGE後TGTテーブル**

|       EMP_CD(主キー) |    EMP_NAME    | 
|:-----------------:|:------------------:|
|              E111111 |        aaa        |
|              E222222 |        bbb        |


##コード
**注意点**
・INSERT、UPDATEにはテーブル名は記述しない
・UPDATEでは比較対象となるカラムは記載しない

```sql:test.sql
MERGE INTO tgt tgt
    USING wk wk
    ON tgt.emp_cd = wk.emp_cd
WHEN MATCHED THEN
    UPDATE SET
        tgt.emp_name = wk.emp_name
WHEN NOT MATCHED THEN
    INSERT (tgt.emp_cd, tgt.emp_name)
    VALUES (wk.emp_no, wk.emp_name)
;
```

##UPDATEかINSERTのみ
MERGE文ではUPDATEまたはINSERTのみの実行も可能です。
以下の例を実行すると新規作成のみ行われます。

```sql:test.sql
MERGE INTO tgt tgt
    USING wk wk
    ON tgt.emp_cd = wk.emp_cd
WHEN NOT MATCHED THEN
    INSERT (tgt.emp_cd, tgt.emp_name)
    VALUES (wk.emp_no, wk.emp_name)
;
```

**MERGE後TGTテーブル**

|       EMP_CD(主キー) |    EMP_NAME    | 
|:-----------------:|:------------------:|
|              E111111 |        ddd        |
|              E222222 |        bbb        |
数値計算勉強関連で参考にした・する予定・閲覧したサイトを記録しておく

##投稿者/執筆者に感謝
随時更新追加予定のため内容は不定、記述に間違いがあると確認された場合は削除するかもしれません

https://qiita.com/Ren112358/items/f2c0bbc90810c040a2e5
二分法に関する実装

https://www.sist.ac.jp/~suganuma/kougi/other_lecture/SE/num/num.htm
静岡理工大菅沼研究室のサイト　連立方程式、非線形方程式、数値積分、微分方程式、補完法


http://www-fcs.acs.i.kyoto-u.ac.jp/~harada/OC_Integral/index.html
京都大学のサイト　数値積分について

http://dse.ssi.ist.hokudai.ac.jp/~onosato/EDUCATION/sec04-06.pdf
北海道大学のPDF　数値計算について

http://gihyo.jp/dev/serial/01/java-calculation/0012
数値計算におけるIEE754実装

http://shimaphoto03.com/science/rk-method/
ルンゲクッタ法・オイラー法による常微分方程式の数値解析について

http://www.aoni.waseda.jp/ykagawa/ode1html/node5.html
常微分方程式について



まあそんなに身についてるわけじゃないですが・・・メモとして・・
どうしてもAtomでAthrill開発環境を作りたい

## 概要
以前、Athrill開発環境をVSCode上で構築する[こんな記事](https://qiita.com/Maeda-Shoota/items/4b1be75a6c4993522ab1#vscodeの設定)を書きましたが、せっかくなので大人気エディタAtomでの構築方法も簡単にまとめます。

Athrillについて⇒[athrill(アスリル)機能マニュアル](https://qiita.com/kanetugu2018/items/cf3dea16710a3f0737e8)

## Atom環境設定
#### 1. [Platformio-ide-terminal](https://atom.io/packages/platformio-ide-terminal)のインストール(拡張機能)
必須？Atom内でターミナルを起動できるようになります。インストール後、拡張機能の設定から「Shell Arguments」に使用するシェルへのパスを設定してください。
（WSLのデフォルトなら「C:\Windows\System32\bash.exe」）

## Athrill設定
Athrillではデバッグモード動作中、listコマンドで実行中箇所のソース表示を行えますが、標準ではVSCodeを起動しようとするため、Atomが立ち上がるよう修正します。

`{athrillルートdir}/bin/linux/geany.sh`を開き、

```bash:geany.sh
code -r -g ${FILE}:${LINE}
```
の箇所をAtomに変更すればよいのですが、WSLのバグ（らしい）によりatomコマンドでAtomが立ち上がらないことがあります。筆者もそうでした・・・

ここでは対策として、Atomの実行パスを直接書き込む方法を選択します。（より良い方法がありましたらご教授お願いします…！）

```bash:例
# code -r -g ${FILE}:${LINE}
/mnt/c/Users/{ユーザ名}/AppData/Local/atom/app-1.34.0/atom.exe ${FILE}:${LINE}
```

## 動作検証
Atom内ターミナルからAthrill上でプログラムを実行し、デバッグモードでl(list)コマンドを実行、起動中のAtomでソースが表示されれば導入完了です！

## まとめ
特にこだわりがなければVSCodeが楽です。。。
RedHat Quarkusを使ってビルドしたDockerコンテナを起動するところまで

RedHatがKubernetesなどのコンテナ環境に最適化されたJavaアプリケーションを実現するフレームワーク「[Quarkus](https://quarkus.io/)」を2019年3月7日に公開しました。

このフレームワークを使って実際にDockerコンテナを起動できるところまでやってみます。ごちゃごちゃとした説明は省き、端的にコマンドだけ示します。

## macosのセットアップ

JavaやMavenなどの必要なものをbrewでインストールします。

```bash
brew cask install java
brew install maven
```

## Quarkusのレポジトリをclone

```bash

git clone https://github.com/quarkusio/quarkus-quickstarts.git
```

## ローカルで起動

```
cd quarkus-quickstarts/getting-started
mvn compile quarkus:dev
```

## curlで接続してアプリケーションが動作しているか確認

```
curl http://localhost:8080/hello
```


## dockerイメージをビルド

```bash

mvn package -Pnative -Dnative-image.docker-build=true
docker build -f src/main/docker/Dockerfile -t quarkus/getting-started .
```

## dockerイメージからコンテナを起動

```
docker run -i --rm -p 8080:8080 quarkus/getting-started
```

## curlで接続してアプリケーションが動作しているか確認

```
curl http://localhost:8080/hello
```
iOSライセンス一覧を生成するツールLicensePlistが便利

#1.はじめに
App Storeにある有名アプリでもいくつか導入されているようだったので、試しに入れてみました。日本の方が作成したようでReadMeも読みやすいです。
[iOSライセンス一覧を生成するツール LicensePlist](https://github.com/mono0926/LicensePlist)
2017年に日本の方がリリースしたライブラリ(CLIツール)です。

現在個人アプリを開発中なのですが、以前は、ライセンス表記するために`設定`、`ライセンス一覧`、`ライセンス表示画面`を作ってplistから取得してゴニョゴニョ表示していました。
新しいライブラリを入れる度にplist更新しないといけないので、それが日に日に面倒でした。
プロジェクトによりますが、個人開発でなくてもそのような状況は、良くあるのではないでしょうか。
自分でscript書いてビルド時にライブラリのplistから摘出してってやっても良いと思いますが、それすらしたくない!って方にはいいかもしれません。結局ライブラリでやっていることはそれと同じようなことだと思いますが。
導入までの備忘録も兼ねて投稿します。

これを導入すると端末の設定アプリの該当のアプリの欄にLisenceというセルが追加されて、ライセンスたちはここに明記されるようになります。
<img width="898" alt="スクリーンショット 2019-03-12 11.27.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/184792/710fa482-f42c-c2bd-a68b-e1b4147944e0.png">

つまり、**アプリ内部でライセンス表記画面を作成する必要もなくなります。**
Settings Bundleを使用して端末の設定アプリにアプリ情報を表示したり、アプリの設定を変更できる機能を実装する仕組みは以前からありましたが、無知でしたでの僕は驚きました泣。

#2.メリット、デメリット
###メリット
・ **アプリ内部で専用画面を作る必要がない**
・ **ライブラリを導入する度に修正する手間がなくなる**
###デメリット
・ **手動でライブラリを取り込んだ場合は別途YMLの設定が必要**
・ **アプリ内部にライセンス表記がないのでユーザーが気づきにくい**
　(ライセンスを見る人なんて開発者くらいか)

手動でライブラリを取り込んだ場合というのは、例えばソースを直接入れたりGit Submodule使っている場合ですね。少々面倒。

#3.導入
Homebrew、mintでの導入も記載ありましたが、僕の場合CocoaPodsを使用していたので今回はCocoaPodsで。
はい、導入していきます。

```bash
pod 'LicensePlist'
```

```bash
pod update
```

あとはXcodeのBuild PhasesのRun Scriptに以下を追加。

```bash
if [ $CONFIGURATION = "Debug" ]; then
${PODS_ROOT}/LicensePlist/license-plist --output-path $PRODUCT_NAME/Settings.bundle --github-token YOUR_GITHUB_TOKEN
fi
```

こんな感じです。
<img width="737" alt="スクリーンショット 2019-03-12 12.04.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/184792/0324516f-d6f8-572f-1961-bd26f5820ec3.png">

そしてプロジェクトをビルドすると先ほど設定した`Run Script`でCLIが実行され、**ターミナルが自動起動されます**。
そのままではまだ、設定アプリ上には表示されていません。
`プロジェクトディレクトリ`内の`RootにSetting.bundle`が生成されているのでこれを`プロジェクトRoot`に追加します。
<img width="784" alt="スクリーンショット 2019-03-12 12.18.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/184792/bacd4a85-836c-b5fe-6f42-07fcc4a0d3cc.png">

その後アプリをビルドランすると設定アプリ>アプリ名>Licenseのセルが追加されています。
中を見るとこんな感じです。

<img width="375" alt="Screen Shot 2019-03-12 at 12.28.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/184792/99073dd2-5bf8-ac52-412b-47f5ad467dbb.png">
<img width="375" alt="Screen Shot 2019-03-12 at 12.29.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/184792/6d3b55a2-7cbf-8100-4e5a-1fc300890a75.png">
はい出来ました。

#4.最後に
ReadMeや本人の記事を見れば普通に導入できますが、分かりやすく解説してみました。
ライブラリを使う場合は、多くの場合でライセンス表記が必要なので、このようなツールはとても便利だと思います。
みなさんもぜひ使ってみてください。

その他参考にした記事やサイト
・ [iPhoneの設定アプリにライブラリのライセンスを表示するようにする](https://qiita.com/akatsuki174/items/392cb3be619fabfa4608)
・ [LicensePlist github](https://github.com/mono0926/LicensePlist)

・ [LicensePlist というiOSアプリ利用ライブラリのライセンス一覧を生成するツールを作りました](https://medium.com/swift-column/license-plist-c0363a008c67)
↑これは本人の記事です。
【連載】ジャンプ＆ランゲームを作ろう(7) マリオ風のジャンプを実装する

# これまでの連載記事

こちらのQiitaは勝手連載「ジャンプ＆ランゲームを作ろう」になります。
初回の記事はこちらです。

[【連載】ジャンプ＆ランゲームを作ろう(6) いろんな床を生成しよう](https://qiita.com/motoyasu-yamada/items/58412eeecac2e0532b2a)
※お断り※ 毎日お昼休みに15分程度で執筆していおり細切れになりましてすみません


# 今回の内容

かってチャリ走のシリーズ「[超チャリ走 for Nintendo 3DS](https://www.nintendo.co.jp/titles/50010000039506)」で長押しジャンプを取り入れたことがありました。ジャンプを押した長さに応じてジャンプ距離が変わるというものです。難易度がくそ難しくなり、結局このタイトルは微妙な評価になってしまいました。

ネットの記事でマリオのジャンプアルゴリズムというのを見ました
https://blog.game-kids.net/haruzakki/entry-769.html

確かにマリオはジャンプを押す長さに応じて飛ぶ距離が変わるけど、難易度が難しくなる印象ないというか、楽になっているイメージがあったので、興味をもってアルゴリズムの記事を読んでみました。

シンプルにまとめると
1. ジャンプすると上向き初速度が適用される
2. 重力加速度は、落下時をふくめた通常状態の加速度と、ボタンを押下中の重力加速度と2種類がある
3. また、停止または低速時、低速ダッシュ時、高速ダッシュ時の3種類でパラメータが異なる

今回は、初速度、二種類の重力加速度を取り入れて、タップしている時間にあわせたジャンプを実装します


# 今回の実装のまとめ

https://github.com/liberapp-inc/h5g-qiita-jump-and-run/commit/a76a69912b8d2c5af1da07988c0c0055e87ff745

# 解説

## 「タップした」だけではなく「タップ中」のフラグもとる

イベント`TOUCH_BEGIN`でタップしたというフラグ`tapped`を管理していました。
あわせてイベント`TOUCH_END`をキャッチすることで、タップ中のフラグ`tapping`を管理します

```diff:Main.ts
:
-        this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.tap, this);
+        this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTouchBegin, this);
+        this.addEventListener(egret.TouchEvent.TOUCH_END, this.onTouchEnd, this);
    }
    
     private tapped: boolean;
+    private tapping : boolean;

+    private onTouchBegin(e: egret.TouchEvent) {
+        this.tapped  = true;
+        this.tapping = true;
+    }

+    private onTouchEnd(e: egret.TouchEvent) {
+        this.tapping = false;
+    }

:

-    private tap(e: egret.TouchEvent) {
-        this.tapped = true;
-    }

## マジックナンバーをやめる
いままで速度・加速度を生の数値で埋め込んでいました。その場合は数値の意味をソースコードから推定しなくてはなりません。速度・加速度の数値をソースコードの先頭に定数でまとめました。

```diff:Main.ts
+ const MAX_VELOCITY_Y = 10;
+ const INITIAL_VELOCITY = -7;
+ const GRAVITATIONAL_ACCELERATION_DEFAULT = 0.7;
+ const GRAVITATIONAL_ACCELERATION_ON_TAP = 0.2;
```

## タップ中かどうかに応じて適用する重力加速度をかえる

ボールの垂直方向の速度に重力の力を加える際の重力加速度を、タップ中かを管理するフラグ`this.tapping`にあわせて切り替えています。

```diff:Main.ts
-            this.ballVy += 0.6;
+            const g = this.tapping ? GRAVITATIONAL_ACCELERATION_ON_TAP : GRAVITATIONAL_ACCELERATION_DEFAULT;
+            this.ballVy += g;
        }
```

## マジックナンバーは定数を利用
ジャンプ時の初速や、Y方向の速度の上下限値については、マジックナンバーを定数化しました

```diff:Main.ts
        if ((isBallOnBlock || this.jumpCount < 2) && this.tapped) {
-            this.ballVy = -5;
+            this.ballVy = INITIAL_VELOCITY;
            this.ball.y += this.ballVy;
            this.jumpCount ++;
        }
-        this.ballVy = limit(this.ballVy, -7, 7);
+        this.ballVy = limit(this.ballVy, -MAX_VELOCITY_Y, MAX_VELOCITY_Y);
        this.tapped = false;
    }
```

# 遊べるサンプル
https://liberapp.net/applications/643acd30-4074-11e9-bb24-e194797f46d1
Elixir: リストに要素を加える

リストに要素をひとつ加える場合の書き方です。


# リストはヘッドとテイルの組みで表される
リストは`|`演算子を用いて、頭の要素(ヘッド)と残りのリスト(テイル)に分けることができます。

```elixir
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]
```

これは、Elixirにおけるリストの内部的な扱いを表しています。つまり、リストはヘッドとテイルの組みを入れ子にしたものです。最後のテイルは空のリスト`[]`であることにご注目ください。

```elixir
iex> [1 | [2 | [3 | []]]]
[1, 2, 3]
```

最後のテイルが空`[]`でないと、不適切なリストとして扱われます。ただし、特別な環境で使われるため、エラーにはなりません(「[List](https://hexdocs.pm/elixir/List.html)」参照)。

```elixir
iex> [1 | [2 | [3 | 4]]] 
[1, 2, 3 | 4]
```


# リストのはじめに要素を加える
リスト同士を連結するのは[`++/2`](https://hexdocs.pm/elixir/Kernel.html#++/2)演算子です。要素(`item`)をリスト(`list`)のはじめに加える処理は、つぎのように書けます。

```elixir
[item] ++ list
```

正しいコードです。けれど、つぎのように内部表現に沿って`|`演算子を用いる方がよいでしょう。

```elixir
[item | list]
```


# リストの最後に要素を加える
要素を最後に加えるときは、`++/2`演算子の出番に思われます。

```elixir
list ++ [item]
```

動作に問題はありません。もっとも、最後のリスト要素を見つけなければならないので、サイズが大きいほど効率は落ちます。公式ドキュメントの[`++/2`](https://hexdocs.pm/elixir/Kernel.html#++/2)の解説によれば、はじめに加えて、順序を逆転させる方がよいそうです。

```elixir
[item |list] |> Enum.reverse()
```


# Erlangによる実装
[`++/2`の実装](https://github.com/elixir-lang/elixir/blob/v1.8.1/lib/elixir/lib/kernel.ex#L1298)は`:erlang.++/2`([`lists.append/2`](http://erlang.org/doc/man/lists.html#append-2))を呼び出しています。Erlangの処理はつぎのとおりで、再帰のたびに左辺のリストのコピーがつくられるのです(5「List Handling」5.1「[Creating a List](http://erlang.org/doc/efficiency_guide/listHandling.html#creating-a-list)」参照)。

```erlang
append([H|T], Tail) ->
    [H|append(T, Tail)];
append([], Tail) ->
    Tail.
```

[`Enum.reverse/1`](https://hexdocs.pm/elixir/Enum.html#reverse/1)の[実装](https://github.com/elixir-lang/elixir/blob/v1.8.1/lib/elixir/lib/enum.ex#L2024)が呼び出すErlangの[`:lists.reverse/1`](http://erlang.org/doc/man/lists.html#reverse-1)は、反転したリストを新たにひとつつくるだけです。前出5.1「Creating a List」の例を実測した記事「[Erlang 入門 (3) - リスト](https://qiita.com/nunulk/items/64433a02d358754c3484)」によると、処理時間に約30倍の開きが出たといいます。
AWS SDK for .NETで署名バージョンが4になっているか確認する方法

## 経緯
こちらの記事を見て慌てました。
https://dev.classmethod.jp/cloud/aws/s3-sigv2-abolition/

いくつかS3からファイルをダウンロードするアプリを作っているので、対応しないとやばい！となって確認しました。
しかし、見てみると「AWS SDK for .NET v3」を使っている場合はデフォルトで署名バージョンは4になっているとの事なので特段対応する必要なないのですが、目で見ないとソワソワしちゃう性分なので、SDKのソースコードを見て確認方法を探してみました。

その結果、デバッグでインスタンス内容を見ることで署名バージョンが確認できたのでその方法を紹介します。

## 確認方法
まず、自分のコード上で

```csharp
var s3Client = new AmazonS3Client();
```

のようにS3Clientをしている所を探します。この直後にブレークポイントを打ち、プログラムを起動させて動作を止めます。
止まったら、イミディエイトウィンドウを起動して下記コマンドを実行してください

```
((Amazon.S3.Internal.S3Signer)s3Client.Signer)._s3Signer._useSigV4
```

**s3Client**の部分はAmazonS3Clientのインスタンス名なので、自分の実装に合わせてください。

実行結果がtrueになっていれば署名バージョンが4になっています。
私みたいに目で見ないとソワソワしてしまう人に役に立てば幸いです。
Fortranでの静的ライブラリのリンクとmodule

"fortranの静的ライブラリと問題点"
https://qiita.com/blu_epos_t59/items/1a88230698f5de9cb615
という記事に、Fortranの静的ライブラリを作る記事があるが、

> ただし、調べてみたところどうやら読まれるのは宣言部、つまりcontains以下のみであり、subroutineしかまとめることができないらしい。定数はおろか構造体やクラスもまとめることができない。

及び、

>なので、moduleのソースをどこかにまとめて置いておいてmakefileでその都度一緒にコンパイルするほうがいいと思う。

とあった。これではmoduleを使った場合に非常に面倒なので、2019年現在どうなっているか調べてみた。

# バージョン
gcc version 7.2.0 (Homebrew GCC 7.2.0_1) 

# コード
記事にあるものと同じ、単純なモジュールを考える。

```fortran:mylib.f90
module mylib
   implicit none
   integer :: mynum = 100
   type myclass
      integer :: id
   end type myclass
contains 
   subroutine myroutine()
      write(6,*) "hello world!"
   end subroutine myroutine
end module mylib
```
また、Makefileを

```makefile
all:mylib.f90
	gfortran -c mylib.f90 -o mylib.o
	ar cr libmylib.a mylib.o
```
とした。

これを```test```ディレクトリに置く。そして、

```fortran:test.f90
program main
    use mylib
    implicit none
    type(myclass)::a
    write(*,*) mynum
    a%id = 4
    write(*,*) a%id

    call myroutine()
end
```
をその上のディレクトリに置いてみよう。つまり、

```
test		test.f90
```
で、testの中身は

```
Makefile	mylib.f90
```
という状況とする。

# make
testディレクトリ内で

```bash
make
```
をすると、

```bash
ls
Makefile	libmylib.a	mylib.f90	mylib.mod	mylib.o
```
となる。次に、その上の```test.f90```のあるディレクトリに行って、

```bash
gfortran test.f90 -L./test/  -lmylib
```
としてみたが、

```bash
test.f90:2:8:

     use mylib
        1
Fatal Error: Can't open module file 'mylib.mod' for reading at (1): No such file or directory
compilation terminated.

```
というエラーが出た。つまり、moduleを探すことができていない。
そこで、
https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/510065
を参考にして、

```bash
gfortran test.f90 -L./test/ -I./test -lmylib
```
とすると、ちゃんとコンパイルできて、出力は

```bash
./a.out 
         100
           4
 hello world!
```
となった。

# まとめ
今回使ったgfortranのバージョンでは、記事の問題を再現できなかった。一方、modがないと言われる件に関しては、Iオプションをつけることで解決することができた。
Javaのフレームワーク「Quarkus」を試してみた

# はじめに

アプリケーションをDockerコンテナ上で運用する機会が多くなってきました。
コンテナで運用するにあたり、起動時間は重要になってきます。
Javaを実行する際、JVM上で動かすわけですが、このJVMの起動にはやや時間がかかります。

今回ご紹介するQuarkusは、GraalVMを使いネイティブ用のバイナリを作成することで、高速起動を実現するフレームワークになります。

# 実行環境

- MacOS Mojave

# 前提条件

- Java 8以上
- Maven 3.5.3以上

# GraalVMのセットアップ
[ここ](https://github.com/oracle/graal/releases)からgraalvm-ce-1.0.0-rc13-macos-amd64.tar.gz
（2019/03/12時点）をダウンロードしてください。

解凍し、/Library/Java/JavaVirtualMachinesにフォルダごと置いてください。

GraalVMの環境変数（GRAALVM_HOME）を設定します。

```bash:.bash_profile
GRAALVM_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-1.0.0-rc13-macos-amd64/Contents/Home
```

# プロジェクトを作成

```console
$ mvn io.quarkus:quarkus-maven-plugin:0.11.0:create \
    -DprojectGroupId=jp.acme \
    -DprojectArtifactId=getting-started \
    -DclassName="org.acme.quickstart.GreetingResource" \
    -Dpath="/hello"
```

上記のコマンドを実行すると、下図のようなMavenプロジェクトが作成されます。

![quarkus.png](https://qiita-image-store.s3.amazonaws.com/0/53830/9feafadc-9061-9bc9-b0e8-a1295e1fccfb.png)

# アプリケーション起動

```console
# 開発モードで起動
$ mvn compile quarkus:dev
```

開発モードで起動すると、ホットリロードが実現できます。
以下のコマンドで動作確認します。

```console
$ curl http://localhost:8080/hello
```

# ビルド（ネイティブのバイナリ生成）

```console
$ mvn package -Pnative -Dnative-image.docker-build=true
```

|オプション|内容|
|:--|:--|
|-Pnative|ネイティブで実行可能なバイナリを生成する際に指定する|
|-Dnative-image.docker-build=true|Docker上のOSに合わせたネイティブのバイナリを生成する場合に指定する|
今回はDocker上で起動したいので、```-Dnative-image.docker-build=true```も指定します。

ビルドにはネイティブバイナリの生成を行うためか、多少時間がかかります。

# Dockerビルド

```console
$ docker build -f src/main/docker/Dockerfile -t <イメージ名> .
```

# Dockerコンテナ起動

```console
$ docker run -i --rm -p 8080:8080 <イメージ名>
2019-03-12 01:29:01,328 INFO  [io.quarkus] (main) Quarkus 0.11.0 started in 0.004s. Listening on: http://0.0.0.0:8080
2019-03-12 01:29:01,328 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]
```

ここで注目して欲しいのは、起動時間です。
起動後のログを確認すると、```Quarkus 0.11.0 started in 0.004s```とあります。
つまり、0.004秒で起動されたことがわかります。早いですね。

# おわりに

Quarkusを利用することで、コンテナ上のアプリケーションの起動が圧倒的に早くなりました。
Quarkus自体、出たばかりなので、本番での実用は難しいとは思いますが、開発が進み情報が増えてくれば、実用可能になる機会は増えてくると思います。今後に期待しています。

あと、Quarkusには拡張機能も追加できます。
例えば、デフォルトだとJavaEE標準のCDIですが、これをSpringベースのCDIが利用できたりします。
ここら辺も調査していきつつ情報を共有していきます。

# 参考
- [QUARKUS(本家サイト)](https://quarkus.io/)
- [Quarkus: コンテナ上で Java アプリを高速起動する新しい手法のご紹介](https://yoshio3.com/2019/03/11/try-quarkus/)
Gradle-SpringBoot ：STS(Eclipse)上でHot Deployを有効にする方法(HTMLはThymeleaf)

いろいろとネット上の記事にある方法を試してみましたが上手くいかないので、
結局このやり方が一番良いのかなと思える方法を書いておきます。
Java側はJavaのDebug機能を用いてソースの更新を検知し、
HTML関係はSpringにリソースとして登録しておく。

## build.gradleの設定
build.gradleに下記の設定を追加する。

~~~~
bootRun {
	sourceResources sourceSets.main
	jvmArgs=["-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"]
}
~~~~

1. sourceResources sourceSets.main
    HTML、Javascript、CSS、その他リソースの自動更新(src/main/resourcesが対象になる)

2. jvmArgs=["- agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"]
    SpringBootをデバッグ起動させるための設定　デバッグポートは5005


### こちらの依存の追加もしておきましょう
~~~~
compile("org.springframework.boot:spring-boot-devtools")
~~~~

## application.propertiesに以下のプロパティを追加
~~~~
spring.resources.cache.period=0
spring.thymeleaf.cache=false
~~~~
1. spring.resources.cache.period=0
    キャッシュ時間ゼロ（これは要らないカモカモカモカモカモミール）

2. spring.thymeleaf.cache=false
    thymeleafのキャッシュをしない。

## Gradle実行設定（Eclipse, STS)
特別な設定はなく、ワークスペースのプロジェクトを指定して実行。
実行設定から下記イメージの様に設定。
<img width="522" alt="gradle_setting.png" src="https://qiita-image-store.s3.amazonaws.com/0/375776/1005156a-a409-6d83-2f9c-b7d2caa153ec.png">

## デバッグ設定
デバッグの実行設定から **Remote Java Application** を選び、build.gradleに記述したポートを設定する。

<img width="708" alt="debug_setting.png" src="https://qiita-image-store.s3.amazonaws.com/0/375776/fdc9e45a-6a57-0d1a-97d3-63584e62d61d.png">


## bootRunの実行
Eclipse(STS)の実行メニューからbootRunを実行する。
コンソールに下記のメッセージが出て、デバッグポート5005に接続が入るまで実行が中断される。


## デバッガの起動
Eclipse(STS)のメニューから設定したデバッガを起動する。
SpringBoot起動のメッセージが出力される。

* この時内部で一時的に発生する例外がデバッガを止めることがあるので、F8を押して実行を続行する。

<img width="750" alt="debug_console_restart.png" src="https://qiita-image-store.s3.amazonaws.com/0/375776/8f316ca6-4735-2c75-1116-5ac3958ca03b.png">


## Hot Deploy を Enjoy
1. デバッグポインタを使ってソースコードをチェック・その場で修正
    => Javaのデバッグなので、メソッド名やフィールドを変更するとリロード出来ないので、その辺はご了承ください。
2. HTMLのあるsrc/main/resourcesは修正と同時にリロードされます。
tera tarmマクロ　作成用メモ


【前提条件】
・現在使用しているTera Tarmのバージョン「4.9.3」
・複数機器にログイン・汎用性を持たせるために別紙テキストを読み込む用作成
・下記テキストを作成　※直接記載で下記テキストは不要でもOK
　－OV.txt
　　⇒踏み台として利用する機器名・IPアドレス
　－hozon.txt
　　⇒出力したログを置く場所指定。ディレクトリパスを記載
　－host_ipadd.txt
　　⇒ログ取得対象のIPアドレスと機器名
　－show_comm.txt
　　⇒取得コマンド一覧

【任意の名前.ttl】
＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
;;;外部ファイルを開いて「login」にファイルの内容を格納。「0」はファイルの頭から読み込み
fileopen login 'host_ipadd.txt' 0
:LOOP

;;;fileopenで読んだ「login」から一行読み出し、「host_nmif・host_ip」に格納
filereadln login host_nmif result goto filclose
filereadln login host_ip
 if result goto filclose


;log保存先フォルダ読み込み

fileopen log_outp 'hozon.txt' 0
filereadln log_outp log_outp2
fileclose log_outp

fileopen springboard 'OV.txt' 0
conchk = 1

:SPRINGBOARDLOOP

filereadln springboard springboard_nm
 if result goto LOG_GET
filereadln springboard springboard_ip
 if result goto LOG_GET

;;「springboard_nm」で格納した内容に「'#'」を追加する
strconcat springboard_nm '#'
if conchk = 1 then
  strconcat springboard_ip ':23 /nossh /T=1'
  connect springboard_ip
  wait 'Username:'
  sendln 'cisco'
  wait 'Password:'
  sendln 'cisco'
else
  Telnet = 'telnet '
  strconcat Telnet springboard_ip
  sendln Telnet
  wait 'Password:' '#' 
  sendln 'cisco'
  wait springboard_nm '#'
endif

conchk = conchk+1
goto SPRINGBOARDLOOP

:LOG_GET
fileclose springboard

mpause 50

;; ログファイル名の設定
;日時とホスト名入れる場合
getdate strLOG_NAME "_%Y%m%d_%H%M%S"

strLOG_FILE = log_outp2
strconcat strLOG_FILE host_name
strconcat strLOG_FILE strLOG_NAME
strconcat strLOG_FILE '.log'
strconcat host_name '#'

if conchk = 1 then
  strconcat host_ip ':23 /nossh /T=1'
  connect host_ip
  wait 'Password:'
  sendln 'cisco'
  wait host_name
else
  Telnet = 'telnet '
  strconcat Telnet host_ip
  sendln Telnet
  wait 'Password:' '#'
  sendln 'cisco'
  wait host_name '>' '#'
  sendln 'enable'
  wait 'Password:' '#'
  sendln 'cisco'
  wait host_name '#'
endif

setsync 1
;; ログ取得開始
logopen strLOG_FILE 1 1
timeout=300
fileopen list 'show_comm.txt' 0
mpause 200

while 1
 ;ファイルから1行読む
 filereadln list line2


;最終まで読み込んでいたらループを抜ける
 if result = 1 break


;読み込んだコマンドを実行
 flushrecv
 sendln line2
 wait '--More--' host_name '[confirm]' '#'
 mpause 50

 if result = 1 then
  sendln $03
  mpause 10
  fileclose list
  end
 endif
 
 flushrecv
endwhile

fileclose list

mpause 100
sendln ''
wait host_name '#'
mpause 50
while  conchk > 1
 sendln 'exit'
 wait 'closed'
 mpause 50
 conchk = conchk - 1
endwhile
setsync 0
sendln 'exit'
logclose

unlink
goto LOOP

:filclose
fileclose login
＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
マクロがうまく動作しない場合は、
messageboxや変数を利用してうまく動作しない部分を調査する。
Mac版のAmazon Driveインストールに手こずる話

メモ程度ですが，誰かのお役にたてば。

# Amazon Drive
これは罠である。
https://www.amazon.co.jp/Amazon-Digital-Services-Inc-Driveデスクトップ/dp/B00W9J9X1M

「Amazon_Driveデスクトップ_Mac_ダウンロード_Downloader.dmg」というファイルをダウンロードして，インストールしようとするとずっこける。
何もエラーを出さずにすっと消えていくので全くわからない。

# Amazon Photo
こちらが正解。
https://www.amazon.co.jp/b?_encoding=UTF8&node=5262651051&ref_=cdw_ms_ga

「通常のDriveのように同期して使いたい」という人のために，使い方が理解できないだろうからココに記す。

インストールしたあと謎の，ピクチャとムービーの同期選択画面とかダウンロード先設定などがでてくる。
これはまさに意味不明であるが，ここは無視して設定に入る。
そこに「同期機能の有効化」みたいなチェックボックスがあるだろうから，それを有効にする。
するとアプリの再起動を促されてアプリが自動的に落ちる。
しょうがないのでアプリをもう一度起動すると，なんとAmazon Driveとして動作する。

# 結論
これはびっくり。
メモリ関連のパラメータなどを誤設定してしまったためにOracleインスタンスが起動しなくなってしまった場合の対処

うっかりメモリ搭載量より多くのサイズをSGAに指定してしまったりするとOracleが起動しなくなってしまうことがあります。
そんなときの対処方法です。

# SPFILEを基に任意の場所にPFILEを作成する
SQL*Plusを起動してcreate pfileします。

```
sqlplus / as sysdba
create pfile='/home/oracle/temp_init.ora' from spfile='+DATA/ORCL/spfileorcl.ora';
```

# パラメータの値を手動で修正
viなどで前項で作成したpfileのパラメータを元に戻します。

# 修正を行ったPFILEを基にSPFILEを作成
修正したPFILEでインスタンスが起動するか確認して、問題なく起動するようでしたらSPFILEを作成します。

```
sqlplus / as sysdba
startup pfile='/home/oracle/temp_init.ora'
create spfile='+DATA/ORCL/spfileorcl.ora' from pfile='/home/oracle/temp_init.ora';
shutdown immediate
startup
```

# Oracleの起動...

```
srvctl stop database -d orcl
srvctl start database -d orcl
```
systemctlコマンド チートシート

## systemctlコマンド　一覧
* .serviceは省略可能
* nameはサービス名

|systemctl  |詳細  |
|---|---|
|systemctl start name.service  |サービスを起動します。  |
|systemctl stop name.service  |サービスを停止します。  |
|systemctl restart name.service  |サービスを再起動します。 |
|systemctl try-restart name.service  |サービスが実行中の場合のみ、再起動します。|
|systemctl reload name.service  |設定を再読み込みします。 |
|systemctl status name.service  |サービスが実行中かどうかをチェックします。 |
|systemctl list-units --type service --all  |すべてのサービスのステータスを表示します。 |
|systemctl enable name.service  |サービスを有効にします。 |
|systemctl disable name.service  |サービスを無効にします。 |
|systemctl list-dependencies --after  |指定されたユニットの前に開始するよう命令されるサービスを一覧表示します。 |
|systemctl list-dependencies --before  |指定されたユニットの後に開始するように命令されるサービスを一覧表示します。 |

## Link
[Hat Enterprise>Linux>7>システム管理者のガイド10.2.システムサービスの管理](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-Managing_Services_with_systemd-Services#tabl-Managing_Services_with_systemd-Services-systemctl)
Firebaseの対抗馬？Amplifyの概要


# Amplify
AWSをBAASとして扱うためのフロント向けフレームワーク。
iOS / Android / SPAに対応。
cliを使って、AWSのサービスとクライアント側APIの双方の管理が可能。

例えば
> amplify add api

によって、ブラウザからアクセス可能なAPIが生成される。
裏側では
- サーバ側のappsync / dynamodbと
- クライアント側のjs コード
が生成される。

- メリット
必要なサービスを一括で作れる
Rails Wayみたいに、乗ってけ的な楽さはある。

- デメリット
結局個々の機能は別々に学習していく必要がある。
情報が個々の機能とAmplifyで分散する。



# Cognito

```
amplify add auth
```
作成時に「全部デフォルト」すると、ユーザプール名が意味のないIDになってしまって切ない思いをする。
ユーザ管理と認証をしてくれる。
TwitterとかGoogleアカウントとかもやってくれる偉いやつ。

IAMロールを関連づけることができる。

# AppSync
DynamoDB/ElasticSearch/Auroraをバックエンドに、スマホから直接クエリーを投げたりデータ同期が出来る。

```
amplify add api
```

## 認証

API_KEYかCOGNITOを選べる　

```amplify/backend/baend-config.json 
"output": {
   "securityType": "API_KEY"
}
```

https://aws-amplify.github.io/docs/js/api
API_KEY / AWS_IAM / AMAZON_COGNITO_USER_POOLS / OPENID_CONNECT

認証かけてる
https://dev.classmethod.jp/cloud/aws/higobashi-aws-5-angular-appsync/

## connection
@connectionで、model同士の関連が作れる。

# S3 / Storage

```
amplify add storage
```


クライアントから直接S3へアクセスする。
アクセス制御は、CognitoのIAMをベースとする。

そのユーザにしか見えないフォルダも作れるっぽい。
Prettier 入門

![スクリーンショット 2019-03-10 12.44.19.png](https://qiita-image-store.s3.amazonaws.com/0/242655/70addf0e-bf76-3a02-63f4-81778dec26a8.png)

# Prettier とは
- [Prettier · Opinionated Code Formatter](https://prettier.io/)
- コードフォーマッタ (コード整形ツール)
- HTML, CSS, JavaScript, Markdown, YAML, GraphQLなどの言語に対応している (詳しくは[公式サイト](https://prettier.io/)参照)
- Atom, Emacs, Espresso, Sublime Text, Vim, Visual Studio, VS Code, WebStorm などのエディタでプラグインが提供されている(もちろんnodeのモジュールとして単体でも使える)

# コードフォーマッタとは
以下のように、指定したルールに沿って、ソースコードを自動整形するツール。

- HTML

```html:
<!-- 整形前 -->
<!DOCTYPE html>
<html lang="ja">
  <head>
  <meta charset="UTF-8" />
      <meta name="viewport"   content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    
    <title>Sample</title>
  </head>
    <body>
        Sample
  </body>
  
</html>


<!-- 整形後 -->
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Sample</title>
  </head>
  <body>
    Sample
  </body>
</html>
```

- CSS

```css:
/* 整形前 */
.hogehoge {
    background-color: #fff;
  color: #000;
}
.hogehoge::before {
    content: "";
  }


/* 整形後 */
.hogehoge {
  background-color: #fff;
  color: #000;
}
.hogehoge::before {
  content: '';
}
```

- JavaScript

```javascript:
// 整形前
const increment = x=>x++;


// 整形後
const increment = (x) => x++;
```

# とりあえず使ってみる
```console:
$ npm init -y
$ npm install --save-dev --save-exact prettier
$ npx prettier --write src/**/*.*
```

# 設定を変更する
詳細な設定値の意味については、[公式サイト](https://prettier.io/docs/en/options.html)参照

```JavaScript:.prettierrc.js
module.exports = {
  // デフォルト設定
  // printWidth: 80
  // tabWidth: 2,
  // useTabs: false,
  // semi: ture,
  // singleQuote: false,
  // quoteProps: 'as-needed',
  // jsxSingleQuote: false,
  // trailingComma: 'es5',
  // bracketSpacing: true,
  // jsxBracketSameLine: false,
  // arrowParens: 'always',
  // rangeStart: 0,
  // rangeEnd: Infinity,
  // jsxBracketSameLine: false,
  // requirePragma: false,
  // insertPragma: false,
  // proseWrap: 'preserve',
  // htmlWhitespaceSensitivity: "css",
  // vueIndentScriptAndStyle: false,
  // endOfLine: 'lf',
  // embeddedLanguageFormatting: 'auto',
  // 特定のファイルのみ設定をオーバーライドする
  overrides: [
    // HTMLファイル
    {
      files: '*.html',
      options: {}
    },
    // CSSファイル
    {
      files: '*.css',
      options: {}
    },
    // jsファイル
    {
      files: '*.js',
      options: {
        trailingComma: 'es5',
        arrowParens: 'always',
        singleQuote: true
      }
    }
  ]
};
```

# ファイル保存時に自動フォーマットしたい
他のモジュールと組み合わせれば可能。

```console:
$ npm install --save-dev onchange
$ npx onchange "src/**/*.*" -- prettier --write {{changed}}
```
# サンプルコード
https://github.com/ohnaka0410/nodejs-samples/tree/main/prettier

# おすすめ設定
[Prettierのおすすめ設定](https://qiita.com/ohnaka0410/items/abdfb164174d6618d728)
【BigQuery】EXISTS関数をつかって、目的の行を抜き出してみた

#概要


BigQueryでEXISTS関数を紹介します。

以下、Postgresqlドキュメントより引用

>
EXISTSの引数は、任意のSELECT文、つまり副問い合わせです。 副問い合わせはそれが何らかの行を返すか否かの決定のために評価されます。 もし1つでも行を返すのであれば、EXISTSの結果は「true（真）」となり、副問い合わせが行を返さない場合、EXISTSの結果は「false（偽）」となります。


#データ紹介

テーブル1：item_table


|user_id|item|price|
|----|----|-----|
|A|みかん|50|
|A|もやし|19|
|A|りんご|100|
|B|りんご|100|
|B|りんご|90|


テーブル2：item_price_m

|product|price|
|----|-----|
|もやし|19|
|ネギ|298|
|小松菜|298|
|みかん|50|
|りんご|100|
|メロン|3000|



## 基本1：EXISTS関数の使い方


BigQueryへ取り込んでおいた二つのテーブルを使い、WHERE句で条件を絞ります。


```sql:BigQuery　基本１

SELECT
  *
FROM
  test1.item_table AS t1
WHERE
  EXISTS (
  SELECT
    product
  FROM
    test1.item_price_m AS t2
  WHERE
    t1.item = t2.product )
ORDER BY
  user_id ;
```

出力は以下です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352801/e4c07bae-4cf1-f12f-0dd2-6b322a6d57b1.png)


続いて、複数の条件をいれた場合です。


```sql:BigQuery　基本１　複数の条件の場合

SELECT
  *
FROM
  test1.item_table AS t1
WHERE
  EXISTS (
  SELECT
    product
  FROM
    test1.item_price_m AS t2
  WHERE
    t1.item = t2.product
    AND t1.price = t2.price)
ORDER BY
  user_id ;
```
出力は以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352801/1bf13b70-f6bd-faa1-d6f9-b2bd7aa0aef6.png)


## 基本2：NOT EXISTS関数の使い方

EXISTS関数と対の条件になる`NOT EXISTS`を使ってみます。

`NOT EXISTS`を使った構文は以下になります。

```sql:BigQuery　基本２


SELECT
  *
FROM
  test1.item_table AS A
WHERE
  NOT EXISTS (
  SELECT
    item
  FROM
    test1.item_price_m AS B
  WHERE
    A.item = B.product
    AND A.price = B.price )
ORDER BY
   user_id;

```
出力は以下の様になりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352801/29652e9c-cc4c-3df7-8843-76451b4efda5.png)


条件に一致しない行の抽出がされました。




#まとめ
EXISTS関数を使うと、テーブルに目的の行が存在するかどうかの存在チェックができます。
WHERE句のINと似ていますが、SQLの実行挙動が異なり、EXSITS関数の方が、早いと言われています。
是非、習得しておきたい関数だとおもいました。


#参考サイト


https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql?hl=ja
https://www.postgresql.jp/document/10/html/functions-subquery.html