Rubyでwhat3words APIを使ってみる

What3WordsのAPIを使って自分の住所の3wordを取得する

はじめに

Rubyは気軽に書けて実行もすぐできるでいいですよね。
ということで、今回は外部のAPIを使って簡単なスクリプトを作ってみたいと思います。
今回使うAPIはWhat3wordsという位置情報サービスのAPIを使います。
今回作るものはエラー処理とか考慮していないのでちゃんと作りたい場合は、別途エラー処理を加えてください

What3wordsとは

What3wordsとは、世界中の住所を3つの単語で組み合わせて表現するものです。
世界中を3m ✕ 3mの正方形に区切るため、従来の住所より細かい位置を指定することができます。
余談ですが、京都の住所は長いと言われてますが碁盤の目の形を活かして、通りの名前 +「上ル」や「下ル」という組み合わせになっているそうです。そのため、この京都の違うところに住んでいる人に住所を伝えても大体の位置がわかるという話を聞いたことがあります。
What3wordsを使えば、京都の長い住所も3語で表現することができます。
まぁ、人にこの3語を伝えても位置は分からないわけですが。。。

今回作るスクリプト

今回作るスクリプトとは、住所から3単語を出すというものです。
下記のような感じです。

住所入力 → (API) www.geocoding.jp → (API) what3words → 3単語

スクリプト

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
require 'json'
require 'rexml/document'

if ARGV[0].nil?
exit 1
end

address = ARGV[0]

def get_geocoding(address)
# 住所を引数にして、問い合わせ
url = URI.encode("https://www.geocoding.jp/api/?q=#{address}")
uri = URI.parse(url)
xml = Net::HTTP.get(uri)

# 返ってきたXMLをパースし、緯度経度を抜き出す
doc = REXML::Document.new(xml)
return doc.elements['result/coordinate/lat'].text, doc.elements['result/coordinate/lng'].text
end

# 抜き出した緯度経度を引数にし、what3wordsに問い合わせを行う
# [APIKEY]の部分はwhat3wordsで取得する必要がある
def get_what3words(lat, lon)
uri = URI.parse("https://api.what3words.com/v3/convert-to-3wa?coordinates=#{lat}%2C#{lon}&language=ja&key=[APIKEY]")
json = Net::HTTP.get(uri)
result = JSON.parse(json)
end

# 各関数を呼び出す
lat, lon = get_geocoding(address)
json = get_what3words(lat, lon)

# 返ってきたjsonから単語だけを抽出する
puts json["words"]

実行/実行結果

1
2
ruby test.rb 東京都港区芝公園4丁目2−8
=> けんぶつ・このは・はかり

まとめ

こんな感じで住所から3単語を抽出できました。
ちなみに実行時に指定した住所は東京タワーのものです。
観光地だけに「けんぶつ」が含まれてますね!意図的なものだろうか気になる…

【Ruby】CSVファイルに読み込み/書き込みを行う

RubyでCSVファイルを扱う

はじめに

CSVファイルを読み込んでデータを整形したり、作ったデータをCSVファイルとして書き込んだりすることもあると思います。
Rubyで書いていきたいと思います。

読み込み

下記のようなCSVファイルを準備します。

1
2
3
4
aaa,bbb,ccc
ddd,eee,fff
ggg,hhh,iii
jjj,kkk,lll

CSVの内容すべてを読み込む

1
2
3
require 'csv'
CSV.read("test.csv")
=> [["aaa", "bbb", "ccc"], ["ddd", "eee", "fff"], ["ggg", "hhh", "iii"], ["jjj", "kkk", "lll"]]

CSVの内容を1行ずつ読み込む

1
2
3
CSV.foreach("test.csv") {|row|
p row
}

書き込み

CSVを作成する

1
2
3
4
5
CSV.open('hoge.csv', 'w') do |test|
test << [1,2,3]
test << [4,5,6]
test << [7,8,9]
end

モードについて

ファイルの書き込み/読み込みのモードが指定できます。

  • “r” 読み込み
  • “w” 書き込み
  • “b” バイナリモード
  • “a” 追記

まとめ

RubyでCSVのファイルの読み込み/作成をやってみました。
ファイルが存在したら追加、なければ新規作成とかってよしなにやってくれないだろうか…

【Ruby】 DateTimeとTimeの挙動の違い

DateTimeとTimeの違い

はじめに

