OmniAICreator/Qiita-1.07M huggingface dataset:
PostGISでの空間結合のチューニング


以下のようなPostGISでの空間結合のチューニングの記事を見かけたので試行した際のメモ。
[5x Faster Spatial Join with this One Weird Trick](http://blog.cleverelephant.ca/2018/09/postgis-external-storage.html)

例えばPointとPolygonでの空間結合のような処理で、サイズの大きなポリゴンが多数存在するような場合に、簡単な手順でパフォーマンス改善ができる余地がある模様。


# 環境

試行の際に使用した環境は以下。

- PostgreSQL 11.1
- PostGIS 2.5.1

# 試行の手順

基本的には [5x Faster Spatial Join with this One Weird Trick](http://blog.cleverelephant.ca/2018/09/postgis-external-storage.html) の通りなので、流れだけ記述。


## サンプルデータの入手とロード

[Natural Earth](https://www.naturalearthdata.com/)からサンプルのデータとしてne_10m_admin_0_countries.zipとne_10m_populated_places.zipを入手。

zipファイルを解凍したのち、PostGISに付随する shp2pgsql のツールを用いてPostGISにロードする。
ここではテスト用に作成していた geomdb というDBに対してインポートするため、以下のようなコマンドで実行した。

```
shp2pgsql -s 4326 -D -I ne_10m_admin_0_countries.shp countries | psql -U postgres geomdb
shp2pgsql -s 4326 -D -I ne_10m_populated_places.shp places | psql -U postgres geomdb
```

それぞれcountries, placesというテーブルにロードされる。

なおshp2pgsqlコマンドのオプションは以下の通り。
[4.4.2. Using the Loader](http://postgis.net/docs/manual-2.0/using_postgis_dbmanagement.html#shp2pgsql_usage)


## 通常のパフォーマンス

何もしない状態で [5x Faster Spatial Join with this One Weird Trick](http://blog.cleverelephant.ca/2018/09/postgis-external-storage.html) に上げられている`ST_Intersects`を用いたクエリを実行したところ、手元のPCでは約10秒ほどの時間がかかった。

これはcountriesテーブルのうちサイズの大きな約150件ほどのポリゴンがTOASTのタプルに圧縮状態で格納されており、それらのpglz_decompress関数での解凍で多くの時間が使われているためとのこと。


## チューニングとその結果

以下のようにEXTERNALのオプションを指定して、countriesテーブルのポリゴンをTOASTのタプルに非圧縮で格納する。

```
-- Change the storage type
ALTER TABLE countries
  ALTER COLUMN geom
  SET STORAGE EXTERNAL;

-- Force the column to rewrite
UPDATE countries
  SET geom = ST_SetSRID(geom, 4326);
```
（[5x Faster Spatial Join with this One Weird Trick](http://blog.cleverelephant.ca/2018/09/postgis-external-storage.html)より引用）

その上でチューニング前と同じクエリを実行したところ、処理時間が約1.3秒程度に改善された。


# まとめ

- PostGISでは、一定以上サイズの大きなジオメトリはTOASTのタプルに格納する。その際に"MAIN"のストレージオプションが使われ、大きなジオメトリは圧縮して格納される。
 - 圧縮されたジオメトリが多い場合は、pglz_decompress関数での解凍に時間がかかる場合がある。

- 以下のように"EXTERNAL"のストレージオプションを使用して、非圧縮でジオメトリをTOASTのタプルに保持することで、高速化することが可能。
 - この使用するストレージの変更は、特別なプログラムなど無しで対応可能。
 - 但し、（当然ながら）使用するストレージの容量は増加する。

```
ALTER TABLE [table] ALTER COLUMN [geometry_column] SET STORAGE EXTERNAL;
UPDATE [table] SET [geometry_column] = ST_SetSRID([geometry_column], [SRID]);
```

- また、圧縮が必要となるような大きなサイズのジオメトリが少ない場合も、この調整による効果は小さいと考えられる。


# 参照

- [5x Faster Spatial Join with this One Weird Trick](http://blog.cleverelephant.ca/2018/09/postgis-external-storage.html)

- [SIOS "OSSよろず" ブログ出張所:PostgreSQL の TOAST の仕組みと効果](http://sios-oss.blogspot.com/2013/09/postgresql-toast.html)
MendixのDBの中身を見てみると分かること

[こちら](https://qiita.com/baaaaa/items/fbf0510e3d148c8a1c07)の記事でMendixのDBの中身を直接見る方法を書きました。
実際にDBの中身を見てみると、いろいろ分かることがあります。

# 全てのEntityやAttributeがあるわけじゃない
非永続Entity（Non-Persistent Entitiy）やCalculate項目はDB上には存在しません。
![db-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/187387/89f281dc-46cf-f244-7729-59b658affe38.png)
![db-2-2.png](https://qiita-image-store.s3.amazonaws.com/0/187387/87e49659-7881-2841-d5ad-ceca4d0fb115.png)

そもそも

- 非永続Entityは一時的な用途に使うためのもの。メモリ上にのみ存在
- Calculate項目はRetriveされた時にMicroflowで計算される項目

なので、当然と言えば当然ではあります。

# 内部IDが払い出されている
DomainModelのEntityにはありませんでしたが、テーブルの方にはID列があり、ユニークな値を持っています。
![db-2-3.png](https://qiita-image-store.s3.amazonaws.com/0/187387/0290ec23-fb51-4eb9-05eb-102ef6c5b738.png)
このIDはオブジェクトを生成したタイミングでMendixによって採番されますが、その採番ルールは不明です。（なんとなく連番になっているように見えるが、その保証は無い）
従って、Mendixの内部DBのテーブルに対して外からSQL等でレコードを直接INSERTすることはできません。必ずMendixのロジックを介してレコードを生成する必要があります。

# Associationは関連テーブル
Associationは同名の関連テーブルになります。
![db-2-4.png](https://qiita-image-store.s3.amazonaws.com/0/187387/d1aa495f-7867-d4d1-cd5b-fe67a9e904c9.png)
![db-2-5.png](https://qiita-image-store.s3.amazonaws.com/0/187387/87a2c23b-d1e5-430f-8d5a-4da909c96911.png)

# 日時はUTC
[このドキュメント](https://docs.mendix.com/refguide/date-and-time-handling)に書いてあるように、Date and time型のAttributeはUTCとして格納されます。
> The platform stores all dates in the UTC time zone.

![db-2-6.png](https://qiita-image-store.s3.amazonaws.com/0/187387/6aafc8ce-e27e-7333-069a-64f67d0aeaaa.png)
![db-2-7.png](https://qiita-image-store.s3.amazonaws.com/0/187387/a439f074-d791-2004-ef71-99ca0a9ea63b.png)

# 継承しているEntityはどうなっているか
DomainModelの特徴の一つである継承はRDBではどのように展開されているのでしょうか。
例えば以下のようにParentを継承した子Entityが2つあり、それぞれに1件ずつレコードを登録したとします。
![db-2-8.png](https://qiita-image-store.s3.amazonaws.com/0/187387/19eb6fcc-ca74-3a45-a3b1-ca1a4e11fc31.png)
親Entityのテーブルを見てみると、子Entityに登録したレコードがそれぞれ存在します。
また、「submetaobjectname」という列が存在します。どの子Entityのオブジェクトか、を示す列です。
![db-2-9.png](https://qiita-image-store.s3.amazonaws.com/0/187387/bc1b65ef-3698-33f7-20e6-62b0cf1f8837.png)
子Entityのテーブルを見てみると、親Entityのレコードと同じID値を持っていることが分かります。
レコードとしては分かれているけれども、オブジェクトとしては同一ということなのでしょう。
![db-2-10.png](https://qiita-image-store.s3.amazonaws.com/0/187387/d2d3ea8c-d11c-27b5-a3c7-cd82c86f2ef6.png)
![db-2-11.png](https://qiita-image-store.s3.amazonaws.com/0/187387/5ed56a68-b5ad-92e8-9732-26c2d635c009.png)

# 参考
- [MendixのDBの中身を直接見てみる](https://qiita.com/baaaaa/items/fbf0510e3d148c8a1c07)
Herokuでscheduling jobを動かす（PythonでAPSchedulerを使って）

# この記事について
Heroku上で、Scheduler Add-Onではなくcustomのschedulingでjobを動かすのに、
PythonでAPSchedulerを使ってみたので、詰まった点などをまとめる。

# Scheduling Jobについて
前提知識として、Herokuのscheduling jobの設定について

設定方法としては下記の2種類がある。

1. Herokuの[Scheduler Add-On](https://devcenter.heroku.com/articles/scheduler#scheduling-jobs)を使う
2. 自分で[clock process](https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes#custom-clock-processes)を実装する

1.２.の違いは、

1. ある程度決まり切った間隔のschedulingなら使える（毎日、毎時、10分毎など）
2. 1.より複雑なschedulingをする場合（月、水、金とか、毎２時間毎など）

今回自分は細かい設定をしたかったので、2.で設定した。

# PythonのAPSchedulerの実装
pipでのinstallなどは、[User Guide](https://apscheduler.readthedocs.io/en/v3.5.3/userguide.html)や
Herokuの[ヘルプページ](https://devcenter.heroku.com/articles/clock-processes-python)に載っているのでここでは省略。

scheduling jobの呼び出しは2種類あって、

1. add_job()を使う
2. scheduled_job()を使う

scheduled_job()の実装方法は上記のHerokuのヘルプページに載っているのだけど、
scheduled_job()を書いてから、そのすぐ下にschedulingしたいタスクを書く記法のよう。

私はadd_job()の方を使って、さらに別のpyファイルに書いてあるモジュールを呼び出すようにした。
そのときの記法としては下の感じ
（別のpyファイルをmysample.py、schedulingしたいタスクをmytask()とする）。

```
import os,mysample

from apscheduler.schedulers.blocking import BlockingScheduler

if __name__ == '__main__':
    sched.add_job(mysample.mytask,'cron', day_of_week='mon', hour='1-3', minute='5')
    sched.start()
```

ここで最初詰まったのが、add_jobに渡すのはモジュールそのものであるという点。
どういうことかというと、add_jobで下記のように渡すと、モジュールの実行結果が渡ってしまい、
全然scheduling jobにならない（herokuでprocessをscaleした瞬間に実行されてしまう）。

```
...snip...
   sched.add_job(mysample.mytask(),...
```

上の実装で実行すると、Herokuのlogに下記のように出力される。

```
TypeError: func must be a callable or a textual reference to one
```

このエラーで調べていて、stackoverflowに[同じ質問](https://stackoverflow.com/questions/40700406/apscheduler-runs-once-then-throws-typeerror)が載っていたのでそれで分かった。

もしmytask()に引数を渡す必要があったら、
add_job()の引数にargs, kwargsというのがあるのでそれを使えばOKのよう。

# cronのパラメーターについて
Herokuの[ヘルプページ](https://devcenter.heroku.com/articles/clock-processes-python)を見れば、schedulingのtriggerとして、
'interval'と'cron'があるのが分かるが、
cronのパラメーターにどういう値を設定出来るかが分からなくてちょっと探した。

下記ページに書いてあった。
[apscheduler.triggers.cron](https://apscheduler.readthedocs.io/en/3.0/modules/triggers/cron.html)

細かく設定できるのが分かる。

# scheduling jobを動かす
実際に動かすときは、Procfileも下記のように変える。

```
clock: python myschedulejob.py
```

Herokuにdeploy出来たら、下記を実行する。

```
$ heroku ps:scale clock=1
```
謎のプロセスCompatTelRunner.exeを停止させる。

リモートデスクトップを使っていると、出現条件が定かではないけれど
CompatTelRunnerというプロセスの読み書きでディスク使用率が100%になってしまう。
（ユーザエクスペリエンスのなんとやらに同意していないはずなのに）

タスクを無効にするか削除すると、一時的に消える。
```schtasks /change /tn “¥Microsoft¥Windows¥Application Experience¥Microsoft Compatibility Appraiser” /disable
```

しかし、また復活するので定期的に消している。
削除とか怖いのでやっていない。

##追記 2021/2/28
HDDの寿命だった可能性あり。SSDに換装したら直った。
AWS S3のアクセス拒否の解決方法

AWS S3のファイルアップロードで「アクセス拒否」され、
ようやく解決できたので残しておきます！

##エラーメッセージ
S３でバケットを作成し、jpgファイルがアップロード完了している状態で、
「公開する」ボタンをクリックすると、下記のエラーが表示されます！
<img width="976" alt="error.png" src="https://qiita-image-store.s3.amazonaws.com/0/261748/ba631365-fabf-5e69-531f-b4032e4583f9.png">

この「アクセス拒否」エラーにはまってしまい、
１週間くらいあれこれVPCやらポリシーやら色々いじってみたものの
一向に解決せずでした。。。

##解決方法
単純にアクセス権限のACLのチェックボックスのチェックを外すだけでした！

<img width="1086" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/261748/65017c44-a017-3cbf-805b-042357bda95f.png">


【手順】
1.S３　＞　バケット名　をクリック
2.「アクセス権限」タブをクリック
３.「パブリックアクセス設定」内の真ん中の四角の枠の右上の「編集」をクリック
４.ACLの下記の項目のチェックを外す
>□新規のパブリック ACL と、パブリックオブジェクトのアップロードをブロックする (推奨) 
>□パブリック ACL を通じて付与されたパブリックアクセスを削除する (推奨)

５.保存
あとは、画面の指示に従って進めていくだけです！

再度、アップロードした画像を「公開する」ボタンを押すと、
「成功」って表示されました♩

##まとめ

解決方法は以外と簡単でした！
初心者の私だけかもしれませんが、備忘録として残しておきますー。
あ〜〜〜〜〜すっきりしたぁ♩
【簡単】vue-click-outsideライブラリを使ってみた

[watsuyo](https://twitter.com/watsuyo_2)と申します。
年末年始に作っていたToDoアプリでめっちゃ役に立ったライブラリを紹介します。

## 「vue-click-outside」を使おうと思った理由

- 作成のToDoアプリでモーダルウィンドウ使用し、それを**閉じる動作**が欲しかった
- 「☓」で閉じる動作だと**誤タップや誤クリックを招く**から

実際に「vue-click-outside」を使用した[アプリはこちら](https://todoapp-b6529.firebaseapp.com/)です。

<img width="427" alt="スクリーンショット 2019-01-06 16.00.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/253605/fb2f6a79-506f-8108-b336-2461fbea5a0d.png">


この画像でいうと黒い部分をタップorクリックするとモーダルが閉じるようになります。

## 実際のコード

ToDo.vue

```vuejs
<template>
---中略---
  <div class="modal" :class="{'is-active':isActive}"> //isActiveがtrueならモーダルを表示
    <div v-click-outside="close" @click="close" class="modal-background"></div>
    <div class="modal-content">
      <div class="box">
        <div class="content has-text-centered">
          <div class="control">
            <form class="field is-grouped" @submit.prevent="Add">
              <div class="control is-expanded">
                <input class="input is-rounded" type="text" v-model="newItem" placeholder="Title">
                <textarea class="textarea" type="text" v-model="newContent" style="white-space: pre;" placeholder="Todo"></textarea>
                <input class="button is-info is-rounded" type="submit" value="Add">
              </div>
            </form>
          </div>
          <span>&nbsp;</span>
        </div>
      </div>
    </div>
  </div>
---中略---
</template>
<script>
import ClickOutside from 'vue-click-outside' //import
  export default {
    name: 'ToDo',
    newItem: "",
    props: ["user"],
    data () {
      return {
        todos: [],
        components: [],
        isActive: false //初期画面ではモーダルを表示しないためfalse
      }
    },
---中略---
    methods: {
      close: function () {
        ---中略---
        this.isActive = !this.isActive
      }
    },
    mounted () { 
      this.popupItem = this.$el //popupItemを使用して、イベントの外側をクリックしないようにする
    },
    directives: { //directivesオプションを使用することにより、ローカルディレクティブに登録されるため、機能を使うことができる
      ClickOutside 
    }
---中略---
</script>
```

上記ファイルのscript内で**vue-click-outside**をimportすることによって、**v-click-outside="close"**は、モーダルウィンドウの範囲外をクリックすることでモーダルを閉じる機能を与えることができます。

methodsオプション内にある、close関数では初期dataでfalseと設定した**isActive**を**!isActive**に、すなわちtrueに変更することでモーダルを閉じる処理が完成します。

## 感想
実現したい機能がすでにライブラリ化しているとめちゃくちゃ楽なんだなと身をもって実感しました。

自分も近い将来、ライブラリを作ってみたい…！


[Twitter](https://twitter.com/watsuyo_2)、コメントへのフィードバックお待ちしています！！
TALK LOUD because your the 0.000001%  in the world 

TALK LOUD because your the 0.000001%  in the world

# たとえば技術ブログソーシャルサービスであまり大声を出すと人に迷惑がかかると思うかもしれない

- For example in one social service talk loud is bother to other people? maybe it is true.
- E.g Qiita japanese engineering share wisdom and messaging service

![image](https://user-images.githubusercontent.com/13635059/50733701-c1e18780-11d5-11e9-84a2-db1e643f024c.png)

# しかしQiitaの中であなたはほんのごく0.1%以下である

- But actually your articles are part of Qiita is lower than 0.1% probably

![image](https://user-images.githubusercontent.com/13635059/50733711-e178b000-11d5-11e9-92ff-388b40bdff98.png)

# Qiita でさえ 世界から見ればほんのごく 0.00001% 未満である

- Yes and Qiita  is lower than 0.000001% in this world if you usually use Qiita then Qiita is over 60% in the world on your sense but is illusion.  
- あなたがふだんQiitaを使っているから、それが実感で大きく見えているだけだ

![image](https://user-images.githubusercontent.com/13635059/50733708-d4f45780-11d5-11e9-9638-c759898fd87f.png)

# どんなに大声でメッセージを叫んでも

- If you talk loud louder loudest but that voice is a small small part of cosmo so you better to more than talk loud? is my opinion of small voice in the world.
- しょせん世界のごくごく チリのような声でしかないのだから
- 逆にもう少し大声でラウドに叫んでみても良いんじゃないかと思う

![image](https://user-images.githubusercontent.com/13635059/50733723-2dc3f000-11d6-11e9-97fd-31c47734d209.png)

---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues

https://github.com/YumaInaura/YumaInaura/issues/280








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
cloud9でpipが使えなくなった話 (pip: command not found)

## pipの場所が/usr/local/bin/pip に変わってる可能性があるよ！インストールし直そう！



### 詳細
cloud9でセレニウムを使おうと思って pip install selenium 打ったら、

```
You are using pip version 9.0.3, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```

って言われたので素直に pip install --upgrade pip 打ったら、それ以降pipコマンドを打つとすべて以下エラーに。

```
pip: command not found
```

###原因

原因は、pipの場所が変わっていることでした。

```
$ which pip
/usr/local/bin/pip 
```

pipの場所が/usr/bin/pipから/usr/local/bin/pip に変わってしまったため、pipが認識されなくなってました。


### 解決方法
以下コマンドを順番にうってく。

```
/usr/local/bin/pip uninstall pip  
yum remove python-pip  
yum install python-pip 
```

- 普通のlinuxではyumではなく、apt-getでいいはず。: apt-get remove python-pip  
- sudo つけたほうがいいかも: sudo yum remove python-pip  



いや、おまえがpip install --upgrade pip打てっていったんじゃんけ！！
vSphere Web Client を使ってVMware Toolsの情報一覧を取得する方法

VMware Toolsのバージョンが最新になっているか一括で確かめる方法を探していたとき
日本語資料でUIを使った一括取得がなかったので。


####方法

1. vSphere Web Clientに接続(6.0, 6.5のUIで試しました）
2. ホストおよびクラスタを開いて左の列でvCenterを選択しておく（vCenter配下の全部の仮想マシンをまとめてチェックしたい時）
3. 真ん中の列で仮想マシンタブを開く。仮想マシンの一覧と、起動ステータスなどが表になって出てくる。仮想マシン一覧へのたどり着き方がバージョンによって違うのでスクショを２パターン。
１枚目：vCenter 6.0 
![S__63561756.jpg](https://qiita-image-store.s3.amazonaws.com/0/109034/22255d89-04e6-6439-2c7d-f8fe59b07c1d.jpeg)
２枚目：vCenter 6.5
![S__63561757.jpg](https://qiita-image-store.s3.amazonaws.com/0/109034/b9a732b9-0b3b-ad86-7333-f003b8732ced.jpeg)

4. 表のタイトル行で右クリックし、「列の表示/非表示」
5. 表の表示項目で「VMware Tools バージョン ステータス」があるので選んでOK
 <img width="163" alt="スクリーンショット 2019-01-06 16.35.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/109034/758bff6b-3231-6aa2-2b88-62173d6cfd6a.png">
 


以上です。



####参考
#####Power CLIを使う方法

公式ブログ
[VM Tools and Virtual Hardware Versions - VMware PowerCLI Blog - VMware Blogs](https://blogs.vmware.com/PowerCLI/2011/11/vm-tools-and-virtual-hardware-versions.html)

Qiita投稿
[vSphere PowerCLIでVMware Toolsのバージョンを一覧取得する方法 - Qiita](https://qiita.com/khayama/items/f3eac763a185a51563c2)

#####UIを使う方法

公式ブログ
[Tracking VM Tools and Virtual Hardware Versions - VMware vSphere Blog](https://blogs.vmware.com/vsphere/2011/11/tracking-vm-tools-and-virtual-hardware-versions.html)
さくらレンタルサーバにSubversionをインストールしてWindowsからTortoiseSVNを使って接続する

#Subversionのインストール
TeraTermでさくらレンタルサーバに接続する。

```
$ mkdir $HOME/src/
$ mkdir $HOME/src/subversion/
$ cd $HOME/src/subversion/
$ wget http://subversion.tigris.org/downloads/subversion-1.6.15.tar.gz
$ wget http://subversion.tigris.org/downloads/subversion-deps-1.6.15.tar.gz
$ tar xzf subversion-1.6.15.tar.gz
$ tar xzf subversion-deps-1.6.15.tar.gz
$ cd subversion-1.6.15
$ ./configure --prefix=$HOME/local
$ gmake prefix=$HOME/local
$ gmake prefix=$HOME/local install
```

#リポジトリを作る

```
$ mkdir $HOME/svn/
$ cd $HOME/svn/
$ $HOME/local/bin/svnadmin create myrepos
```

#TortoiseSVNでエラーが出ないように設定
これをしないとリポジトリブラウザを起動したときに「to better debug ssh connection problems remove the q option from 'ssh' in the tunnels」なんてエラーが出てしまう。原因は割愛。

```
$ mkdir $HOME/bin
$ ln -s $HOME/local/bin/svnserve $HOME/bin/svnserve
```

#TortoiseSVNの設定
[設定][ネットワーク]のSSHクライアントを編集

```
C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe -l さくらレンタルサーバアカウント -pw さくらレンタルサーバパスワード(FTPと同じ)
```

あとはチェックアウトなり、コミットなりなんなりと。
[エラーメッセージ] can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundException)

#　事象
1　Rubyのバージョンを2.5.1に

```sh

$ rbenv install 2.5.3
$ rbenv local 2.5.3
```

2　新しいバージョンに即したbundlerをinstall

```sh
$ rbenv exec gem install bundler
```

3　bundle install

```sh
$ bundle install
Traceback (most recent call last):
	2: from /Users/<user名>/.rbenv/versions/2.5.3/bin/bundle:23:in `<main>'
	1: from /Users/<user名>/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/Users/<user名>/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```

# 原因
Gemfile.lockに指定されているbundlerのバージョンと、bundlerのバージョンが異なっている


```Gemfile.lock
<省略>
BUNDLED WITH
   1.17.3
```

```sh
$ bundler -v
Bundler version 2.0.1
```

# 対処法
bundlerのバージョンをGemfile.lockのものと合わせる

```sh
$ gem uninstall bundler -v 2.0.1
$ gem install bundler -v 1.17.3
```
Visual Studio 2017でTcl/Tk 8.6.9をコンパイルする

# はじめに
Tkを使うとクロスプラットフォームなGUIアプリケーションを簡単に作ることができます。Tclの人気はいまひとつですが，Tkはさまざまな言語のバインディングがあり，いい意味で枯れたGUIツールキットとして広く使われています。

Tkの[tutorial](https://tkdocs.com/tutorial/index.html)には，同じアプリケーションがTk，RubyTk, Tkinterで書かれています。PythonにはTkinterがついてくるのですが，wishやtclshは見当たらないので，インストールすることにしました。

Tcl/TkはActiveTclのバイナリやパッケージ管理システムのものをインストールすることが多いと思いますが，Windows 10でソースからコンパイルしてみることにしました。Tkのコンパイルにつまづいたので，やりかたをまとめておきます。

## 追記 2019/6/22
* パスの誤りなどを修正しました。
* Visual Studio 2019でやってみました。
* x64_x86 Cross Tools Command Prompt for VS 2019でx86バイナリの作成ができました。

```cmd
C:\Users\takeshi\Downloads\destroot\bin>dumpbin /headers wish86t.exe | findstr machine
             14C machine (x86)
                   32 bit word machine
```

# Windows 10 SDK
Tcl-8.6.9は[How to Compile Tcl]のとおりにやればコンパイルが通ります。Tk-8.6.9のコンパイルが通るのは，Windows SDK 10.0.15063.0までです。TclとTkとでSDKのバージョンが違うとTkのリンクに失敗します。そこで，コンパイルに取り掛かる前にSDKを準備します。Tcl/Tk-8.6.9時点での情報です。それ以降のバージョンでは，古いSDKのインストールは不要かもしれません。

## インストール
Visual Studio Installerを起動します。インストーラ自身やインストールされているものの更新が始まるかもしれません。

* Visual Studio Community 2017の「変更」ボタンをクリックします。
* 「ワークロード」タブの「C++によるデスクトップ開発」にチェックを入れます。
* 「インストールの詳細」の「C++によるデスクトップ開発」から「Windows 10 SDK (10.0.15063.0)」にチェックを入れます。
* 「ダウンロードしながらインストールする」あるいは「全部ダウンロードしてからインストールする」を選択してクリックします。

## SDKの選択

スタートメニューから「Visual Studio 2017」を開いて「開発者用コマンドプロンプト」を実行します。`varsall.bat`のあるディレクトリに移動します。

```cmd
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
```
[Building with Visual Studio 2017](https://wiki.tcl-lang.org/page/Building+with+Visual+Studio+2017)にある通り，バッチ`varsall`を実行します。

```cmd
vcvarsall x64 10.0.15063.0 
```

x86用のバイナリを作るときはx64の代わりにx86とします。

# Tcl/Tkのコンパイル

* tcl869-src.zipをダウンロードして展開します。
* インストール先`INSTALLDIR`を決めます。なければ作成します。私は`AppData\Local\Programs\Tcl`にしました。
* `tcl869-src\tcl8.6.9\win`に移動してコンパイル・インストールします。

```cmd
> nmake -f makefile.vc INSTALLDIR=path_to_your_install_dir
> nmake -f makefile.vc install INSTALLDIR=path_to_your_install_dir
```
* `tk869-src\tk869\win`に移動してコンパイルします。`TCLDIR`はTclのソースを指定します。上の例では`tcl869-src\tcl8.6.9`です。
 
```cmd
nmake -f makefile.vc INSTALLDIR=path_to_your_install_dir TCLDIR=path_to_tcl_source
nmake -f makefile.vc install INSTALLDIR=path_to_your_install_dir TCLDIR=path_to_tcl_source
```

* 必要に応じて`tclsh86t.exe`を`tclsh.exe`に`wish86t.exe`を`wish.exe`に改名します。
* `TCLDIR\bin`にパスを通しておきます。

ソースからのコンパイルは気持ちがいい。
前澤自動化スクリプトを使ってみた

# 元ネタはこちら

* 前澤友作社長から100万円を貰うためにTwitterのフォローとリツイートを自動化する
* https://qiita.com/relu/items/d37f746c85c6494c3799

# Macで失敗

* seleniumで途中まで動いたがdriver errorで死んだ

# Windows Python3系で失敗

* pip install gimeiでcp932エラー
* cmdの文字コードを変えてもダメ

# Windows Python2系で成功

* gimeiも入った
* lxmlで検索しているところを微修正
  * .pathとtypoしている箇所を.xpathに (auth_codeの箇所)
  * 検索用の文字列を実際に合わせて変更 Sign up -> 登録する
* 1周完了したのを確認したので、Windowsのタスクスケジューラでbatを定期実行

# 4回成功したのち、エラーが発生するようになる

* 成功していたときと表示が変わるので、HTML内の検索もうまくいかずエラー

# Twitterに表示された画面

```
twitter Options 
We've temporarily limited some of your account features

河原 果樹 
@xcA4T2mV5kBq5UT
What happened?

Your account appears to have exhibited unusual behavior violating the Twitter Rules. 
You can use all of Twitter's features again once you complete the following steps to confirm you are the account owner.

What next?
For full access, you must:
Pass a Google reCAPTCHA challenge
When you tap 'Start', Google may collect and use information about you, 
your device, and browser. View Google's Privacy Policy.
```

* reCAPTCHAやって人間であることを示せとのこと
* 面倒そうなのでここで止める

# プロキシー設定はしているはずだが・・・

```python
#proxy_server='http://159.89.200.187:8080'
proxy_server='http://139.59.80.140:8000'
options.add_argument('--proxy-server=%s' % proxy_server)
```

# 学び

* 今までソシャゲのBotとか作ってこなかったが、今回のでselenium, lxml等に少し慣れた
protocol buffers をGolangで使う

protocol buffersって名前は聞くけど、今まで使ったことなかったので、とりあえず触ってみた。
「protocol buffersでシリアライズしたデータをTCPで送信し、受信側はそれをjsonに変換して標準出力にアウトプットするプログラム」を作ってみることにする。

## 1. データ定義
とりあえず動かしてみるのが目的で、データは何でも良いので、[tutorial](https://developers.google.com/protocol-buffers/docs/gotutorial)からコピペしてきたものを使う。

```protobuf:addressbook.proto
syntax = "proto3";
package pb;

import "google/protobuf/timestamp.proto";

message Person {
    string name = 1;
    int32 id = 2;  // Unique ID number for this person.
    string email = 3;

    enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }

    message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
    }

    repeated PhoneNumber phones = 4;

    google.protobuf.Timestamp last_updated = 5;
}

// Our address book file is just one of these.
message AddressBook {
    repeated Person people = 1;
}
```

## 2. コンパイル
```shell
protoc --go_out=./ ./addressbook.proto
```
成功するとgoのソースが作られる。

## 3. tcpclientを書く

pbというのが、生成されたgoファイルのあるパッケージ
import文は省略

```golang

package main

func main() {

	p := pb.Person{
		Id:    1234,
		Name:  "John Doe",
		Email: "jdoe@example.com",
		Phones: []*pb.Person_PhoneNumber{
			{Number: "555-4321", Type: pb.Person_HOME},
		},
	}
	book := &pb.AddressBook{}
	book.People = append(book.People, &p)
	out, err := proto.Marshal(book)
	if err != nil {
		log.Fatal("Failed to encode\n")
	}

	conn, err := net.Dial("tcp", "localhost:8080")
	if err != nil {
		panic(err)
	}
	conn.Write(out)
}
```

## 4. tcpserverを書く

pbというのが、生成されたgoファイルのあるパッケージ
import文は省略
jsonとprotocol buffersの変換はjsonpbというパッケージが提供されている。
https://godoc.org/github.com/golang/protobuf/jsonpb

```golang

package main

func main() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		panic(err)
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			panic(err)
		}
		go func() {
			var buf bytes.Buffer
			io.Copy(&buf, conn)
			book := &pb.AddressBook{}
			if err := proto.Unmarshal(buf.Bytes(), book); err != nil {
				log.Fatalln("Failed to parse address book:", err)
			}
			addressBookMarshaler := jsonpb.Marshaler{Indent: "  "}
			addressBookMarshaler.Marshal(os.Stdout, book)
		}()
	}
}
```

## 5. 実行
サーバ側の標準出力で下記が出力されることを確認。

```shell
{
  "people": [
    {
      "name": "John Doe",
      "id": 1234,
      "email": "jdoe@example.com",
      "phones": [
        {
          "number": "555-4321",
          "type": "HOME"
        }
      ]
    }
  ]
}
```
HerokuのMailgun Add-ons 無料版を使ってみた

# この記事について
Herokuで[Mailgun Add-ons](https://elements.heroku.com/addons/mailgun)を使ってみたので、使用感をまとめる。

# Add-onsの設定
前提知識としてAdd-onsの導入方法について

ログイン → dashboardページ → Add-onsを使いたいAppを選択 → 
Overviewタブ（デフォルトで選択されているはず）の左上の枠がAdd-onsでそこの"Configure Add-ons" → 
真ん中辺の"Find more Add-ons" → 使いたいAdd-onsを選択 → 
loginしていれば右上に"Install Add-on名"ボタンがあるのでそれを押す

//最初インストール方法が分からず、Mailgunのサイトに行って、
//Mailgunのアカウントを作ってしまった...
//Add-onsなので個別にアカウント作る必要はなし

# Mailgun Add-onsについて
Appの通知機能として、メールで通知してみようと思い、Mailgunを使うことにした。
後で知ったけど、メール通知Add-onsとしてはSendGridの方が有名みたい
（結局いまはSendGridを使っている）。

Mailgun Add-onsではまずSandboxドメイン（テスト送信用ドメイン）が付与される。
自分の持っているドメインを設定することも出来るけど、Sandboxドメインでもメール送信できる。
この2つの違いは、
Sandboxドメインで送信する場合は、**前もって認証したメールアドレスにしかメールが送れない。**
つまり、まず送りたい先を決めて、そのアドレスに認証メールを送って、
MailgunのSandboxドメインからのメール受信を認証してもらう必要がある。
この制限はメールアドレスを間違えて他の人にメールを送っちゃった！
みたいなことを防止できるので良いなと思った
（Sandboxドメインからのspam防止がメインの目的だろうけど）。
個人が持っているドメインを設定すれば、上記の制限はなくなる。

# Mailgun Add-onsを使ってみて
私の作ったAppでは、1時間を15分ずつに区切り、その15分の中でランダムな時間に1回、
Appが動作し問題なければその結果を個人アカウントに通知する設定にした。
最初は良かったものの、だんだんメールの配送が遅延していって、
1日経つ頃には、約9時間遅れで届くようになって通知としては全く使えなかった...
配送に失敗することはなかったけれど、無料版とはいえ、
1時間にたかだか4回メール送る程度の送信量で遅延するとは思わなかった。
Add-onsとしては送信のための[ヘルプページ](https://documentation.mailgun.com/en/latest/quickstart-sending.html#how-to-start-sending-email)も分かりやすかったりして良かったので少し残念。

遅延した理由としては、下記のようなことが考えられる。

1. 無料版だから（無料版ユーザーは多いので当然メールキューが貯まる可能性が高い）
2. 似たようなメールを送っていたので、Mailgun側でspam判定して遅延させていた

お金を払えば遅延は解消するだろうけど、無料版の上は19$/月なので、遊びで使うにはちょっと高いかな...
NativeなJavaScriptでFetch APIを利用しAjaxを行う

昨今、jQueryが下火になって久しい。
そこでjQueryのajax関数を使わずNativeなJavaScriptでどのようにAjaxを行うのかを調べたので備忘録として記述していく。

## TL;DR;

フロントエンドの規模が小さく、古いブラウザのサポートを気にする必要がないプロジェクトでは今後はFetchAPIを利用していったほうが良さそう。

## 従来のNativeなAjax

### XMLHttpRequest

過去のやり方であればXMLHttpRequestを使う方法も用意されていた。
しかし、これはjQueryのAjaxに慣れてしまった人には違和感も覚える人もいるだろう。  

```javascript
var request = new XMLHttpRequest();
request.open('post', '/foobar', true);
request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
request.onload = function (event) {
    if (request.readyState === 4) {
        if (request.status === 200) {
            console.log('OK');
        } else {
            console.log('Bad');
        }
    }
};
request.onerror = function (event) {
  console.log('Error Occurred');
};
request.send('foo=1&bar=2');
```

### Ajax

jQueryのAjaxなら以下のような書き方になる。
XMLHttpRequestと比較すると、 `どこに、どのようにアクセスし、その結果どういう処理をするのか` という一連の流れをメソッドチェーンで追えるのでわかりやすいのではないかと個人的には思っている。
XMLHttpRequestは特に `どのようにアクセスする` という記述が散っているので読み辛い。

```javascript
$.ajax({
    url: '/foobar',
    type: 'POST',
    data: {
        'foo': 1,
        'bar': 2,
    }
})
.done(function (data, status, xhr) {
    if (xhr.status == 200) {
        console.log('OK');
    } else {
        console.log('Bad');
    }
})
.fail(function (err) {
    console.log('Error Occurred');
})
```

## Fetch API 

そこでFetchAPI。  
最近のブラウザなら実装されている（当然ながら古いブラウザ対応したいなPolyfillとかで対応してあげる必要あり
記述もほぼAjaxと同様に行えてjQueryから移行してくる人も理解しやすいのではないだろうか。

```javascript
fetch('/foobar', {
  method: 'POST'
  body: 'foo=1&bar=2',
  headers: new Headers({'Content-type' : 'application/x-www-form-urlencoded' }),
})
.then(function (response) {
    if (response.status === 200) {
      console.log('OK');
    } else {
      console.log('Bad');
    }
})
.catch(function (err) {
    console.log('Error Occurred');
});
```

### 具体例

RestfulなAPIを叩いて帰ってきたレスポンスのjsonを扱うような具体的な実装は以下のような感じになる。

```javascript
fetch('/foobar', {
    method: 'POST'
    body: 'foo=1&bar=2',
    headers: new Headers({'Content-type' : 'application/x-www-form-urlencoded' }),
    // リクエストパラメータをJSON形式で渡すならこんな書き方もできる
    // body: JSON.stringfy({
    //     "foo": 1,
    //     "bar": 2,
    // }),
    // headers: new Headers({'Content-type' : 'application/json' }),
})
.then(function (response) {
    if (response.status !== 200) {
      throw 'なにかエラーログ的なもの'; // catchに飛んでログが吐かれる
    }
    return response.json(); // promiseが帰ってくるので後続のthenで処理する
})
.then(function(objs)) {
    // objsにはresponse.bodyにあるjson stringがパースされたものが入っている
    // do something ...
}
.catch(function (err) {
    console.log(err);
});
```


## 参考

* [MDN XMLHttpRequest](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest)
* [MDN FetchAPI](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API)
* [jQueryを使わない書き方 ajax, each, trigger, on/off, extend, deferred, animate, css編](https://mae.chab.in/archives/2821)
Python始めたい人にProcessingが便利な５つの理由

# はじめに

プログラミング初心者でも簡単に学べるJavaベースのツールとして有名なProcessingですが、Pythonを始めたい人にとっても、かなり便利なツールであることが分かったのでその理由をまとめました。

# Processingが便利な理由

### ❶環境構築が楽

もともとProcessingは、Javaをベースとした、ほんの少しのコードでビジュアル表現を可能にするツールです。そのため、インストールもかなり簡単になっています。今回は通常のProcessingインストール後に、PythonのIDEをインストールするだけです。

Processingのダウンロードはこちらから(Windows Macどちらも使えます)
[https://processing.org/download/](https://processing.org/download/)

Pythonモードのインストール(こちらのリンクが画像付きで分かりやすいです)
[https://pycarnival.com/processingpy1/](https://pycarnival.com/processingpy1/)

### ❷ビジュアライズが簡単
![processing2.gif](https://qiita-image-store.s3.amazonaws.com/0/197729/a8dcbd32-12f0-64a4-fdb7-c5f8628e2bfb.gif)

Pythonの基本的なループ処理、クラスの作り方を学ぶために、それぞれがどのような動きをするかビジュアライズできると便利ですが、Processingは描画に特化しているので繰り返しがどう処理に反映されるかをみるのに便利です。

### ❸キーマウス入力などの扱いが簡単
pythonでキー入力やマウス入力を扱うにはopencvを使うことが多いですが、
cv2.waitKeyは反応が悪かったり、マウスコールバックの概念をいきなり説明するのは大変です。

![processing1.gif](https://qiita-image-store.s3.amazonaws.com/0/197729/89010a13-b6b7-d6c4-d314-f35970aec214.gif)

ProcessingはkeyやmouseXなどの変数があらかじめ定義されており、draw関数の外で常に更新されているため、簡単です。


### ❹シェーダーも実行できる

JavaでもPythonでもProcessingであればデフォルトのインストールのままGLSLシェーダーを実行できます。
![processing_shader2.jpg](https://qiita-image-store.s3.amazonaws.com/0/197729/a4ec039d-a6e9-4237-d7fb-7755640649bf.jpeg)
こちら左がJavaで書いた時のGLSL実行の短いコード、右がPythonです。
ProcessingなしでやろうとするとPyOpenGLのインストールで環境によってエラーが出たり、
おまじないコードが多かったりするので、これはとてもシンプルです。

JavaとPythonで実行する場合の方法はこちらにまとめました。
[https://qiita.com/mizumasa/items/887c4e85c688a2b0d5f1](https://qiita.com/mizumasa/items/887c4e85c688a2b0d5f1)

### ❺サンプルが標準で入っている

Pythonモードをインストールすると、左上の"ファイル"からサンプルをいくつかみることができます。

<img width="1056" alt="スクリーンショット 2019-01-06 16.18.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/197729/90cbe3c5-a646-8a5e-e382-c464d17d8e9d.png">


# 残念なところ

プロトタイプツールなので求めすぎるのもあれですが、numpy, matplotlibなどは使えないため、本格的にPythonを使った開発を試そうと思うとやはり不十分です。

また、現状日本語のチュートリアルも少ないので、現実的にはPythonを使える人がPythonを教えるのに便利なツールかなとも思います。

ですが、Python特有のコードの書き方を学ぶために、グラフィック表示が簡単にできてアウトプットがやった感が分かりやすく、とにかく躓かないためのツールとしてはとても魅力的だなと思いました。


# まとめ

以上、もともとのProcessingの便利な点を挙げただけではありますが、
Pythonの苦手な部分を補ってくれており、将来的な数値解析や機械学習の勉強にPythonを使い始めたい人、Processingから入ってPythonを勉強したいと思う人、両方にProcessingをオススメしたいと思います。
Payjpで決済をするとサーバーが落ちる

# はじめに
最近、仕事でpayjpを使い、決済を実装していたら起こった事象を紹介します。
# Payjpで決済を実装
こちらを参考にpayjpを実装
https://payjp.hatenablog.com/entry/2017/11/21/191916

payjpのgemをインストール

```ruby
gem 'payjp'
```
HTMLを以下のように設定

```html
<form action="/pay" method="post">
  <!-- 注文情報などの情報ここから -->
    :
  <!-- 注文情報などの情報ここまで -->
  <script src="https://checkout.pay.jp/" class="payjp-button" data-key="YOUR_PUBLIC_KEY"></script>
</form>
```

payjpのボタンが表示され、モーダルも表示された。これで決済が実装できた！すごい！
![payjp.png](https://qiita-image-store.s3.amazonaws.com/0/290687/bed7bb2c-a6db-0fe0-507b-397989f6868c.png)
![payjp2.png](https://qiita-image-store.s3.amazonaws.com/0/290687/cd012a45-9fa1-f0d4-fcad-2e257ad0b19f.png)

と思いきや

# なぜかサーバーが落ちる
カード情報を入力し、カードで支払うをクリックすると、
![payjp3.png](https://qiita-image-store.s3.amazonaws.com/0/290687/46d3b7e9-2ec3-02eb-2bed-711178101486.png)
このサイトにアクセスできません。
となる。

プロンプトを確認してみると、サーバーがなぜか落ちてる。

# 解決
その後、数日原因を調査してみるもわからず。byebugでデバッグしてみても、わからない。

自分はWindowsのコマンドプロンプトでrails sしてサーバーを動かしていたのですが、これがなぜかLinuxのターミナルで動かすと上手くいくことが判明しました。

なので、以下の記事を参考にWindows環境にUbuntuを入れて、そこでrails sし、もう一度決済すると、できました。

[Windows 10でLinuxプログラムを利用可能にするWSLをインストールする](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)

誰か原因知っている人いれば教えてください・・・。

# まとめ
railsで開発している時はWindowsのコマンドプロンプトでやらない方が良い。
数日無駄にしました。

ちなみに、同様の決済サービスであるOmise、Stripeでも同様の操作をしてみました。
OmiseではPayjpと同様に決済をするとサーバーが落ちました。
しかし、Stripeでは決済をしてもサーバーが落ちませんでした。

全く原因がわかりません。。。
Mac初期化時にやること

# What is this?
初期化時に行うことのメモ。

# アプリケーションインストールに関する方針
基本 Homebrew で導入。brew-cask は使わない。
homebrew にないものは AppStore か webのインストーラから（公式が推奨する方法で）適宜。
node は brew で nodebrew を入れる。


# 前準備

必要なデータを DropBox に移す


# 初期化
再起動時にcmd-Rを押し続ける。ディスクユーティリティで初期化。OSインストール。
参考）https://support.apple.com/ja-jp/HT204904

# 基本設定

## System Preferences
 - Dock: 位置を左に、自動で隠す設定に
 - Keyboard: Keyboard-Modifier Keys...からCtrlの位置をAの隣に、Textにメールアドレスの省略を登録、input source にJapaneseを追加（ctrl+shift+;/jで切り替えてます）
 - Trackpad: Tap to clickを追加
 - Sharing Computer: Name をいい感じに変更
 - Users & Groups: Login OptionsでAutomatic loginを設定
 - Accessibility: Mouse&Trackpad の Trackpad Options で3本指ドラッグを有効に（なぜこれデフォルトじゃないの？）

## その他
- Dockを整理 （Finder以外消す）
- Launchpad を整理（Safari, App Store以外を一つにまとめる）
- App StoreからUpdatesがあれば更新
- Finder sidebar等の設定、

# アプリインストール
- Chromeをインストール
- Dropboxをインストール
- VS Codeをインストール
- Spectacleをインストール（ https://www.spectacleapp.com/ ）（アプリはできるだけ入れたくないので、この機能はapple公式で作ってほしい所）

# Homebrew
https://brew.sh/ を見る（Command Line Tools も同時にはいるね）
とりあえず絶対使うもの
`brew install vim zsh git python nodebrew`

# ターミナルとディレクトリ
`sudo vim /etc/shells`でbrewのzshを追記
`chsh -s /usr/local/bin/zsh`でデフォルトのシェルに設定
`vim ~/.zshrc`を好みの設定にする


# git 設定

```shell
brew install git
```
参考) https://qiita.com/peccul/items/90dd469e2f72babbc106


# node環境

```shell
nodebrew install stable
nodebrew use stable
nodebrew setup
npm update -g npm
```
Oracleブロンズを目指して　結合①

#結合
複数の表の異なる行を1行として表示することができる。

#結合の種類
 - 内部結合
 - 外部結合
 - クロス結合

##内部結合
結合条件と一致する行のみを結果として返す。
###ON句による内部結合

```構文
SELECT 列1, 列2, … FROM 表1 JOIN 表2 ON 表1.外部キー = 表2.主キー
```
- **ON句に結合条件を記載する。**
- **あいまいな列には表接頭辞を修飾する。**

###NATURAL JOINによる内部結合

```構文
SELECT 列1, 列2, … FROM 表1 NATURAL JOIN 表2
```

- **2つの表で名前とデータ型が一致している列を結合列にする。**
- **結合条件は等価結合となる**
- **結合列は表名を修飾してはいけない**
- **同じ名前の列が複数存在すると、それらすべてが結合に使用される。**
 - **意図しない結合が行われる可能性がある。**

###UING句による自然結合

```構文
SELECT 列1, 列2, … FROM 表1 JOIN 表2 USING(表1、表2に共通する列)
```

- **名前が同じでデータ型が違う列の場合はUSING句を使用する。**
- **同じ名前、同じデータ型の列が複数あるが、特定の列のみを結合列として使用する。**


###NATURAL JOIN と USING の使い分け
- **NATURAL JOIN は2つの表で同じ名前とデータ型を持つすべての列に基づく等価結合を行うときに使用する**
- **名前が同じでデータ型が違う列の場合はUSING句を使用する。**


###NATURAL JOIN　と　USINGの注意
- **NATURAL JOIN　USING　のどちらも結合列に対して表接頭辞をしようしてはいけない(エラーになる)**
⇒双方の表に存在す列だからこそ自然結合に使用されているため
H8/3664ではじめるマイコン制御5 モータを一周だけ回してみる



![93046 - コピー.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/7cb69801-3ffb-1b93-73f0-a4b9599c26e0.jpeg)
次はステッピングモータの回転角度を制御します。
リセットを押すたび一周だけ回るプログラムを作ってみます。

```c:MoterAround.c

//反時計回りにモータをちょっきり一周させるプログラム
#include <stdio.h>

#define	BRR		(*((unsigned char *)0xFFA9))
#define	TMA		(*((unsigned char *)0xFFA6))

#define	PMR1	(*((unsigned char *)0xFFE0))
#define	PMR5	(*((unsigned char *)0xFFE1))

#define	PCR1	(*((unsigned char *)0xFFE4))
#define	PCR5	(*((unsigned char *)0xFFE8))
#define	PCR7	(*((unsigned char *)0xFFEA))
#define	PCR8	(*((unsigned char *)0xFFEB))

#define	PDR1	(*((unsigned char *)0xFFD4))
#define	PDR5	(*((unsigned char *)0xFFD8))
#define	PDR7	(*((unsigned char *)0xFFDA))
void wait();
void rot_L();


int i,cnt=1,cnt1=0;
int t1=0,t3=0,t4=0;
int t2=-1;
unsigned char Seg1,Seg10;//表示用変数
unsigned char rot;//1の位シフト用
unsigned char rot10;//10の位シフト用

main()
   {

	
	BRR=12;			//16MHZ時には１２を　デフォルトは７　ボーレート変更	
 	PMR1 = 0x00;			/*ポート１を汎用ＩＯに設定*/
 	PMR5 = 0x00;			/*ポート１を汎用ＩＯに設定*/

	TMA = 0x98 ; 

 	PCR1 = 0xff;	//アドレス　FFE4
    PCR5 = 0xff;	//FFE8
    PCR7 = 0x00;	
    PCR8 = 0xff;	//FFED		//00入力　　ff出力
    
    
    if(cnt==1){//初期化
		Seg1=0x01;Seg10=0x81;rot=0x01;rot10=0x81;cnt=0;
		}
		
		
    for (;;) {/* 無限ループ */
	    
		PDR1=Seg1;
		wait(4000);
		
		if(cnt1<485){ //モータによってこの値は変えなければならない　今回使用したモータは485パルスで一周する
			cnt1++;
			rot_L();
		}
    }
    return 0;
   }
 
 
void rot_L()//反時計回り用関数
{
  //4bit rot
		if(rot==0x80){
			Seg1=rot;
			rot=0x10;  //左へ1ビットシフト
		}
		else{
			Seg1=rot;
			rot=rot<<1;
		}
}

void wait(int n)
{
	int i;
 	for(i=0;i<n;i++);
}
```
以下の部分はモータ固有の値をとるためモータを変えれば変更が必要です。

```c

if(cnt1<485){ //モータによってこの値は変えなければならない　今回使用したモータは485パルスで一周する
			cnt1++;
			rot_L();
		}
```

さらに

```c
void rot_L()//反時計回り用関数
{
  //4bit rot
		if(rot==0x80){
			Seg1=rot;
			rot=0x10;  //左へ1ビットシフト
		}
		else{
			Seg1=rot;
			rot=rot<<1;
		}
}
```

反時計回りを行う部分を関数にしました。

次回[H8/3664ではじめるマイコン制御6](https://qiita.com/kiki0817/items/f9e8f588ec5d456eab0e)
Kotlinのwhen式が便利

## when式とは？
when式とは、javaやPHPにおけるswitch文を強化したようなものです。

## Javaのswitch文とKotlinのwhen式比較
### Java
```java
int number = 1;

switch (number) {
    case 1:
      System.out.println("one");
      break;
    case 2:
      System.out.println("two");
      break;
    case 3:
      System.out.println("three");
      break;
    default:
      System.out.println("unknown")
}
```
###Kotlin
```kotlin
val number = 1

when (number) {
    1 -> println("one")
    2 -> println("two")
    3 -> println("three")
    else -> {
        println("unknown")
    }
}
```

見ての通りKotlinの方がシンプルで書きやすいのがわかると思います。
また、いちいちbreak文を書かなくていいので楽なのがわかります。

## when式の説明
1. switch が　whenになる
2. cose: が -> になる
3. default　が　esleになる
4. break文を入れなくてよくなった
C++ アプリで flatbuffers でシリアライズされたメッセージを読み込む

スキーマでデータ構造を指定できて, ライブラリとしても組み込みやすく C++ と親和性のたかそうな flatbuffers を試します
 
https://google.github.io/flatbuffers/

## Cmake で自作アプリに取り込む

flatbuffers のライブラリ自体は, `add_subdirectory` で簡単に自作アプリに取り込めます.

```

# [flatbuffers]
set(FLATBUFFERS_BUILD_TESTS Off CACHE INTERNAL "" FORCE)
set(FLATBUFFERS_BUILD_FLATHASH Off CACHE INTERNAL "" FORCE)
set(FLATBUFFERS_INSTALL Off CACHE INTERNAL "" FORCE)

add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/flatbuffers)

...

target_link_libraries(app flatbuffers)

```

## C++ アプリに組み込む

サンプルは flatbuffers のコードを参考にしてみてください.

パースエラーが出る場合は, `error_` メンバ変数にエラーメッセージがあります.

パースがうまくいったら, parser.builder_.GetBufferPointer() にそのデータがありますので, flatc で背一斉されたクラスの `Get***` に渡せばメッセージが復元できます.


```
  // load FlatBuffer schema (.fbs) and JSON from disk
  std::string schemafile;
  std::string jsonfile;
  bool ok = flatbuffers::LoadFile("../schema/config.fbs", false, &schemafile) &&
            flatbuffers::LoadFile("../config.json", false, &jsonfile);
  if (!ok) {
    printf("couldn't load files!\n");
    return 1;
  }

  // parse schema first, so we can use it to parse the data after
  flatbuffers::Parser parser;
  const char *include_directories[] = { nullptr };
  ok = parser.Parse(schemafile.c_str(), include_directories) &&
       parser.Parse(jsonfile.c_str(), include_directories);
  if (!ok) {
    std::cerr << "Parse error: " << parser.error_ << std::endl;
    return 1;
  }

  const App::Config *config = App::GetConfig(parser.builder_.GetBufferPointer());
  std::cout << config->pos()->x() << ", " << config->pos()->y() << ", " << config->pos()->z() << std::endl;
```

## TODO

スキーマファイルを `.h` かなにかにして, 実行時にファイルから読まずに済むようにする

## 代用案 JSON + JSON schema 

テキストのデータが主流であったり, バイナリのデータが少なく base64 にエンコードしてもサイズ的に問題がないのであれば, JSON + JSON schema という手もあります.

TinyGLTF では nlohmann json.hpp と, それをベースにした schema validator を使っています.
 
https://github.com/syoyo/tinygltf/tree/master/examples/validator

ただし, データを直接 C++ のクラスや構造体に変換してくれるものは, Cereal などの別ライブラリを使うか, 自作する必要があります.
機械学習/ディープラーニング勉強としてやってきたこと -実践編-

前回の[機械学習/ディープラーニング勉強としてやってきたこと -読んだ本編-](https://qiita.com/shoji9x9/items/b6f4db9e612b5af3a3f4)の続きになります。

# 初めに（再掲）
2018年1月頃から機械学習/ディープラーニングの本を読み始め、6月頃からコードを書くようにしてきました。今振り返ると「これはいい本だった」「もっと先にこれをやればよかった」などの気付きがあるので、それを紹介します。[kaggle初心者の私が3ヶ月でソロゴールドを獲得した方法](https://www.rco.recruit.co.jp/career/engineer/blog/kaggle_by_novice_engineer/)のようにすぐに結果を出した！なんてことはなく、普通の社会人が休日だけ勉強した軌跡です。

# 対象読者（再掲）
これから機械学習/ディープラーニングを勉強しようという方

# Pythonの基本
まずPythonを学ぶ必要がありましたので以下のサイトを使い勉強しました。無料枠だけでも基本的なことは十分勉強できたと思います。

* [CODEPREP](https://codeprep.jp/featured)
    * 2018年9月末まで無料開放（その後閉鎖）とのことでしたが、無期限延長提供となった模様です
* [paiza](https://paiza.jp/)
    * paizaラーニングもやりましたが、それ以上にスキルチェックの問題をPythonで解きました。やはり課題があった方がやりがいも出ていいですね
* [numpy 100 exercises](http://www.labri.fr/perso/nrougier/teaching/numpy.100/)
    * 全てではないですが、これにも取り組みました。Python（Numpy）ならではの書き方を学ぶのに役立ちました

# ディープラーニング実践
* 社内の勉強会
    * Deep Learning基礎講座を受講した方が主催して下さった勉強会に参加し課題を解きました。MLP、CNN、RNNなどを勉強しました。ただ、この頃はGPU環境がなく辛かった覚えがあります
* [Deep Learning基礎講座](https://deeplearning.jp/lectures/dlb2018/)
    * これを所属企業向けにして頂いたものを2018年8月より月に一度受講しています。ここでGPU環境が手に入りました！嬉しくなって社内勉強会の課題に早速使っていました（VGG16のファインチューニングにより精度が上がって喜んでたような・・・）。こちらでnumpy、Tensorflow、k近傍法、MLP、AutoEncoder、CNN、Data Augumentation、RNNなど色々と学ぶことができ非常に有益でした。特に毎回の課題に取り組む中での試行錯誤が理解に役立ったと感じます

# 実践環境
* ノートPC
    * 古いLet's noteを使っています。CPU Core i5、メモリ4GB、GPUはありません。なので、本格的に学習させるのには使っていません
    * Visual Studio 2017で開発しています。Jupyter Notebookは気軽に試せるよさはあるのですが、入力補完やデバッガーの機能が弱いので、できればVisual Studioを使って開発したい、でもノートPCにはGPUがないというジレンマを抱えています。ノートPCで開発、サーバーで学習をシームレスに実現できるといいのですが・・・
* サーバー
    * iLect
        * Deep Learning基礎講座で提供頂いている環境を利用しています。GPU使えます
    * Google Colab
        * 最近使い始めましたが、これはすごいです！GPUだけでなくTPUまで使えます、そして無償です（ただし、TPUを使いこなすのはハードルが高そう）。既に役立つブログが書かれているので、それを検索して頂ければすぐに使い始められると思います。後日、それらのまとめ記事を書く予定です

# してこなかったこと、まだしていないこと
* 動画
    * 実はほぼ見たことがありません。線形代数の勉強に[【大学数学】線形代数入門①(概観&ベクトル)【線形代数】](https://www.youtube.com/watch?v=svm8hlhF8PA)を見たくらいです
    * しかし、[Udemyで学べる機械学習を全部見てみたんで、お勧め報告](https://qiita.com/kurosawa_kuro/items/63e13e6336613d79493a)などにもありますが、Udemyはよさそうな感覚はあります
* [Aidemy](https://aidemy.net)
    * 自分では実践しなかったのですが、有料プランを契約するならば有益そうです
* [Kaggle](https://www.kaggle.com/)
    * アカウントだけ作ったという段階です。今後取り組みたいと考えています

# まとめ
もしも自分自身がこれからディープラーニング勉強するぞという立場になれば以下のようにします。

* まずはPythonの基本を学ぶため[CODEPREP](https://codeprep.jp/featured)を受講します
* そして[お勧めの本](https://qiita.com/shoji9x9/items/b6f4db9e612b5af3a3f4#%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%AE%E6%9C%AC)を読み写経します
* [Deep Learning基礎講座](https://deeplearning.jp/lectures/dlb2018/)、もしくは[DL4US](http://dl4us.com/)へは絶対に応募します！当選できれば本当に大きいです
* もしも当選できなければ、別の手段で課題を設定し、それに取り組むのがいいように思います。自分自身で課題設定するのが難しければ、[Udemy](https://www.udemy.com/)や[Aidemy](https://aidemy.net)を受講するのがいいのかもしれません
* 学習にはGoogle Colabを使います。ここで試行錯誤しながら学びます。試行錯誤にはデバッガーを使う必要があるので、[JupyterまたはiPython Notebookでデバッグをする方法](https://qiita.com/makopo/items/170c939c79dcc5c89e12)あたりを読んでおきます。GPUを必要としない課題であればVisual Studioを使います

以上です。みなさんのお役に立てれば嬉しいです。
BEAR.Sunday 用認証ライブラリ

BEAR.Sunday 上で実装した認証機能をライブラリ化しました。
https://github.com/ryo88c/BEAR.Authority
ライブラリ化することで実装が整理できて良いですね。
アドベントカレンダーということで2018年内に投稿したかったのですが、気がついたら2019年になっていました。あけましておめでとうございます。

認証機能は一般化されているところとそうでないところが比較的混ざりあってしまいやすい機能だと思います。
だからこそライブラリ化によってビジネスロジックをできる限り分離して改修のしやすさを維持しておく価値がより高いのだと思います。

BEAR.Sunday はその設計思想的に言っても、セッション的な認証の仕組みはミスマッチで、OAuth などに代表されるトークンによる認証がよく合います。特に、マルチテナント型のウェブサービスにおいてはセキュリティ上の懸念として運用が雑なアカウントを起点としたインシデントがありますが、JWT で秘密鍵をアカウント別に発行することでそういったリスクへの対策にもなります。
従って、このライブラリでは [OAuth 2.0 Bearer](https://tools.ietf.org/html/rfc6750) と [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) を使って認証機能を実装しています。

よりビジネスロジックとの混在が予測される承認機能は `Authentication` クラスに実装し、承認される側、要はウェブサービスでいうところのユーザーを JWT の仕様に合わせて `Audience` というクラスとして実装しています。`Audience` は JWT によってトークナイズされる際に `Payload` というクラスに格納されます。
これら2つのクラスはバリューオブジェクトとしての性質を持たせているため、依存性の注入は意図的にしていません。

ソースコードはできるだけ無駄がないよう書いたつもりなので、よかったら一度目を通してみてください。
ReactでGeolocation APIを使って現在位置の緯度を表してみた

# 概要
APIを使って何かしたいと思い、簡単なものから実装したいということで本文の通り、Geolocatin APIを使って現在の緯度を表してみました。
Geolocatin APIはブラウザに組み込まれているので使いやすかったのも良いと思いました。

# Reactの雛形

まずはReactの雛形から作っていきます。
create-react-appで作っていきます。

```javascript:index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component {
  render() {
    return <div>Latitude: </div>;
  }
}

ReactDOM.render(
  <App />,
  document.querySelector('#root')
);

```

上記のLatitude:　の所に現在の緯度を表そうと思います。

# stateのイメージ

stateのイメージとしては初期値はnullでGeolocation APIで取得した緯度をsetStateでstateに保存するイメージです。

```javascript:index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component {
  state = { lat: null };

  render() {
    // ここにGeolocation APIで緯度を取得してsetStateする処理を書く

    return <div>Latitude:{this.state.lat}</div>;
  }
}

ReactDOM.render(
  <App />,
  document.querySelector('#root')
);

```

#Geolocation APIから緯度を取得する

緯度の取得方法ですが公式によると
> Geolocation API は navigator.geolocation オブジェクトを通じて提供されます。

そうです。

さらにgetCurrentPosition()メソッドで現在位置を取得できるそうです。
このgetCurrentPosition()では２つの引数を取り、１つ目にpositionオブジェクトを入力引数として受け取れるコールバック関数、２つ目にerrを入力引数として受け取れるコールバック関数を取ります。
実際にコードをみていきましょう。

```javascript
navigator.geolocation.getCurrentPosition(
  pos => console.log(pos),
  err => console.log(err)
);
```
上記のコードでエラーが出なければpositionオブジェクトがコンソールに表示されます。
それを見ると緯度の表示がposition.coords.latitudeにあると思うのでそれをsetStateしてあげて表示まで行きます。

```javascript:index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component {
  state = { lat: null };

  render() {

    navigator.geolocation.getCurrentPosition(
      pos => this.setState({ lat: pos.coords.latitude }),
      err => console.log(err)
    );

    return <div>Latitude:{this.state.lat}</div>;
  }
}

ReactDOM.render(
  <App />,
  document.querySelector('#root')
);

```

以上で表示されたはずです。

#感想
今回はとりあえず何かしらAPIを使うのが目標でした。
今後はいろんなAPIも触って行き、Reactも楽しんでいければと思います。
H8/3664ではじめるマイコン制御4  MoterRotation

![93046 - コピー.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/9db6383a-7aa4-bcb9-1755-0fe7187137a0.jpeg)

今回はPort1xを使ってモータを動かしてみたいと思います。
モータはステッピングモータを使っています。
ステッピングモータとは
電流を与える毎に一定の角度(=そのステッピングモータ固有の角度)だけ回転するモータのことです。
1回電流を与えると、正確に一定の角度だけ回転します。

実際に動作させるにはステータに一定の順序で電流を流して励磁させることでモータを回転させることができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/333756/67663d6b-8d34-95ce-94c6-3a142bcfeba6.png)


```c:MoterRotation.c
//時計回りにモータを回転させるだけのプログラム
#include <stdio.h>

#define	BRR		(*((unsigned char *)0xFFA9))
#define	TMA		(*((unsigned char *)0xFFA6))

#define	PMR1	(*((unsigned char *)0xFFE0))
#define	PMR5	(*((unsigned char *)0xFFE1))

#define	PCR1	(*((unsigned char *)0xFFE4))
#define	PCR5	(*((unsigned char *)0xFFE8))
#define	PCR7	(*((unsigned char *)0xFFEA))
#define	PCR8	(*((unsigned char *)0xFFEB))

#define	PDR1	(*((unsigned char *)0xFFD4))
#define	PDR5	(*((unsigned char *)0xFFD8))
#define	PDR7	(*((unsigned char *)0xFFDA))
void wait();

main()
   {
	int i,cnt=1;
	unsigned char Seg1,Seg10;//表示用変数
	unsigned char rot;//1の位シフト用
	unsigned char rot10;//10の位シフト用
	
	BRR=12;			//16MHZ時には１２を　デフォルトは７　ボーレート変更	
 	PMR1 = 0x00;			/*ポート１を汎用ＩＯに設定*/
 	PMR5 = 0x00;			/*ポート１を汎用ＩＯに設定*/

	TMA = 0x98 ; 

 	PCR1 = 0xff;	//アドレス　FFE4
    PCR5 = 0xff;	//FFE8
    PCR7 = 0x00;	
    PCR8 = 0xff;	//FFED		//00入力　　ff出力
    
    
    if(cnt==1){//初期化
	Seg1=0x01;Seg10=0x81;rot=0x01;rot10=0x81;cnt=0;
		}

    for (;;) {/* 無限ループ */
	    
			PDR1=Seg1;
			wait(5000);//回転速度調整
		if(rot==0x80){
			Seg1=rot;
			rot=0x10;  //左へ1ビットシフト
			
		}
		else{
			Seg1=rot;
			rot=rot<<1;
		}
    }
    return 0;
   }

void wait(int n)
{
	int i;
 	for(i=0;i<n;i++);
}
```

前回の7segRotation.cを使いまわしたので使わなくなった変数も残ってしまっています。

次へ[H8/3664ではじめるマイコン制御5 ](https://qiita.com/kiki0817/items/630bcc13ea02b73133e2)
OctopusというFirebaseのRealtime Databaseで動くMarkdown WikiをDeployしてみた

![4ohlZk5eTY.gif](https://qiita-image-store.s3.amazonaws.com/0/38292/728293d8-c7bc-adbd-bf2f-25527b46e4a3.gif)

# 背景

[Firebase](https://firebase.google.com)で動くMakdownなWikiでTech的なアウトプットをする試みです。

## お試しになりたい方向け

### Octopusについて

以下RepositoryをCloneしてBuildしてDeployしてください。

- [livechat/octopus: 🐙  Octopus - Internal wiki with diagrams for software and product teams](https://github.com/livechat/octopus)

#### Requirements

1. npm
2. node.js
3. Googleアカウント & Firebase

#### 基本的なHowto

1. Firebaseプロジェクト作成([ググって](https://docs.kii.com/ja/samples/push-notifications/push-notifications-android-fcm/create-project/))
    1. Authenticationから必要に応じた認証方法を設定しておく。(自分はGoogleだけ)
    2. Databaseを`Realtime Database`として作成しルールを設定しておく。([`Realtime Database設定`](#realtime-database設定)参照されたし)
2. `git clone git@github.com:livechat/octopus.git`
3. `cp src/config/config.template.js src/config/config.js`
4. `vim rc/config/config.js` で1で作成したFirebaseのプロジェクトのconfig情報をコピペ
    1. ![image](https://github.com/livechat/octopus/raw/master/readme-assets/config.png)
5. `npm install --build-from-source`
6. `npm run build`

#### Firebase HostingにDeploy[^1]

1. firebase-toolsをインストールしてない人はインストール
    1. `npm install -g firebase-tools`
    2. `firebase login`してBrowser認証する
    3. `cd /path/to/project`
2. `firebase init`して`hosting`に`Space`でチェックを入れて`Enter`する
    1. 対象ディレクトリは`build`にする(デフォルトは`home`)

[^1]: Netlify使うと良いよ的な事がREADMEに書いてあるんだけど、Firebase Hostingも速いらしいのでとりあえず試してみる。

### 早速ハマったポイント

#### Mac OSXでDeployするとgRPC関連で`npm install`が失敗する

対応方法 = Mac OSXじゃなくてLinuxで`npm install --build-from-source`する。

ググったらこんなIssueが出てくる。Node.jsのv11.x固有の問題っぽい？
- [gRPC sporadically doesn&#39;t build properly under node 11. · Issue #594 · grpc/grpc-node](https://github.com/grpc/grpc-node/issues/594)

#### Realtime Database設定

自分の場合は`read`と`write`共に自分のドメイン(G Suite)に限定しました。

```
{
  "rules": {
    ".read": "auth.token.email.endsWith('@tokifu.jp')",
    ".write": "auth.token.email.endsWith('@tokifu.jp')"
  }
}
```

# まとめ

SFSG:smile: