OmniAICreator/Qiita-1.07M huggingface dataset:
marginとpaddingの違いについて

#はじめに
これは文系ボードゲーマーである私がプログラミングを勉強したことをアウトプットする日記のようなもの。
今回は**margin**と**padding**の違いについて

#marginについて
marginとは要素と要素の間のことを指します。
上下左右それぞれ
margin-top: ○○px;
margin-botom: ○○px;
margin-left: ○○px;
margin-right: ○○px;
で表します。

#paddingについて
paddingとは要素の中の余白のことを指します。
上下左右それぞれ
padding-top: ○○px;
padding-botom: ○○px;
padding-left: ○○px;
padding-right: ○○px;
で表します。

#marginとpaddingの違い
marginは要素の間隔、paddingは要素内の余白と説明しました。
何かしらのボックスがあるとしたら、ボックスの枠線と中身の間に余白を入れたいときは**padding**、枠線と別のボックスの枠線の間を開けたいときは**margin**を使います。

黒の線をボックスのボーダーとします。
この時にmarginを使って動かせる部分は黒と緑の間になります。
paddingを使えば黒と青の調整ができます。
![スクリーンショット 2019-02-23 12.21.39.png](https://qiita-image-store.s3.amazonaws.com/0/268042/9b1a92a4-205f-4db6-611e-71e85225ae8a.png)

#まとめ
marginとpaddingの違いについて画像を使いながら説明してみました。
初心者プログラマーのアウトプットとして暖かく見守っていただけると幸いです。
Swift MkMapViewで地図アプリ作成してみた（記事一覧）

#記事一覧
スタンダード編
- [(01) 地図を表示する](https://qiita.com/rain_00_00_09/items/797c74c64f57b36ddf29)
- [(02) 現在位置を取得する](https://qiita.com/rain_00_00_09/items/18496f0f9aa1e89350e0)
- [(03) 現在位置を地図の中心にする](https://qiita.com/rain_00_00_09/items/34b65640c7c839a379f4)
- [(04) トラッキングモードを切り替える（自作ボタン）](https://qiita.com/rain_00_00_09/items/d6fad14a81250c2a346b)
- [(05) トラッキングモードを切り替える（自動）](https://qiita.com/rain_00_00_09/items/a239d6e4ae893673f18f)
- [(06) スケールバーとコンパスを追加する](https://qiita.com/rain_00_00_09/items/a04dcf647f7362258ecf)
- [(07) 地図の表示タイプを切り替える](https://qiita.com/rain_00_00_09/items/6e19ac92bb9eddbf89f9)

ゴルフモード編
- [(08) ロングタップした位置の緯度経度を取得する](https://qiita.com/rain_00_00_09/items/1be8bf72ecf0700ffdf5)
- [(09) ロングタップした位置と現在位置の距離を求める](https://qiita.com/rain_00_00_09/items/70daa540bb5f8485b9b8)
- [(10) ロングタップした位置にピンを立て距離を表示する](https://qiita.com/rain_00_00_09/items/d426a32ab8356a97fc78)
- [(11) ロングタップした位置の標高を国土地理院から取得する](https://qiita.com/rain_00_00_09/items/df32926d6755972cb421)
- [(12) ロングタップした位置と現在位置の標高差をピンに表示する](https://qiita.com/rain_00_00_09/items/00df470bfbcb66fa2b26)

簡単なんでAppleWatchとも連動してみた編
- [(13) 簡単なんでAppleWatchとも連動してみた](https://qiita.com/rain_00_00_09/items/53652bea2f7d2bc5f275)

AppleWatchのゴルフモード編
- [(14) iOSから送信したデータをwatchOSで受信する](https://qiita.com/rain_00_00_09/items/59ff413b71caf4189656)
- [(15) watchOSからiOSにデータ送信を要求する](https://qiita.com/rain_00_00_09/items/cb4aefc6a027c36904db)
- [(16) iOSから転送された地点から現在位置の距離をwatchOSで計算して表示する](https://qiita.com/rain_00_00_09/items/41027035e6f90a0cbe38)

サイクルモード/ウォーキングモード編
- [(17) バックグラウンド・スリープ中でも位置情報を受信する](https://qiita.com/yuta-sasaki/items/fe93188dece9f74fae68)
- [(18) 位置情報から速度、平均速度、最高速度を求める](https://qiita.com/yuta-sasaki/items/6784582ade06f01d4785)
- [(19) UserDefaultsでデータをバックアップする](https://qiita.com/yuta-sasaki/items/2c6978e2d0215d81ccab)
- [(20) 受信精度の悪いGPSデータを間引く](https://qiita.com/yuta-sasaki/items/b73462064b1b6cee0d04)
- [(21) 周辺検索した地点をセミモーダルビューに表示する](https://qiita.com/yuta-sasaki/items/b848c17b9493f57c1dd7)
- [(22) ブラウザを表示する](https://qiita.com/yuta-sasaki/items/2ceb5a12950277b94028)
- [(23) ルートを探索する](https://qiita.com/yuta-sasaki/items/e89e94d67c808a6488d4)

#アプリダウンロード
[Map Mode](https://apps.apple.com/jp/app/map-mode/id1496768292)

#プライバシーポリシー
[Map Modeアプリのプライバシーポリシー](https://qiita.com/rain_00_00_09/items/87aaaeccebbf683756a4)

#アプリ画像
![Screen1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/d268501c-e1b2-2c68-dede-d7ab25c58406.png) ![Screen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/34549ab4-49b5-c931-4507-27f55fea18ed.png) ![Screen3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/808ae3df-e34c-3b95-ea5b-acb42a08a226.png) ![Screen4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/a3df0ccd-f689-8e93-b0ac-8bb7f345996a.png) ![Screen5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/ad284e69-94f6-fa92-8cf5-6bc9b01799c3.png) ![Screen6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362635/27f74941-d6da-57f7-8b69-1b356c371c68.png)

#Seriese
* [作成してみたSeriese一覧](https://qiita.com/yuta-sasaki/items/a033edc84bb023eea39b)
1つ目のプログラミングをマスターした人が2つ目の言語を学ぶプロセス

プログラミングを始めてしばらくすると他の言語も書けるようになりたい、書かないといけないということが出てくるかと思います。

すでに最初の言語をある程度かけるようになった人に向けて次の言語を学ぶプロセスを書いてみます。

#オーバービュー
2言語目以降の学習は以下の流れが効率的だと思います。

1. 習得する言語・フレームワークを決める
- 言語・フレームワークの理念・設計思想・パラダイムを理解する
- 開発環境を構築する
- ハローワールドしてみる
- 基本的な構文を知る
- 言語パラダイムを理解する（1言語目と異なる場合）
- フレームワークを使った開発の流れを理解する
- その言語特有の書き方に慣れる
- 言語・フレームワークの理解を深める

#習得する言語・フレームワークを決める
多くの場合、Webの開発をするのか、ネイティブアプリを開発するのか、計算をするのかなど目的が決まっているでしょうから、**目的によって言語とフレームワークを選ぶ**必要があります。

個人的に、webのフレームワークは新しいものが出てくるサイクルが早くどれを選んでいいのかよくわかりません。周りの人に聞くのが一番良いでしょう。周りに教えてくれる人がいなければネットで調べるなどしましょう。ネットでランキングを見て、ランキング上位のものに安直に決めてしまうのは必ずしもお勧めしません。人気の言語は情報も多く使いやすいですが自分の**実現したいものに適した言語・フレームワークを選ぶ**のが一番重要です。


#言語・フレームワークの理念・設計思想・パラダイムを理解する
開発元サイト、Wikipedia、ネット記事を読んで理解しましょう。

###理念・設計思想
必ずしも開発開始当初の理念が現在の使われ方にマッチしているかと言えばそうではないかもしれません。開発当初は別の目的でつくられたものだが、ある特定の分野のフレームワークが充実しているのでその領域でよく使われるということがよくあります。このことから、言語とフレームワークをセットで**どのように使われることを想定して作られているか**を調べておくと良いでしょう。こういうことはその言語やフレームワークの公式ページを見ればすぐにわかります。Wikipediaには概要がよくまとまっているのでそちらもお勧めします。

###パラダイム
オブジェクト指向、手続き型、関数型などどのプログラミングパラダイムに対応しているのかを知っておくべきです。プログラミングパラダイムはその言語の特性をよく表しているため、これを知っておくと理解が効率的に進みます。

逆にこれを知らずに、とりあえず構文だけを勉強し始めると混乱のもとになります。

#開発環境を構築する
これがとても大変だったりします。パソコンにもとから入っている言語だと何もせずに始められたり、IDEをダウンロードしてインストールするだけだったりすることもありますが、そうでないときは頑張ってください。

開発元が親切な場合はGet Startedとかを読んでその手順通りに進めればいいわけですが、言うとおりにやっても上手くいかない場合が一番しんどい。個々で挫折しないようにしましょう。

#ハローワールドしてみる
開発環境が上手く構築できたかどうか確かめる作業です。つかの間の感動をお楽しみください。

#基本的な構文を知る
普通の言語（＝いまどきの手続き型言語）は方言が違うだけで**どれも同じ**です。1言語使える方はfor文とはなんぞやというようなところから理解する必要はないので書き方の違いを頭に入れてください。別に憶えなくてもプログラミングの方法を知っているならそれぞれの書き方をググりながら書いても問題はないので難しいことではありません。

とりあえず確認しておきたい構文は以下。

- エントリポイント（c言語ならmain関数をつくらないといけないとかそういうやつ）
- 関数定義
- クラス定義
- 変数・配列の定義
- 代入
- if文、for文
- 入出力

#言語パラダイムを理解する（1言語目と異なる場合）

ここまでで一応その言語を使ってプログラミングができるはずです。この次にフレームワークを活用していくにあたって言語パラダイムは知っておいた方が良いでしょう。

これを事前にある程度知っておかないと、例えばオブジェクト指向のフレームワークを使って開発するときに「newはおまじないですよー」とかいう教え方になってしまうわけです。

#フレームワークを使った開発の流れを理解する
これはフレームワークの公式サイトのGet Startedが大変ためになりますので一回やっておくとよいでしょう。どこに何を書くのかを理解してください。

フレームワークの良さは、内部で何をやっているか知らなくてもここにこれを書けば動くという点にあります。当然、十分に活用していくためにはフレームワーク自体について知る必要はあるでしょうが、最初はどこに何を書くのかという理解で十分かと思います。

#その言語特有の書き方に慣れる
###コーディング規約
細かいところはチームによりますが、その言語を使っている人の中で慣習となっている書き方があります。変数の命名はキャメル記法かスネーク記法かなど。Objective-Cでは関数の名前、引数を英語のように読めるようにするということになっているので長い名前がよく使われます。

###モダンな書き方を使う
古い言語から新しい言語に移るといまどきな書き方を目にします。新しい書き方をしなくてもいままでの書き方でやりたいことは実現できると思いますが、新しい書き方を積極的に使うとコードが綺麗になるので使っていきましょう。（foreachとかclosureとかいろいろ←例が別に新しくないというコメントは甘んじてうけます）

pythonなどだと標準ライブラリが充実しているので他の言語では自分でアルゴリズムを実装しなければならないものも便利な関数が用意されていたりするのでご活用ください。

#言語・フレームワークの理解を深める
ここまでできればあとは開発していくだけですね。開発しながら身につくこともあると思います。同時にこまめに色々な資料を読んでおくことでよりよい書き方に出会えたりします。

#おわりに
今回書いたのは、意識的にやっているわけではないものの、新たに言語を習得するときに自分がなんとなくやっている流れです。

余談ですが、「いくつ言語が使えますか？」という質問は、いくつもの言語を使えるプログラマに対してはナンセンスだと思います。作りたいものによって言語を使い分けているだけで、極端な話をすると大抵の言語で明日から開発するというのは可能でしょう。ですので言語は「習得する」ほどのものではないのです。

しかし、まだ1つの言語でしか開発したことのないプログラマに、「言語は習得せずとも使える」といっても信じてもらえないと思います。それは1つめの言語のときに「プログラミング」と「言語」を同時に勉強していたからでしょう。プログラミングができる人には二つ目の言語を使えるようにするのは手順を踏めば簡単です。

この記事で紹介している内容は私の個人的な方法で、そのまま使えるかはわかりませんが、お役に立てれば幸いです。

他の意見などがあれば是非お寄せください。
GCEのインスタンスにgcloudコマンドで予約済みの静的IPを割り当てる

gcloudコマンドでもインスタンスに予約済みの静的IPを割り当てる事ができます。

注意点としては、先にIPを削除しておかないと以下のエラーが起きます。

`ERROR: (gcloud.compute.instances.add-access-config) Could not fetch resource: - At most one access config currently supported.`

```bash
# 先にIPを削除
gcloud compute instances delete-access-config インスタンス名
# IPの割当
gcloud compute instances add-access-config インスタンス名 --address IPアドレス
```

参考：https://stackoverflow.com/questions/51475053/assigning-a-reserved-ip-to-instance-from-command-line-google-cloud
メールでgithubから脆弱性あるよと言われた

メールで脆弱性があるよと言われた。

We found a potential security vulnerability in one of your dependencies.
Only the owner of this repository can see this message. 
Manage your notification settings or learn more about vulnerability alerts.

一言で言うと脆弱性あるよ。

```json:package.json
1 bootstrap vulnerability found in package-lock.json 2 hours ago
Remediation
Upgrade bootstrap to version 4.3.1 or later. For example:

"dependencies": {
  "bootstrap": ">=4.3.1"
}
or…
"devDependencies": {
  "bootstrap": ">=4.3.1"
}
Always verify the validity and compatibility of suggestions with your codebase.
```

直し方の例を教えてもらった。

直す。

package.jsonを直す。

```json
     "devDependencies": {
         "axios": "^0.18",
-        "bootstrap": "^4.0.0",
+        "bootstrap": "^4.3.1",
         "cross-env": "^5.1",
         "jquery": "^3.2",
         "laravel-mix": "^4.0.7",
@@ -23,4 +23,4 @@
         "vue": "^2.5.17",
         "vue-template-compiler": "^2.5.21"
     }
}

$ composer update
```

composerは、installやupdateやupgradeがある。

こちらの記事をいつも参考にさせていただいているが、すぐに忘れてしまう。

composer install と composer updateの違い
https://qiita.com/YusukeHigaki/items/47dd3ec23544225f7301
TermuxでFsWikiを動かす

Androidスマホ上で動くTermux。apache やperl も動かすことができます。
私は、自分自身の備忘録を兼ねて、自宅WEBサーバ上のFsWiki上にいろいろと
書き込んでいたのですが、ネットがつながらないところでも見たい。
でもそのために普段からノートPCを持ち歩くのも辛い ... 

と思っていたのですが、Termux があれば、スマホの上に、FsWikiを構築できます。

そのための手順を紹介します。
#環境構築
Termux をプレイストアから入手。これがないと始まりません。

#まずは、Perl CGIを動くようにする
##apache,perl の入手
Termuxをインストールし、起動したら apache,perl を入手します。

```
apt update
apt upgrade
apt install apache2
apt install perl
```

##httpd.conf 修正
ファイル: /data/data/com.termux/files/usr/etc/apache2/httpd.conf
以下のエントリに、以下を追加 Optins +ExecCGI を追加

```
<Directory /data/data/com.termux/files/usr/lib/cgi-bin>
</Directory>
```

以下のAddHandler ... のコメントを外す

```
AddHanderl cgi-script .cgi
```

mod_cgiモジュールを読み込むため、以下のように変更し、強制的 mod_cgi.soを読ませる

```
<IfModule mpm_prefork_module>
     #LoadModule cgi_module libexec/apache2/mod_cgi.so
</IfModule>
```

　　　↓

```
  #<IfModule mpm_prefork_module>
      LoadModule cgi_module libexec/apache2/mod_cgi.so
  #</IfModule>
```

ここまでで、apace でperl CGIが動く状態になっています。
サンプルの printenv が動くように実行権限の付与と修正を行います。

```
chmod ugo+x /data/data/com.termux/files/usr/lib/cgi-bin/printenv
```

また、エディタを使って、printenv の先頭行に以下を追加します。

```
#!/usr/bin/perl
```

ここまできたら、apace を起動し

```
apachectl
```

スマホのWEBブラウザでいかにアクセスしてみましょう。
http://127.0.0.1:8080/cgi-bin/printenv
(127.0.0.1ではなく、localhost でもアクセスできますが、Yahooブラウザ等だとダメでした)


#FsWikiを動かす
##モジュールの入手

```
apt install make
apt install clang
apt install wget
apt install openssh
```

(wegt は、FsWikiを取得するため。標準で入っている wget は httpsに対応していないため)

##cpan からCGIを取得

```
cpan
```
上記で、cpan を一度動かし、一通り設定（問い合わせは全て デフォルトでOK)が終了したら、"q"で終了。
再度cpanを起動

```
cpan
cpan>install CGI
```

##FsWikiを取得し、htdocs 配下に展開
```
cd /data/data/com.termux/files/usr/share/apache2/default-site/htdocs/
/data/data/com.termux/files/usr/bin/wget https://ja.osdn.net/projects/fswiki/downloads/69263/wiki3_6_5.zip
unzip wiki3_6_5.zip
mkdir /data/data/com.termux/files/usr/share/apache2/default-site/htdocs/wiki3_6_5/log
mkdir /data/data/com.termux/files/usr/share/apache2/default-site/htdocs/wiki3_6_5/backup
```

##httpd.conf に以下の定義を追加

```
<Directory /data/data/com.termux/files/usr/share/apache2/default-site/htdocs/wiki3_6_5>
  Options +ExecCGI
</Directory>
```

その後、apache 再起動し、以下にアクセスしてwikiが表示されればOK。

http://127.0.0.1:8080/wiki3_6_5/wiki.cgi


小さなスマホの中で、apache や perl CGI が動いていると思うと、ちょっと感動です。
大規模行列の固有値計算：ARPACK-ng+ARPACKPP

#はじめに
目下の悩みである固有値計算のライブラリについて、
implicitly Restarted Arnordi法を用いているARPACK-ngと、
そのC++ラッパーであるARPACKPPを試してみたので、
intelコンパイラを使用してのインストール手順をまとめておく。

#謝辞
情報提供
@septcolor  さん


#理論
下記が一番わかりやすい。
http://www.cms-initiative.jp/ja/events/0627yamamoto.pdf
固有値計算に関する日本語の教科書だと、下記は知る限り記述が明瞭でとっつきやすいが、
さすがにimplicitly restartedのくだりに関する記述はなかった。
https://www.iwanami.co.jp/book/b258658.html

#ARPACK-ng
ubuntu環境であればlibarpack2がaptでインストールできるが、
local環境に入れたいので、ソースコードからコンパイルした。

下記よりダウンロード。
git clone https://github.com/opencollab/arpack-ng.git

cmakeもしくはccmakeにてコンパイル。intelコンパイラを用いたが特に問題なし。
intelコンパイラをデフォルト設定でインストールしているなら、
intel MKLのLAPACKとBLASを自動で検知するので、その他のライブラリのインストールは不要。

#ARPACKPP
下記よりダウンロード。
git clone https://github.com/m-reuter/arpackpp.git

ARPACKCPPはテンプレートライブラリでありコンパイルは不要。
includeディレクトリを適当な場所に置き、下記にてexampleが実行可能であることを確認した。

icpc example.cpp -I/arpackppDir/include -L/arpackDir/lib/ -mkl -larpack -lifcore

g++,gfortranの場合は-lifcoreの代わりに-lgfortranを使用すれば問題ないかと。

4スレッド並列計算にて、10000自由度の密行列にかかる時間が10秒程度なので、今の最低限の実用には耐えうるか。
そもそもこんな扱いにくい行列の使用が不可避な現状を改善するほうが早いかもしれない…。
Qt for pythonとPyQt5の比較

##イントロダクション
マルチプラットフォームでGUIを作成する場合、様々な方法があります。
その中でもQtと連携しているライブラリは多い(OpenCV、その他OpenGLのViewerとして)。
また、QtをPythonから使用しているものもあります。

QtをPythonから使用する方法としてQt for python(PySide2)かPyQt5のどちらかをimportする必要があります。

Qt for pythonが公式のようです。
https://www.qt.io/qt-for-python

しかし、２，３年前に作られたソースコードを見るとPyQt5を採用しているものが多く、Qt for pythonに移植するにはどうしたらいいか、と思ったのでとりあえず比較等まとめてみます。

##環境
Ubuntu18.04

##環境構築の比較
```
$ sudo apt install python3-pip
```
| Qt for Python | PyQt5 |
|:-----------|:------------|
| $ pip3 install PySide2  | $ pip3 install pyqt5 |

##importの比較
| モジュール名 | Qt for Python | PyQt5 |
|:-----------|------------:|:------------:|
| QtCore | from PySide2 import QtCore | from PyQt5 import QtCore |
| QtGui | from PySide2 import QtGui | from PyQt5 import QtGui |
| QtWidgets | from PySide2 import QtWidgets | from PyQt5 import QtWidgets |
(ex. from PySide2 import QtCore, QtGui, QtWidgets)

##Hello worldの比較
| Qt for Python | PyQt5 |
|:-----------|:------------|
| import sys<br>from <font color=red>PySide2</font>.QtWidgets import QApplication, QLabel<br><br>app = QApplication(sys.argv)<br>label = QLabel("Hello World!")<br>label.show()<br>app.exec_()<br>  | import sys<br>from <font color=red>PyQt5</font>.QtWidgets import QApplication, QLabel<br><br>app = QApplication(sys.argv)<br>label = QLabel("Hello World!")<br>label.show()<br>app.exec_()<br>  |

##condaでパッケージを取得する場合の比較
| Qt for Python | PyQt5 |
|:-----------|:------------|
| $ conda install -c conda-forge pyside2  | $ conda install pyqt=5 |

##結論
...とりあえず、このレベルなら何も気負う必要はない？
何も考えずに
「PyQt5」→「PySide2」
「pyqt5」→「pyside2」
に置換してやれば移植できる。

うまくいかなかったら、その都度追記予定。
GASのscriptIdはどこで確認するのか

# 経緯
ブラウザでサクッと開発始めたものの、だんだんローカル開発したくなってきた。

# Google謹製のCUIツール
`clasp`というGoogle謹製のCUIツールがある事に気がついた。
> https://developers.google.com/apps-script/guides/clasp

## とりあえずinstallしてみる
### ディレクトリを作る
```
mkdir -p ~/clasp/hello_clasp
cd ~/clasp/hello_clasp
```

### claspをインストール
```
npm install @google/clasp -g
```
**npmは知らないけどCUIのエラーに従って何回か繰り返していたらインストールできた。**

### claspでログイン
```
clasp login
```
突然Chromeが立ち上がって、いつものGoogleアカウント連携が表示される。よくできていて驚く。

### 既存のscriptをcloneする
```
clasp clone <scriptId>
```

#### scriptIDを求められる
gasのエディタから次の手順で得られる。
> `File > Project properties > Info.`

**僕は良く読んでいなかったので、Executionsを開いた後にそのURLに書いてあるIDから取得したが、そんな必要はない。**
サーマルプリンタとRaspberry Piでカンバンを改善した話

2019年2月22日(金)に大阪で開催された「[大阪版IoT縛りの勉強会 IoTLT Osaka Vol.10](https://iotlt.connpass.com/event/118404/)」にて「サーマルプリンタとRaspberry Piでカンバンを改善した話」というタイトルでLTしました。この記事は、そのスライド、関連記事、ソースコードをまとめたものです。

## スライド

発表に使用したスライドはこちら。

[![](https://speakerd.s3.amazonaws.com/presentations/9357373cd84248a3b2c8980d2dcce615/preview_slide_0.jpg)](https://speakerdeck.com/yuyakato/samarupurintatoraspberry-pidekanbanwogai-shan-sitahua)

## 記事

基となったQiita記事はこちら。

* [サーマルプリンタで印刷する: 目次](https://qiita.com/yuyakato/items/288962fbc39446644668)
* [サーマルプリンタで印刷する: セットアップ編](https://qiita.com/yuyakato/items/7d4db1c567d952a7ac91)
* [サーマルプリンタで印刷する: Raspberry Piからのテスト印刷編](https://qiita.com/yuyakato/items/3309b0ede886c2698526)
* [サーマルプリンタで印刷する: 印刷サービス編](https://qiita.com/yuyakato/items/24666dff3ea1a6a86672)
* [サーマルプリンタで印刷する: レンダリングサービス編](https://qiita.com/yuyakato/items/750364647bbb189016bb)
* [サーマルプリンタで印刷する: Webアプリ編](https://qiita.com/yuyakato/items/99f09875348539531da4)
* [サーマルプリンタで印刷する: Chrome拡張編](https://qiita.com/yuyakato/items/2d6cd811065be0e8ebec)
* [サーマルプリンタで印刷する: まとめ（再セットアップ＆自動起動編）](https://qiita.com/yuyakato/items/e2d55411e6d40deafc1c)

## ソースコード

ソースコードが格納されているGitHubリポジトリはこちら。

[nayutaya/thermal-printer](https://github.com/nayutaya/thermal-printer)
Django サインアップの方法

この記事群が分かりやすく書いてある
ちなみにサインアップする時は当たり前だけど
データベースをmigrateしている必要があります。

1
https://wonderwall.hatenablog.com/entry/2018/03/21/153000

2
https://jyouj.hatenablog.com/entry/2018/05/28/232026

3
https://ymgsapo.com/create-sign-up/

4
https://qiita.com/hayata-yamamoto/items/00072091caa5921fc819
Volto というPloneのReactによるフロントエンド実装のインストール方法

# Voltoとは

[Volto](https://github.com/plone/volto) は、Plone.Reactという名前で開発が進められていました、2018年秋にVoltoという名前に変更になりました。
これは、VoltoはPloneだけの物ではないという意思表示だと言われています。

PloneはPythonでできているオープンソースCMSです。エンタープライズ向けに適用可能な高機能なCMSです。Ploneは標準でRestfull APIを提供しています。この機能の実装としてVoltoは存在しています。

Voltoは、Ploneの持つ機能のすべてをReactベースのフロントエンド実装となっており、一般の閲覧はもちろんのこと、コンテンツの編集はユーザ管理などのCMSの管理画面まですべての機能を提供しようとしています。
また、[Pastanaga UI](https://pastanaga.io/) という新しいユーザインターフェースの考え方で実装されています。


# インストール方法

このドキュメントは、 [Plone Conference 2018 Tokyo](https://2018.ploneconf.org) で行われた [チュートリアルのドキュメント](https://training.plone.org/5/volto/bootstrap.html) に基づいて 2019年2月現在の情報を元に書いています。


## 概要

Voltoを導入するには、以下の要素が必要です。

- Plone
	- 4.3 以降 (ここでは5.1がインストールされている事を前提にしています)
	- Plone REST.API の設定
	- Ploneの `CORS` 設定
- npm関係のツール
	- nvm
	- npm
	- yarn
- Volto

## Plone関係の設定

Plone 5.1のインストールは、公式ドキュメントなどを見てください。(必要なら改めてエントリーを書きます)

### REST.API

PloneのWeb管理画面で、「アドオン」へ行き、 `plone.restapi` を導入(適用)する

### CORS設定

buildout.cfg の instanceセクションに以下を追記し、buildoutを実行
(localhost 3000ポートで、Voltoを立ち上げる場合)

```
[instance]
recipe = plone.recipe.zope2instance
...
zcml-additional =
  <configure xmlns="http://namespaces.zope.org/zope"
             xmlns:plone="http://namespaces.plone.org/plone">
  <plone:CORSPolicy
    allow_origin="http://localhost:3000,http://127.0.0.1:3000"
    allow_methods="DELETE,GET,OPTIONS,PATCH,POST,PUT"
    allow_credentials="true"
    expose_headers="Content-Length,X-My-Header"
    allow_headers="Accept,Authorization,Content-Type,X-Custom-Header"
    max_age="3600"
    />
  </configure>
```

Note: instanceセクションが見つからない場合 `recipe = plone.recipe.zope2instance` が書かれているセクションを探してください。そのセクション( `[]` で始まるブロック) の後半に記述してください。



```
$ ./bin/buildout -N
$ ./bin/instance restart
```


## npm関係のツール

すでにインストール済みの方は読み飛ばしてください

### nvm

```
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
$ source ~/.nvm/nvm.sh
```

### npm

```
$ nvm install v8.11.3
```

### yarn


```
$ npm install -g yarn
```


## Voltoのインストール

### コマンドラインツールの導入

```
$ yarn global add @plone/create-volto-app
```

Note: 公式ドキュメントによると `create-volto-app` が実行可能とあります。しかし、.yarn以下にPATHが通っておらずコマンド実行ができました。

PATHを通す

```
PATH="$HOME/.yarn/bin:$PATH"
```

### プロジェクトファイル群を

```
$ create-volto-app my-volto-app
```

以下の様のフォルダができあがります

```
my-volto-app
├── README.md
├── node_modules
├── package.json
├── .babelrc
├── .eslintrc
├── .gitignore
├── .yarnrc
├── locales
├── public
│   ├── favicon.ico
│   └── robots.txt
├── theme
│   └── theme.config
└── src
    ├── actions
    ├── components
    ├── constants
    ├── customizations
    ├── helpers
    ├── reducers
    ├── client.js
    ├── config.js
    ├── index.js
    └── routes.js
```



# Voltoの起動

```
$ cd my-volto-app
$ yarn start
```

Note: kou式ドキュメントには、 `3000番ポート` が使われるとありますが、管理用ポートとして `3001番ポート` も使われます。仮想環境で試す場合には、以下のポートへの接続ができることを確認してください。

- 3000 (Volto)
- 3001 (Voltoの開発モードでjsを読み込む)
- 8080 (Plone)
Google Earth EngineのPython APIをColaboratoryで使う

##Google Earth Engineとは
人工衛星（地球観測衛星）の撮像データをすぐに使えるフォーマットで提供してくれるGoogleのプラットフォームです。Google EarthのAPIを外部開放しているということらしい。宙畑の記事がわかりやすいので紹介します。

[衛星画像解析が変わる!? 「Google Earth Engine」の何がすごいのか](https://sorabatake.jp/337/)



Earth EngineのAPIはJavaScriptから使うのが基本的な使い方ということで、かつGoogleでは下記のようなコードエディタも用意してくれています。結果も画像ですぐに表示されて、至れり尽くせりですね。
<img width="500" src="https://developers.google.com/earth-engine/images/Playground.png">



##Earth EngineのPython用APIをColaboratoryで使う
とは言え、私はへなちょこ日曜プログラマーで、JavaScriptを使ったことがないので、できれば手に馴染んだPythonから使いたいところ。ですが、Python用APIのインストールの情報は数が少なく、かつ私には環境構築が難しそうだと思っていました…
そこでちょっと調べたところ、みんな大好きGoogle Colaboratoryから超簡単に使える事がわかったので、ご紹介したいと思います。
（公式ではDocker ContainerをつかってGCPもしくはローカルにインストールすることを推奨してます https://developers.google.com/earth-engine/python_install ）

まずはColab上にEarth Engine APIをインストールします

```
!pip install earthengine-api
```
続いて認証です。ちなみに、予めユーザー登録しておく必要があります。まだの方は[ここ](https://earthengine.google.com/)の右上の「Sign Up」からしておきましょう。

```
!earthengine authenticate
```

あとはモジュールをインポートして初期化するだけでもう使えます。簡単ですね。

```
import ee
ee.Initialize()
```

というか、ここを見たほうが早いです… 
https://github.com/google/earthengine-api/blob/master/python/examples/ipynb/EarthEngineColabInstall.ipynb




私もこれからいろいろいじって遊んでみようと思います。
macosで Control+[ 押下をEscapeに割り当てる

Escapeキーは遠く、さらにtouch barでは押しにくいので、Control+[をEscapeキーにわりあてます。

1. Karabinar Elementsをインストールする
2. 以下を作成する。

```json:~/.config/karabiner/assets/complex_modifications/myconfig.json
{
  "title": "Ctrl+[をEscapeにする。",
  "rules": [
    {
      "description": "Ctrl+[をEscapeにする。",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "open_bracket",
            "modifiers": {
              "mandatory": ["control"]
            }
          },
          "to": [
            {
              "key_code": "escape"
            }
          ]
        }
      ]
    }
  ]
}
```
3. karabinar-elementsのpreferenceからenableする

<img width="945" alt="スクリーンショット 2019-02-23 10.45.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/9979/2560d287-f1ef-ac12-1d78-3fd3ca60c421.png">
ImageMagickで compare: image widths or heights differ と出た場合

# 結論

最新のバージョンのImageMagickをインストールする

# 現象

`a.png` と `b.png` があり、`diff.png` を作成しようとして、「画像の幅か高さが違う！」と怒られる。

```bash
# compare ./a.jpg ./b.jpg diff.jpg
compare: image widths or heights differ `./a.jpg' @ error/compare.c/CompareImageCommand/964.
```

# 経緯

自宅で仮作成したプログラムを会社に持っていったら上記エラー発生。
該当エラーで検索しても、サイズが違うとできないという記事ばかりヒット。
ただ自宅で作ったのはMac環境で、サイズが異なる画像でも比較画像が作成できていた。
会社のLinux環境（CentOS）では、上記エラーが出たことで、問題の切り分けを行った。

まずは、エラーが起こらないMacOSでのバージョンを確認。

```bash
# compare --version
Version: ImageMagick 7.0.8-28 Q16 x86_64 2019-02-19 https://imagemagick.org}
```

次に、エラーが起こるCentOSでのバージョンを確認。

```bash
# compare -version
Version: ImageMagick 6.7.8-9 2016-06-16 Q16 http://www.imagemagick.org
```

CentOSのyumでインストールを試みると、19.2.22時点で、`Ver. 6.7.8.9-15.el7_2` がインストールされるが、どうやらこのバージョンでは、サイズ差がある場合、補完してくれるわけではない様子。

# 最新のバージョンをインストールする

remi レポジトリーを追加し、ImageMagick7をインストールする

```bash
# yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
# yum install imagemagick7 --enablerepo=remi
# compare --version
Version: ImageMagick 7.0.8-28 Q16 x86_64 2019-02-18 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
```

これで、サイズの異なる画像でも画像比較などの処理が可能になる。
Paizaのスキルチェック問題や開発の際によく使うRubyのメソッドをまとめてみた

## はじめに
以前、某企業のエンジニアのコーディングテストを受けた際にリファレンスを見ながらではなく、ある程度のメソッドを覚えておく必要があると感じたので、復習がてらPaizaのスキルチェックや開発でよく使うRubyのメソッドをまとめてみました。

## slice
**引数に指定した分の文字列を取り出す**

```ruby
alphabet = "abcde"
alphabet.slice(1..2)
```

```
"bc"
```

## gsub
**文字列を置換する。**第一引数に変換したいパターン（正規表現）、第二引数に置換したい文字列を指定する。

```ruby
alphabet = "abcde"
alphabet.gsub(/bc/, "a")
```

```
"aade"
```

## sort
**sortは昇順と降順どちらに並び替えることが可能。**
<br>
まずは昇順に並び替えたい場合

```ruby
numbers = [5, 3, 2, 9, 1]
numbers.sort
```

```
[1, 2, 3, 5, 9]
```

<br>
次に降順に並び替えたい場合

```ruby
numbers = [5, 3, 2, 9, 1]
numbers.sort { |a, b| b <=> a }
```

```
[9, 5, 3, 2, 1]
```

## reverse
**文字列の場合、反転させる**

```ruby
name = "Taro"
name.reverse
```

```
"oraT"
```

<br>
**配列の場合は順番を入れ替える**

```ruby
numbers = [5, 3, 2, 9, 1]
numbers.reverse
```

```
[1, 9, 2, 3, 5]
```

## pushとunshift
**pushは、配列の末尾に指定した引数を追加する**

```ruby
alphabet = ["a", "b", "c", "d"]
alphabet.push("e") #alphabet << "e"でもOK
```

```
["a", "b", "c", "d", "e"]
```

<br>
**unshiftは、配列の先頭に引数で指定した要素を追加する**

```ruby
alphabet = ["a", "b", "c", "d"]
alphabet.unshift("0")
```

```
["0", "a", "b", "c", "d"]
```

## round
**数値を四捨五入する**

```
1.3.round
=> 1
1.5.round
=> 2
```

## chomp
**文字列の末尾にある改行文字を取り除く**（改行文字がない場合は何もしない）

```ruby
acquisition = gets #getsはキーボードで入力した値を文字列で取得するメソッド
```

```
hello
=> "hello\n"
```

```ruby
acquisition.chomp
```

```
=> "hello"
```

## uniq
**重複した要素を削除する**

```ruby
num = [0, 1, 1, 1, 2, 4]
num.uniq
```
```
[0, 1, 2, 4]
```

## map
**要素数だけブロックを実行し、ブロックを評価した新たな配列を作成して返す**

```ruby
numbers = ["0", "1", "1", "1", "2", "4"]
numbers.map { |item| item.to_i }
```

```
[0, 1, 1, 1, 2, 4]
```
</br>
上記のブロック部分は省略記法を用いる場合が多く、下記のようになっていることが多い。

```ruby
numbers = ["0", "1", "1", "1", "2", "4"]
numbers.map(&:to_i)
```

```
[0, 1, 1, 1, 2, 4]
```

## select
**ブロック内の戻り値が真になったものを新たな配列として返す**

```ruby
numbers = [0, 1, 2, 3, 4]
numbers.select { |item| item % 2 == 0 }
```

```
[0, 2, 4]
```

## join
**文字列を連結する**

```ruby
numbers = ["0", "1", "1", "1", "2", "4"]
numbers.join
```

```
"011124"
```
<br>

引数に区切り文字を指定して分けることもできる

```ruby
numbers = ["0", "1", "1", "1", "2", "4"]
numbers.join(",")
```

```
"0,1,1,1,2,4"
```

## count
**配列の要素数または、引数で指定した文字列or要素の数を数える**

## maxとmin
**最大と最小の値を返す**

## upcaseとdowncase
**それぞれ大文字と小文字にする**

```ruby
alphabet = "abcde"
alphabet.upcase
```

```
"ABCDE"
```

<br>

```ruby
alphabet = "ABCDE"
alphabet.downcase
```

```
"abcde"
```

## 

## abs
**絶対値を求めることができる**

```ruby
num = -1
num.abs
```

```
1
```

## おわりに
Paizaや開発で使っていたrubyのメソッドを紹介しました。随時更新していきたいと思っています。何かもっと便利でよく使ってるよというメソッドがあれば教えてください！
ConoHaのオブジェクトストレージをLinuxにマウントする(CloudFuse使用)

# CloudFuseとは？

https://github.com/redbo/cloudfuse

オブジェクトストレージを通常のファイルシステムのように扱えるようにしてくれるやつ（雑）
内部的にはcURLライブラリを利用しているようだ


# 前提条件

* ConoHaのオブジェクトストレージを契約していること
(ConoHaでなくても、OpenStack Swiftなオブジェクトストレージであれば対応できるかもしれない)


# 目的

* ConoHaオブジェクトストレージをLinux(Fedora)にマウントして、普通のドライブとして扱いたい。


# 手順

## 1. CloudFuseのインストール

```bash
$ sudo yum -y install fuse libxml2-devel json-c-devel libcurl-devel fuse-devel
$ git clone https://github.com/redbo/cloudfuse.git
$ cd cloudfuse
$ ./configure
$ make
$ sudo make install
```

検証環境では `/usr/local/bin/cloudfuse` にインストールされた。


## 2. ConoHa側の準備

ConoHaコントロールパネルから設定する

* 「オブジェクトストレージ」メニューより、オブジェクトストレージの容量を増やしておく
* 「API」メニューより、APIユーザーを作っておく(後で使用するのでパスワードを控えておく)
* 「API」メニューにて、下記情報を控えておく
    *  「テナント情報」より、テナントID、テナント名
    *  「エンドポイント」より、リージョンに応じた Identity Service の URI
    *  「APIユーザー」より、ユーザー名 (と、先ほど作成したパスワード)

## 3. マウントできるかテスト

設定ファイルを作る

```bash
$ vim .cloudfuse
```

```text:.cloudfuse
tenant=(テナント名)
password=(APIユーザーのパスワード)
authurl=(Identiry ServiceのURI)
verify_ssl=True
```

マウントポイントを作ってマウント

```bash
$ mkdir ~/conoha
$ cloudfuse ~/conoha
```

`Failed to authenticate.` と表示された場合は、`.cloudfuse`に書いた情報に誤りがあるのでチェック。


マウントされているか確認

```bash
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
(中略)
cloudfuse       8.0T  5.3G  8.0T   1% /home/kumasun/conoha
$
```

アンマウント

```bash
$ umount ~/conoha
```
(場合によって `sudo` しないといけないかもしれない)


## 4. fstabに書いて起動時に自動マウント

ちゃんとしたマウントポイントを作っておいて、そこに自動マウントしてみたい

```bash
$ sudo mkdir /mnt/conoha
$ sudo vim /etc/fstab
```

```text:/etc/fstab
(前略)
/usr/local/bin/cloudfuse /mnt/conoha fuse auto,_netdev,allow_other,gid=1001,umask=017,username=(APIユーザー名),tenant=(テナント名),password=(APIユーザーのパスワード),verify_ssl=True,authurl=(Identiry ServiceのURI) 0 0
```

|オプション|重要度|意味|
|---------|----|----|
|auto|任意|起動時に自動マウント|
|_netdev|**必須**|ネットワーク接続を待つ|
|allow_other|任意|他のユーザーによるマウントを許可する|
|gid|任意|グループID|
|umask|任意|パーミッションマスク|
|username|**必須**|ConoHaのAPIユーザー名|
|tenant|**必須**|ConoHaのテナント名|
|password|**必須**|ConoHaのAPIユーザーのパスワード|
|verify_ssl|任意|ピアとホストの証明書を検証する|
|auth_url|**必須**|ConoHaのIdentiry ServiceのURI|

その他はお好みで

**特に`_netdev`を書き忘れないように注意**
ネットワークが有効になっていない状態でマウントしようとして失敗し、最悪の場合セーフモードでしか立ち上がらなくなり詰む場合がある。

マウントできるかテスト

```bash
$ sudo mount -a
$ df -h
(中略)
cloudfuse       8.0T  5.3G  8.0T   1% /mnt/conoha
$
```


# あとがき

* 自分用にメモした手順です。必要に応じて読み替えてください。
* こうしたほうがいいよ的なアドバイスを頂けると大変助かります


以上
HerokuでPythonアプリをデプロイしてみた

# Herokuのインストール
<a href='https://dashboard.heroku.com/login' target='_blank'>Heroku</a>の会員登録をし、その後、<a href='https://devcenter.heroku.com/articles/heroku-cli' target='_blank'>Heroku CLI</a>をインストールしてください。


# 3つのファイルの準備

Procfile

```Procfile
web: python main.py
```


```requirements.txt
Flask==0.12.2
・・・
```

requirements.txtには自分が使用したモジュールの名前とversionを書いてください。
ターミナルでpip freezeをすると一覧が取得できます。


```runtime.txt
python-3.6.8
```


# Buildpacks

<a href='https://dashboard.heroku.com/apps' target='_blank'>Heroku</a>に移動し、SettingからAdd buildpackをクリックし、Pythonを選択してください。


# デプロイ
次は、ターミナルで、デプロイしたいアプリのディレクトリまで行き、以下のコードを実行してください。

```
$ heroku login
```

会員登録をしたメールアドレスとパスワードを入力してください。

```
$ heroku create アプリ名
$ git init(これは初回のみです)
$ heroku git:remote -a (アプリ名)
```

これでGitリポジトリが作成されたので、初期設定をします。

```
$ git add .
$ git commit -m “(何を変更したかメッセージを書く)”
$ git push heroku master
```

これでデプロイ完了です。
クリップボード監視テンプレ



クリップボードにテキストが格納されたら自動で取り出して
ごにょごにょしたいときのテンプレ。Macで利用。

```bash
#!/bin/bash

while :
do
	TXT=`pbpaste -Prefer txt`
	if [ -n "${TXT}" ];　then
		echo "" | pbcopy

		#
		# ${TXT} でごにょごにょ
		#

	fi
sleep 1s
done
```
1秒ごとに監視。
openFrameworksのアドオンofxQuadWarpを使ってプロジェクションマッピング

#1 はじめに
openFrameworksで簡単なプロジェクションマッピングする方法を共有します。

#2 環境
Visual Studio Community 2017
openFrameworks 0.10.1

#3 Visual Studio 2017のセットアップ
以下のサイトを参考に、Visual Studio 2017のセットアップを行う。ただし、「Visual Studio向けopenFrameworksプラグイン」は「前提条件が不足しているため、次の製品に拡張機能をインストールできません」とエラーが出てインストールできなかったため省略した。
https://openframeworks.cc/ja/setup/vs/

#4 openFrameworksのダウンロード
1. openFrameworksのサイトからopenFrameworksをダウンロードする。また、Visual Studio 2017で開発する場合はopenFrameworks for visual studio (2017)をダウンロードする。
https://openframeworks.cc/ja/download/
![openframeworks_download.png](https://qiita-image-store.s3.amazonaws.com/0/242136/34467136-2a1b-1363-ea4e-422821d0350d.png)

2. ダウンロードしたものを解凍し、任意のフォルダに置く

#5 プロジェクトの作成
1. ダウンロードしたopenFrameworksのフォルダにある、projectGenerator-vs\projectGenerator.exeを実行する

2. ウィンドウが表示されるため、自分の環境に合わせて設定する
  - Projection name:任意のプロジェクト名を設定する
  - Projection path:プロジェクトを作成するパスを設定する。デフォルトで入っているため、特に問題なければそのままにする
  - Addons:「ofxPoco、ofxOpenCv、ofxXmlSetting」を設定する

3. Generateをクリックする
![codeGenerator.png](https://qiita-image-store.s3.amazonaws.com/0/242136/30b413e6-6ab6-e857-9146-c1223ac93b4b.png)


4. GithubでofxQuadWarpをダウンロードする
   https://github.com/julapy/ofxQuadWarp/tree/master

5. 先程作成したプロジェクトのsrc配下にダウンロードした以下のソースコードをコピーする
  - main.cpp
  - ofApp.cpp
  - ofApp.h
  - ofxQuadWarp.cpp
  - ofxQuadWarp.h

6. プロジェクトのbinフォルダ配下に画像を置く

#6 ソースコードの修正
openFrameworks 0.10.1の場合、ofxQuadWarpはビルドエラーとなるため以下の修正を行う。
※Github上で0.10.1で動作するように修正するpull requestがあったので、その修正が適用されれば以下の作業は不要です

- 以下のインクルードを追加する

```ofxQuadWarp.cpp
 #include "ofxXmlPoco.h"
 #include "calib3d.hpp"
```

- ofXmlをofxXmlPocoに修正する

```ofxQuadWarp.cpp
// ofXml xml;
ofxXmlPoco xml;
```
#7 動作確認結果
四隅の点をマウスでドラッグ＆ドロップで動かし、プロジェクションしたい物体の四隅に合わせることができます。
![動作確認.png](https://qiita-image-store.s3.amazonaws.com/0/242136/efa50f4b-cfb8-3e01-e869-aa66cb4cde0a.png)

実際にプロジェクターで写した結果は以下となります。画像では荒いですが、実際は綺麗に写っています。
![IMG_0922.jpg](https://qiita-image-store.s3.amazonaws.com/0/242136/5dfaed89-73f5-e05e-9a86-25de12c98f85.jpeg)
pyenvを使ってpython 3.7系のインストールでエラーが発生した時の対処法(macOS Mojave)

#環境
macOS Mojave 10.14
pyenv 1.2.8

#pyenvを使って3.7.0のインストールでエラー
pythonを初めてインストールした時に[3.6.6のインストールで躓いた](https://qiita.com/hayatek/items/e183ca9c5bad4839aaa7)ので、とりあえずエラーが解決してよしとしていましたが、そろそろ3.7系をインストールしようと思って下記を実行。

```
$pyenv install 3.7.0
```
インストール途中で以下のエラーメッセージ表示。

```
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
```
エラーメッセージでググって見たらpyenvのgithubコミュニティで下記記事に辿り着きました。

[Python 3.7.0 :: The Python ssl extension was not compiled. Missing the OpenSSL lib? #1184](https://github.com/pyenv/pyenv/issues/1184)


macOS High Sierra 10.13.5で同様の事象が起きていた模様。色々解決策が書いてありますが、自分は下記でインストールできました。（openssl絡みのエラーっぽいですが、詳細は分かりません...）

```
$ brew install 'openssl@1.1'
$ CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl@1.1)" pyenv install 3.7.0
```
他にも色々とpyenv絡みのissueが挙がっているのでまずは似たようなエラーでissueを探してみるのも良いかもしれません。

[pyenvのissue一覧](https://github.com/pyenv/pyenv/issues)

#pythonの切り替え

```
$ pyenv versions
  system
* 3.6.6 (set by /Users/hiat/.pyenv/version)
  3.7.0
```
3.7.0に切り替え。

```
$ pyenv global 3.7.0
$ pyenv versions
  system
  3.6.6
* 3.7.0 (set by /Users/hiat/.pyenv/version)
```
3.7.0が使えるようになりました！
Fortranで連想配列を書いた話

# 概要

* FortranはC++等に比べて出来ることが限られていて変なプログラムを書きづらいのが美点。
* 個人的に色々不満はあるが、一番は連想配列が無いこと。
    * C++でいう`std::map`, Pythonでいう`dict`みたいなやつ。
* 仕事上Fortranを避けては通れないし、仕方がないので自分で書いた。

# 設計
実用的な連想配列の実装は大きく分けて二通り[^1]、平衡二分木とハッシュテーブルが候補に挙がる。それぞれの特徴を比較するとこんな感じだ。

||平衡二分木|ハッシュテーブル|
|----|----|----|
|概要|高さが要素数の対数程度になるような木を作る|キーにハッシュ関数を適用したものをインデックスとして配列にアクセス|
|挿入、削除、探索|O(log N) やや速い|O(1) 速い|
|k番目のキーにアクセス|できる|できない|
|留意点|単純な実装だとメモリ上非連続|キーが長い時はハッシュ関数が遅い[^2]|
|その他|**好き**|**あまり好きじゃない**[^3]|

私のユースケースでは順序でアクセスする必要は低そうだが、本能に従って実装は平衡二分木を採用した。

[^1]: Trieという決定木アルゴリズムもある、らしい。
[^2]: 平衡二分木で必要な大小比較は文字列の最後まで検証しなくても結果が分かることが多い。1000文字以上になると`std::unordered_map`より`std::map`の方が速くなる（[比較記事](https://qiita.com/Nabetani/items/78281cc98547f8edfea4#%E7%B5%90%E6%9E%9C%E3%81%9D%E3%81%AE1---%E6%96%87%E5%AD%97%E5%88%97%E9%95%B7%E3%82%92%E5%A4%89%E3%81%88%E3%81%A6%E8%A6%81%E7%B4%A0%E6%95%B0%E5%9B%BA%E5%AE%9A)）。実際そんなに長いキーが必要になるユースケースは私には無さそうだが。
[^3]: 余分に配列を確保しておいてハッシュが衝突したら盥回しというのがちょっとね。

# 木の選定と実装
あまり実装が重い木は正しく実装する自信が無いので、[秋葉大先生の資料](https://www.slideshare.net/iwiwi/2-12188757)に倣ってtreapを採用した。親子関係はheap、左右関係は二分探索木になっていて、ランダムに優先度を割り振ることで確率的に平衡が保たれる。

https://github.com/ysdtkm/fortran_associative_array

複数のキーや値の型を使いたい。最近のFortranはポリモーフィズムにも対応しているらしいが、実装が複雑になりそう[^4]なのでプリプロセッサで対応した。

[^4]: 複数の組み込み型のスーパークラス的なものを自分で書いてそのインスタンスへのポインタを扱えば良い、という認識だが使ったことは無い。

# 測定
<img src=https://github.com/ysdtkm/fortran_associative_array/raw/master/test/speedtest/visual/out.png width=50%>

* マイクロベンチマークでは、要素数200以上で線形探索より速かった。
    * 大体`std::map`と同程度。
    * 線形探索が案外速い。Treapは毎ノード挿入時にメモリ確保が必要なので、その辺が遅そう。
    * 趣味に走らずハッシュテーブルで実装したらもう少し速かったかもしれない、という後悔が残った。
    * (追記) 後日ハッシュテーブルで実装したら2-3倍速い。大体`std::map`と`std::unordered_map`の違いくらいだ。
        * fnv-1a (32bit)だと、ハッシュ計算が全体の約半分を占めるのでxxhashやmurmurのような速いハッシュで書いたらもっと速くなりそうだ。

# 補遺
連想配列を使える競プロの問題例

* k番目要素の操作 https://atcoder.jp/contests/arc033/submissions/4270463
* 座標圧縮
    * https://atcoder.jp/contests/abc036/submissions/4380905 (平衡二分木)
    * https://atcoder.jp/contests/abc036/submissions/4380846 (ハッシュテーブル)
* 数え上げ https://atcoder.jp/contests/abc091/submissions/4350818
新マリガンでトロンの揃う確率をモンテカルロシミュレーションで解く

こういう、どう考えても解析的に解いた方がいいやつをモンテカルロ法で近似したくなるのはカードゲーマーの性質ですね。しかしゲームの流れに沿ってプログラムを書けるので、キープ基準とか考え始めると素直に計算するよりこういう方法の方が楽です。新マリガンと旧マリガンで10万回ずつ試行しました。

```python
#新マリガン
import random

def tron():
    urza1 = [1,2,3,4]
    urza2 = [5,6,7,8]
    urza3 = [9,10,11,12]
    karn = [13,14,15,16]
    deck = range(60)
    hands = random.sample(deck, 7)
    if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
        return (1)
    else:
        hands = random.sample(deck, 7)
        if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
            return (1)
        else:
            hands = random.sample(deck, 7)
            if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
                return (1)
        return(0)

iters = 100000
tenhou = [tron() for i in range(iters)]
print(sum(tenhou)/iters * 100)

```

3.895%

```python
import random
#旧マリガン 占術はだるいので考えない

def tron():
    urza1 = [1,2,3,4]
    urza2 = [5,6,7,8]
    urza3 = [9,10,11,12]
    karn = [13,14,15,16]
    deck = range(60)
    hands = random.sample(deck, 7)
    if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
        return (1)
    else:
        hands = random.sample(deck, 6)
        if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
            return (1)
        else:
            hands = random.sample(deck, 5)
            if (len(set(urza1) & set(hands)) != 0) and (len(set(urza2) & set(hands)) != 0) and (len(set(urza3) & set(hands)) != 0) and (len(set(karn) & set(hands)) != 0):
                return (1)
        return(0)

iters = 100000
tenhou = [tron() for i in range(iters)]
print(sum(tenhou)/iters * 100)
```

2.127%

新マリガン：3.895%、旧マリガン：2.127%となりました。

占術もキープ基準も考えてないのであれですが、「一枚でも揃ってない場合は追いかける」と言うガバガバな戦略の場合、初手でトロンが揃う確率が2倍弱上がるようです。結構違うな。
Django のモデルで配列を使う

MariaDB をデータベースとした時の方法です。
PostgreSQL では別な方法になります。

次のようなテーブルを作成する例です。
![charlist_feb2301.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b5819b0b-ca8d-a177-6fd1-a847f36c2ed5.png)

```py:models.py
# ------------------------------------------------------------------
#
#	models.py
#
#					Feb/23/2019
# ------------------------------------------------------------------
from django.db import models
from django_mysql.models import ListCharField

class City(models.Model):
	code = models.CharField(max_length=10,primary_key=True)
	name = models.CharField(max_length=20)
	population = models.IntegerField(default=0)
	towns = ListCharField(
        	models.CharField(max_length=10),size=6, max_length=(6 * 11))
	date_mod = models.DateField()

	def __str__(self):
		return '<City: ' + \
			self.code + ', ' + self.name + '>'
# ------------------------------------------------------------------
```

 データベースには次のようなテーブルが作成されます。

```text
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| code       | varchar(10) | NO   | PRI | NULL    |       |
| name       | varchar(20) | NO   |     | NULL    |       |
| population | int(11)     | NO   |     | NULL    |       |
| towns      | varchar(66) | NO   |     | NULL    |       |
| date_mod   | date        | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+

```

必要なライブラリーのインストール方法

```bash
sudo pip install django-mysql
```

参考ページ
[List Fields](https://django-mysql.readthedocs.io/en/latest/model_fields/list_fields.html)
WSL環境でDockerが動作しなくなった

[WSL環境でDockerが動作しなくなった](https://xn--v6q832hwdkvom.com/post/wsl%E7%92%B0%E5%A2%83%E3%81%A7docker%E3%81%8C%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F/)の抜粋版です

うっかり`apt update && sudo apt -y upgrade`してしまったらWSL環境でDockerが動作しなくなった

## hello-worldしてみた

```Shell
$ docker run hello-world
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:301: running exec setns process for init caused \"exit status 23\"": unknown.
ERRO[0001] error waiting for container: context canceled
```

## 戻せそうなバージョンを確認する

`apt show [インストールパッケージ名] -a`でパッケージのインストールできるバージョンの一覧を取得できる

```Shell
$ sudo apt show docker.io -a
```

## 一旦削除して、バージョンを指定して再インストールする

```Shell
$ sudo apt remove docker.io
$ sudo apt -y install docker.io=17.12.1-0ubuntu1
```

## hello-worldも動いた

```Shell
$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
Twilioアカウントを作った直後に電話番号を取得する

<img width="1440" alt="スクリーンショット 2019-02-23 4.36.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/49fd31af-7164-3fd3-0262-a4394732c519.png">
[製品一覧] > [電話番号]を選択し、[続ける]をクリック

<img width="771" alt="スクリーンショット 2019-02-23 4.37.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/b6dffe9c-ba22-3ccf-57aa-c20b071930fc.png">
プロジェクト名を設定。

<img width="1034" alt="スクリーンショット 2019-02-23 4.38.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/5b4cd291-0d29-3238-1031-c84f939716a4.png">
チームメンバーはスキップ。

<img width="1237" alt="スクリーンショット 2019-02-23 4.38.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/278d972b-a1b9-2efe-a56c-571930dfa32e.png">
ダッシュボードトップに移動する。

[電話番号] > [電話番号を取得する]をクリックすると番号購入ページに移動する。

URL: https://jp.twilio.com/console/phone-numbers/search


<img width="961" alt="スクリーンショット 2019-02-23 4.40.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/33f36a61-f400-5fac-bdf6-f37d90a451dc.png">

japanを選択し、検索をクリック。

<img width="1387" alt="スクリーンショット 2019-02-23 4.40.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/23936/9fb1942a-8503-6545-0bbd-f232074912da.png">
電話番号が表示されればOK.

URL: https://jp.twilio.com/console/phone-numbers/search/buy/results?Country=JP&searchType=number&searchTerm=&align=left&capability%5B%5D=any&type%5B%5D=any&requirement%5B%5D=any&beta%5B%5D=true
だれでもできる物体検出

# はじめに
機械学習がもてはやされるので、試しにtensorflowを使って物体検出(Object Detection)をしてみたら、思いのほか簡単にできてしまったので、その記録。

# やるべきこと
今回は、ローカルのマシンでやっってみたのだが、下記の感じでできた。

- python3とライブラリの導入
- トレーニングデータの作成
- ベースとなるモデルの取得
- トレーニングの設定
- トレーニングの実行

# 結果
こんな感じに、ものを検出できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/365991/ea654330-4370-1348-5113-dad78c8f3dd4.png)

# 詳細
## python3とライブラリの導入
CentOS7にはpython3が入っていないのでPython3を入れるところから始めよう。

```shell
sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
sudo yum install -y python36 python36-libs python36-devel python36-pip
```

ライブラリは次のものがあればよい。

```shell
pip3 install tensorflow
pip3 install pandas
pip3 install pillow
pip3 install Cython
pip3 install matplotlib
```

## トレーニングデータの準備
下記のツールを使ってせっせとラベルづけします。
[labelImg](https://github.com/tzutalin/labelImg)


## モデルの生成

下記のリポジトリからモデルをcloneします。

```shell
git clone https://github.com/tensorflow/models.git
```
また、[このチュートリアル](https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10)にあるツールをもらってきます。

```shell
git clone https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10.git
```
generate_tfrecord.pyとxml_to_csv.py

## モデル取得
今回はssd_mobilenet_v2_cocoを使用します。

```shell
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
```


## 学習データの振り分け
学習データをトレーニング用とテスト用に分けます。例えば、images/testとimages/trainに分けます。

## tfrecordの作成
チュートリアルのツールを使ってtfrecordを作成します。まずはcsvを作成してから、tfrecordを作成するという流れになります。ただし、tfrecord生成ツール(generate_tfrecord.py)はチュートリアル用に作成されているので、一部改変が必要です。具体的にはclass_text_to_int:の部分を検出したいものに変更する必要があります。

```shell
python36 xml_to_csv.py
python36 generate_tfrecord.py --csv_input=images/train_labels.csv --image_dir=images/train --output_path=train.record
python36 generate_tfrecord.py --csv_input=images/test_labels.csv --image_dir=images/test --output_path=test.record
```
## 学習の設定
トレーニングの設定をします。設定ファイルはtrainingフォルダに置くことにします。
ひな形のconfigをコピーして編集してください。labelmap.pbtxtはtfrecordに記載した情報に合わせて記載してください。

## 学習の実行
下記のコマンドでトレーニングを開始します。

```shell
python36 ./legacy/train.py --logtostderr --train_dir=log --pipeline_config_path=training/ssd_mobilenet_v2_coco.config
```
ちなみに、GPUを使わないとめちゃめちゃ時間がかかります。覚悟は必要。


# 参考、詳細

[Tensorflowでライオンとネコを検出する](https://cafe-and-cookies.tokyo/wp/?p=814): おおもとの記事です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/365991/12071fe4-e49a-5249-6e23-19eeaf030fb9.png)
GASでリバースジオコーディングしてみた

今回はタイトル通り、
GASを使ってリバースジオコーディングする方法を紹介します！
GoogleMapsはクレジットカードが手間だったのでこの方法を試してみました。


以下様々なGASの記事を紹介してます！
https://bzbot.work/

##紹介記事
今回紹介している記事は以下です！
https://bzbot.work/2019/02/22/gas-reversegeocoder/

【図1 - 取得前】
![image.png](https://qiita-image-store.s3.amazonaws.com/0/363116/be0e9854-5edd-c43a-eb9e-793bfbba673a.png)


【図2 - 取得後】
![image.png](https://qiita-image-store.s3.amazonaws.com/0/363116/2f2c0579-75bc-4f5f-7edd-fd3ed9fd468e.png)


##実際のコード
```javascript:GAS
//*** http://express.heartrails.com/api.html 路線
//*** http://express.heartrails.com/api/xml?method=getStations&x=139.645683&y=35.443591 sampleAPIレスポンス
	

//*** http://geoapi.heartrails.com/api.html　緯度経度
//*** http://geoapi.heartrails.com/api/xml?method=searchByGeoLocation&x=139.77456498&y=35.68381981　sampleAPIレスポンス

var sheet = SpreadsheetApp.getActiveSheet();
function getGeocode(){
  var getflg = sheet.getRange(2,2).getValue();
  var test = Browser.msgBox("「" + getflg + "」で実行しますか？", "続けますか", Browser.Buttons.OK_CANCEL);
  if (test == 'ok') {
    //緯度経度の最終行を取得して、配列で取得
    var lr = sheet.getLastRow();
    var y = sheet.getRange(4, 1, lr).getValues();
    var x = sheet.getRange(4, 2, lr).getValues();
    var getflg = sheet.getRange(2,2).getValue();
        
    for(var i = 0; i <= lr-4; i++) {
        var lat = y[i];
        var lon = x[i];
        Logger.log(lat);
        Logger.log(lon);
      
        //分岐処理（エリアか駅情報か）
        if (getflg === "エリア"){
          //エリア取得Call（引数に緯度経度をトス） ;
          getArea(lat,lon,i)
        }else{
          //駅情報取得Call（引数に緯度経度をトス）  
          getStation(lat,lon,i);
        } 
    }
    if (test == 'cancel') {
      Browser.msgBox("キャンセルを押しました");
    }  
  }

function getArea(y,x,i) {

var url = "http://geoapi.heartrails.com/api/xml?method=searchByGeoLocation&x="+x+"&y="+y; 
  var response = UrlFetchApp.fetch(url);
  //  Logger.log(response.getContentText()); //レスポンス確認用
  var xml = XmlService.parse(response.getContentText());
  var entries = xml.getRootElement().getChildren("location");
  var err = xml.getRootElement().getChildren("error");
  var err_num = Number(err);
    if (err_num === 0.0){
      sheet.getRange(4 + i,3).setValue(entries[0].getChildText("prefecture")); 
      sheet.getRange(4 + i,4).setValue(entries[0].getChildText("city"));
      sheet.getRange(4 + i,5).setValue(entries[0].getChildText("town"));
    }
}


function getStation(y,x,i) {

var url = "http://express.heartrails.com/api/xml?method=getStations&x="+x+"&y="+y; 
  var response = UrlFetchApp.fetch(url);
  //  Logger.log(response.getContentText()); //レスポンス確認用
  // 名前空間
  var namespace = XmlService.getNamespace("urn:heartrails:express");
  var xml = XmlService.parse(response.getContentText());
  var entries = xml.getRootElement().getChildren("station",namespace);
  var err_num = Number(entries);
    if (err_num !== 0.0){
      sheet.getRange(4 + i,6).setValue(entries[0].getChildText("name",namespace)); 
      sheet.getRange(4 + i,7).setValue(entries[0].getChildText("line",namespace));
      sheet.getRange(4 + i,8).setValue(entries[0].getChildText("distance",namespace));
    }
  }
}
```