会社のRails案件で日付/時間に関係した処理をいじることになったが、
日付/時間に関するクラスが多いため、どれを使っていいかわからなかった。
いろいろ調査や検証をしていると挙動が違うことが判明したため、記録として残す。

環境

Ruby 2.6.4

引っかかった点

DateTime.parseとTime.parseでは、挙動が変わってしまう。
これの結果を利用してDBへの問い合わせをやったら思ったとおりの挙動にならなかった。
下記の通りに挙動が違う。

1
2
3
4
5
6
# Time.parseはタイムゾーンを考慮したパース
Time.parse("2020-06-30 00:00:00")
=> 2020-06-30 00:00:00 +0900

# DateTimeはタイムゾーンは考慮されない
=> #<DateTime: 2020-06-30T00:00:00+00:00 ((2459031j,0s,0n),+0s,2299161j)>

ナルホド…タイムゾーンを考慮したTimeクラスを使用しよう!
さらに日付を計算するとまた違いが出てくる。

1
2
3
4
5
6
7
8
9
# Timeクラスで1を加算すると1秒が加算される
t = Time.parse("2020-06-30 00:00:00")
p t + 1
=> 2020-06-30 00:00:01 +0900

# DateTimeクラスで1を加算すると1日が加算される
d = DateTime.parse("2020-06-30 00:00:00")
p d + 1
=> #<DateTime: 2020-07-01T00:00:00+00:00 ((2459032j,0s,0n),+0s,2299161j)>

Timeを使いたいが加算をどう解決するか

1
2
3
4
5
6
7
8
9
10
11
# Railsであれば、ActiveSupport::Durationにday, week, month, year等の関数が存在
t = Time.parse("2020-06-30 00:00:00")
p t + 1.day
=> 2020-07-01 00:00:00 +0900

# Rubyであれば、普通に計算?
# うるう秒などを扱えるTimeクラスなのに自前で計算するとなると誤差が出そう
t = Time.parse("2020-06-30 00:00:00")
t = t + (60 * 60 * 24)
p t
=> 2020-07-01 00:00:00 +0900

参考

docomoから楽天unlimitへ移行しようとした話

楽天unlimitの申し込みをした

月々の料金が高すぎる

現在docomoを使っており、月々の支払い料金が7000円を超える事態となりました。

これは高すぎるので乗り換えようという話です。

楽天unlimitは今1年間料金が無料になっているのでそちらも活用したいなと思ってます。

楽天経済圏の話

2020年4月から株式投資を始めたのですが、勉強をしていく上で「楽天経済圏」という言葉を知りました。

「楽天経済圏」
楽天経済圏とは、日々の生活を一部を楽天のサービスを経由することでポイントをゲットしていくという方法です。

楽天のサービスは、下記のようなものがあります。
ショッピングサイトから始まり、証券や保険の他に電気、通信などのインフラまでサービスとして提供されています。

  • 楽天市場(ショッピングサイト)
  • 楽天ブックス
  • Rakuten Fashion
  • 楽天トラベル
  • 楽天toto
  • 楽天証券
  • 楽天生命

これらを活用することで楽天ポイントをゲットすることができます。
そのポイントをして投資に回すという手法です。
楽天unlimitの料金もポイントの対象です。

docomoから楽天unlimitにMNP転出をしたが…

docomoから楽天unlimitへMNP転出の申し込みをしました。
MNP転出と楽天モバイルの申し込みは素早くできました。
しかし、審査で問題が発生しました。

docomoの契約の名義人と楽天で申し込みを行った名義人が異なるという理由で弾かれてしまいました。

実際にdocomoの名義人を確認すると親の名前になっていました。
支払い者は私なのですが、契約時の名義人は親のままでした。

名義人を変えようとするが…

「じゃ、名義人を変更したらいいじゃん!」と思い、さっそくmy docomoから申し込みをしようとしましたが…

できない...

docomoの名義人変更について

docomoの名義人変更は、店舗での受付でしかやっていません。
しかもめんどくさいことに、現在の名義人と変更後の名義人が一緒に立ち会わないといけないようです。
それができない場合は、立ち会えない方の委任状を書いて来店しないといけないようです。

参考
名義変更 | お客様サポート | NTTドコモ

まとめ

結論としてまだ契約ができていないです。
まずは実家にいる親に委任状を書いてもらい、店舗に出向いて手続きをし、MNP転出して…めんどくさすぎます。
そもそも、コロナ禍でソーシャルディスタンスをとか言っているわりにはこういうことは融通が効かないのにおかしいと思ってしまいました。
マイナンバーで国民を管理できるのであれば、こういうことにももっと普及させるべきかなと思っています。
また、本人確認という点で言えばマイナンバー+免許証で本人であるとだろうと認めている企業もあるのになぜできないのかと思ってしまいます。
これだから「ハンコ文化」というものがなくならないんだろうなと改めて感じたできごとでした。

次購入する携帯を考える

携帯を変えたい

今、使用している携帯はMotorolaのMoto G3(XT1544)なのですが、購入してから5年ほど経過しました。

購入金額は、12000円ほどでさすがに元取るくらいしようしただろう&動作が不安定になってきたということもあり、乗り換えを検討しています。

どういった条件のスマートフォンを求めるか

私が求める携帯は、次のような条件のものです。

  • 防水
  • デュアルSIM
  • Felica対応
  • USB Type-C

防水

洗面台や台所といった水周りでスマートフォンを利用する機会が多いため、防水は必須です。

デュアルSIM

格安SIMに移行も検討しているので複数のSIMが使えるものがいいなと思っています。

DSDSやDSDVは、同時利用はできないようなのでDSDAであることが望ましいと思っています。

Felica対応

最近では、キャッシュレス対応の店舗も大分多くなったこともあり、私もほとんど財布を持つことなく出かけてます。

私がよく利用するのは、Line Payを使って買い物することが多いのですが、QRコード決済は対応店舗が限られてくることが多いです。

また、私としては決済を楽天にまとめたいと思っている(楽天経済圏)ので楽天Edyが使える環境がほしいなと思っています。

なのでFelica対応のスマートフォンがほしいと思っています。

USB Type-C

私の持っている端末のほとんどがUSB Type-B micro搭載の端末ですが、ここから脱したいというのが大きな目的です。
USB Type-B microは使用しているうちに端子の劣化などによりうまくスマートフォンが充電できないという事象が起きています。
これまでに買い替えたケーブルの数も尋常じゃないです。
今回をきっかけに我が家にもUSB Type-Cも導入したいです。

候補の端末

現状では、私の条件に合致する端末はありません。
やはり、DSDA対応端末が少ないというところがネックになっています。
しかし、デュアルSIM(DSDS、DSDVを含む)という大枠の条件であれば複数台あるようです。
2020/5/2現在。参考:価格コム

  • AQUOS zero2 SH-M13
  • AQUOS sense3 plus SH-M12
  • OPPO Reno A

他にもeSIMと組み合わせることでデュアルSIMを実現するという方法もあるようです。
例えば、iPhoneでeSIM + pSIMの組み合わせでDSDSが実現できるようです。

この組み合わせを利用すると、幅は広がりGoogleから公式で出しているPixelシリーズやAppleのiPhoneシリーズでDSDSが使えるようです。

結局どの端末にするのか

今の段階では、2020/5/22に発売されると噂のPixel 4aが候補の対象です。

Pixel 3aの段階でeSIMが使えたので今回もおそらく使えるため、候補に入れています。

参考

[再周知]スマホのDSDSやDSDVは同時利用ではなく「同時待ち受け」なので注意ポイントをピックアップ - ガルマックス

クラウドファンディングはおすすめしない

はじめに

昨年からクラウドファンディングで世に出る前の製品を見て、買うということをしています。
最近では、クラウドファンディングのサイトも増えてきており、製品の実現化以外にも個人の夢を実現するといったプロジェクトも増えています。

クラウドファンディングとは

いろんなところで取り上げてられているので知らない人はいないと思いますが、念のため。
クラウドファンディングとは、不特定多数の人や企業をインターネット上で募り資金調達をする仕組み。
Wikipediaによると群衆と資金調達を組み合わせた造語らしい。

私がこれまでに購入してきたもの

1. イヤホン(OVEVO Q63)

こちらはMakuakeで購入したワイヤレスイヤホンOVEVO Q63です。
私がクラウドファンディングで製品を購入するきっかけになった製品です。
2019年あたりからワイヤレスイヤホンが注目されてきて、私も1つほしいなと思い購入した1品です。
このワイヤレスイヤホンのいいところはノイズキャンセリング機能が搭載されていることと
付属されているイヤーピースがウレタン性で遮音性が抜群に良くなることでした。
この製品については、私も大満足で1万円ほどの支援で手に入れられたのでコスパ的にとても良いものでした。

2. タブレット(CHUWI Hi9 Pro)

こちらもMakuakeで購入したタブレットCHUWI Hi9 Proです。
国内企業が出している製品と同等のスペックで1.5万円 ~ 2万円ほど安く買うことができるとのことで買いました。
こちらのプロジェクトは大反響もあり、驚異の2000%という達成率を叩き出しました。
しかし、このあとに商品が発送されるまでの大幅な遅延や相次ぐ初期不良によって大荒れしたというのが記憶に残っています。

3. 折りたたみ乾燥機(H2go)

こちらはGreenFundingで購入した洗濯乾燥機H2goになります。
一人暮らしをしていく中で買っておけば良かったなぁと思ったのが乾燥機付き洗濯機でした。
しかし、実際一人暮らしをしていると1K6畳の部屋で乾かす場所も無ければ、乾くまではエアコンを使用して乾かしていました。
いわいる家電量販店で売っているような置型の乾燥機を買うなんてこの狭さではもってのほかです。
乾燥機欲しいと思っていたところに出たのが、この折りたたみ式乾燥機でした。

このプロジェクトは2月末にはプロジェクトが達成し、終了していますが私の手元にはまだ届いていないです。

メリット

  • 市場に出回る前に製品をゲットできる
  • プレリリース版なので価格が安い
  • 単純に応援ができる

デメリット

  • 海外の企業だと対応が遅い(問い合わせ・配送)
  • プロジェクト終了後のサポートが悪い
  • 市場に出回る製品とくらべて、性能が劣る(可能性)

なにが不満なのか

今回不満になったのは、海外企業が出しているプロジェクトで対応の悪さや配達遅延に関してです。
タブレットにしろ、乾燥機は海外企業のプロジェクトですが、配送の遅延等がすごい目立ちます。
ほとんどのプロジェクトでは、企画・立案・開発・テストみたいな流れをスケジュールとして出すのですが、それが一切守られていないように感じられました。
また、クラウドファンディングなので日本で試してみようというテストを含めたプロジェクトであることから日本支部が存在しないまたは、日本企業のようなサポートが受けられないというところに不安がありました。
こういうことが重なったので私としてはクラウドファンディングはおすすめしない(特に海外企業のプロジェクトは)ということでした。

Terraformを使ってMySQLのDBユーザを管理する

はじめに

コロナウイルスの影響もあり最近は家にいる時間が明らかに増えてきました。
今までのようには出かけられなくなって残念という気持ちの反面、自分への投資ということで最近は投資や技術の勉強に勤しんでいます。
DBのユーザの管理方法を見直すということで、Terraformを使った管理方法を試していました。
あまり記事が出ていなかったのでこちらに残します。

作業準備

作業を行うディレクトリを作成します。

1
2
# 作業用ディレクトリを作成、移動
mkdir ~/mysql_management && cd $_

tfenvを使ったTerraformのインストール

brewでの管理はあまり好きではないので今回はgithub上のリポジトリからクローンしてきます。

1
2
3
4
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
cd ~/.tfenv
# 最新でエラーが出たのでバージョンを落として使用
git checkout v1.0.2

パスを通す

1
2
3
4
5
# bashの場合
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile

# zshの場合
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.zsh_profile

各ディストリビューションごとの設定については、細かい設定についてはtfenvのREADMEを参照ください。

これでtfenvが使えるようになると思います。

次はTerraform自体のインストール

1
2
3
tfenv install 0.11.14
tfenv use 0.11.14
terraform --version # バージョンが表示されたらOK!

DockerでMysql環境を作成する

今回は、お試しということでMySQL環境をDockerで立ち上げます。

1
2
3
4
5
6
7
8
9
10
docker pull MySQL
docker run -it --name test_db -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# 立ち上げたコンテナ上にログイン
docker exec -it test_db bash -p

# コンテナ上でmysqlをユーザを確認
mysql -u root -proot
use mysql;
select * from user\G;

PGP鍵を使ったパスワード生成

まず、GPGのインストール

1
brew install gpg

次は公開鍵、秘密鍵の作成

1
2
3
4
5
6
7
8
9
10
11
gpg --gen-key

# 本名など聞かれますが、今回はtest_userで作成
# そのほかメールアドレスとは空欄でスキップ
本名: test_user
...
名前(N)、電子メール(E)の変更、またはOK(O)か終了(Q)?: O

# 画面が変わり鍵にかけるパスフレーズの設定を促す画面が表示される
# 任意のパスフレーズを入力(2回入力する)
# うまくいけば鍵が生成される

鍵の出力

1
2
3
4
5
6
7
8
9
10
11
12
13
# 公開鍵をファイルとして出力
gpg --output test_user.public.gpg --export test_user

# 秘密鍵をファイルとして出力
gpg --output test_user.private.gpg --export-secret-keys test_user

# 出力されたファイルを確認
# 公開鍵と秘密鍵の2つができていればOK
ls *.gpg

# Terraformに設定するため公開鍵をbase64にエンコードしたものを取得
# 大量の文字列が表示されるのでコピー
cat test_user.public.gpg | base64

PGP鍵についてこれにて完了

Terraformの設定

長い道のりでしたが、ようやく本題です。
Terraformのファイルを作成していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
variable "pgp_key" {
# 先程の公開鍵をエンコードしたもの(cat test_user.public.gpg | base64のやつ)
default = ""
}

provider "mysql" {
# DBのエンドポイント
endpoint = "127.0.0.1:3306"
# ユーザを書き込むユーザ(今回はroot)
username = "root"
 # ユーザを書き込むユーザのパスワード
password = "root"
}

# 追加するユーザを記述
resource "mysql_user" "chunli" {
# ユーザ名
user = "chunli"
# Userテーブルのhostに設定される値
host = "%"
# variableに設定したpgp_keyが設定される
pgp_key = "${var.pgp_key}"
}

output "encrypted_password" {
value = "${mysql_user_password.chunli.encrypted_password}"
}

Terraformを実行してみる

ここまでで準備ができました。
Terraformを実行してみましょう。

1
2
3
4
5
6
7
8
# 初回はinitを行う
terraform init

# dry-run(DBには反映されず、結果のみ表示)
terraform plan

# run(実行)
terraform apply

結果を確認してみましょう

1
2
3
4
5
6
7
8
9
# パスワードを取得する
terraform output encrypted_password | base64 -D | gpg -d

# 立ち上げたコンテナ上にログイン
docker exec -it test_db bash -p

# コンテナ上、先程作ったユーザと取得したパスワードでログイン
# ログインできたらOK
mysql -u chunli -p

まとめ

TerraformでMySQLユーザの管理を行ってみました。
PGPの部分はkeybaseを使ってパスワードを生成することもできるみたいなので、
気になるかたはやってみてください。

WealthNaviとクラウドバンクで投資 〜26日目〜

WealthNaviとクラウドバンクで投資 〜26日目〜

26日目の結果

WealthNavi

投資金額: ¥200,000 → 現在の金額: ¥147,111 差額: -¥52,889

内訳

投資先

金額

米国株(VTI)

¥46,910

日欧株(VEA)

¥35,591

新興国株(VWO)

¥12,323

米国債券(AGG)

¥28,580

金(GLD)

¥16,644

不動産(IYR)

¥6,543

現金

¥520

まとめ

コロナウイルスにより世界的に経済が落ち込んでいます。 2日連続のサーキットブレーカー発動するなどの下落っぷりです。 とりあえずガチホします。

WealthNaviとクラウドバンクで投資 〜14日目〜

WealthNaviとクラウドバンクで投資 〜14日目〜

14日目の結果

WealthNavi

投資金額: ¥200,000 → 現在の金額: ¥186,745 差額: -¥13,255

内訳

投資先

金額

米国株(VTI)

¥62,744

日欧株(VEA)

¥49,498

新興国株(VWO)

¥16,519

米国債券(AGG)

¥29,752

金(GLD)

¥18,388

不動産(IYR)

¥9,366

現金

¥478

まとめ

昨日よりも回復してきました。 まだまだコロナの影響は強そうです。

WealthNaviとクラウドバンクで投資 〜13日目〜

WealthNaviとクラウドバンクで投資 〜13日目〜

13日目の結果

WealthNavi

投資金額: ¥200,000 → 現在の金額: ¥182,885 差額: -¥17,115

内訳

投資先

金額

米国株(VTI)

¥60,484

日欧株(VEA)

¥48,296

新興国株(VWO)

¥16,331

米国債券(AGG)

¥29,850

金(GLD)

¥18,402

不動産(IYR)

¥9,044

現金

¥478

まとめ

コロナウイルスの影響で株価が大暴落しています。 さすがにWealthNaviも引き出されることを恐れてかメールやメッセージで通知を行っていました。 回復するまで辛抱です。