How to spend the terminal

技術ブログでさえない

Go言語でriver.go.jpからダムの貯水率を取得する

最近雨が降らないな、と思っていたらニュースで早明浦ダム取水制限が始まることを知り驚きました。 取水制限が始まるくらい貯水率が減っていたのなら早明浦ダムbotが毎時間ツイートしているだろう、 と思っていたら止まっていました。(2017/06/18現在動いています。)

作者の 103yen (@103yen) | Twitter さんによると、 river.go.jpの仕様が変わって貯水率を取得できなかったようです。

なんでbotが止まっていたかどうかわからなかったので、自分で貯水率を取得してつぶやこうと思いました。 作者さんのWebページ( ダムbotシリーズについて )とブログ( Pythonでriver.go.jpからダムの貯水率を取得する - 99円のへたれ日記! )を参考にしてGo言語で実装しました。(ほぼgoquery)

package main

import (
    "fmt"
    "log"

    "github.com/PuerkitoBio/goquery"
)

type Storage struct {
    date string
    time string
    pos  string
}

var (
    BASE_URL           = "http://www1.river.go.jp"
    OUTSIDE_URL_BEFORE = "/cgi-bin/DspDamData.exe?ID="
    OUTSIDE_URL_AFTER  = "&KIND=3&PAGE=0"
    ID                 = "1368080700010"
)

func GetPerOfStorage() (s Storage) {
    found := false
    outside_url := BASE_URL + OUTSIDE_URL_BEFORE + ID + OUTSIDE_URL_AFTER
    outside, err := goquery.NewDocument(outside_url)
    if err != nil {
        log.Fatal(err)
    }
    iframe := outside.Find("iframe")
    iframe_url, _ := iframe.Attr("src")
    contents_url := BASE_URL + iframe_url
    contents, _ := goquery.NewDocument(contents_url)
    contents.Find("tr").EachWithBreak(func(i int, tr *goquery.Selection) bool {
        if found == true {
            return false
        }
        tr.Find("td").EachWithBreak(func(j int, td *goquery.Selection) bool {
            if j == 0 {
                s.date = td.Text()
            } else if j == 1 {
                s.time = td.Text()
            } else if j == 6 {
                s.pos = td.Text()
            }
            if s.pos != "" && s.pos != "-" {
                found = true
                return false
            }
            return true
        })
        return true
    })
    return
}

func main() {
    s := GetPerOfStorage()
    fmt.Printf("%s %s %s\n", s.date, s.time, s.pos)
}

これで取得したデータをRubyを用いてツイートしました。

2時間ごとにツイートしていたのですが、早明浦ダムbotが復活したのでtwitterでのツイートはやめました。 (GNU socialでは毎時間クイップしてます)

Raspberry Pi 2 Model BでGNU social

この記事は、SLP KBIT Advent Calendar 2016 10日目の記事です。

はじめに

Twitterはことあるごとにダウンします。 自分はツイートをよくするのでじれったく思います。 Twitterは最近身売りを検討していると聞きます。 買収されるならともかく、もしTwitterがなくなったらどうすればいいでしょうか。

Twitterが使えない時にどのSNSを使えばいいでしょうか、FB、Instagram、LINEなど様々なSNSがありますが、Twitterの完全な代替となるようなSNSはほとんどないと思います。 しかし、その中でもGNU socialはTwitterの代わりになりうると思いました。

GNU social

GNU socialはTwitterのようなマイクロブログを提供するソフトウェアです。 名前の通りフリーソフトです。 GNU socialの目的はマイクロブログの連合を作ることによる中央集権化された資本主義なサービスからの離脱、とのことです。 ソースコードgithubで公開されているため、簡単に導入することができます。PHPで書かれているのでビルドの必要はありません。

導入した理由

以前より、 https://Quitter.no でアカウントを作ってクイップを行っていたのですが、GNU socialの思想が(フリーソフトウェアという思想の他に)自分のサーバに掲示板を建てたりするパソコン通信と似ているのではと思い、導入しようと思いました。導入の際にApacheとnginxの使い方を学ぶこともできました。

Raspberry Piを使った理由

Raspberry Piで建てられるなら安価でGNU socialを普及することができると思ったからです。RPiより安いマシンがあるかも

今回使ったRaspberry Piは「Raspberry Pi 2 Model B」です。

(2017/04/16 追記)OSはRaspbian Jessieです。

参考サイト

以下のサイトを参考にしました。

GNU socialのインストール - Akionux-wiki

Instalar GNUSocial en una Raspberry Pi - la Enredadera

GNU Social · Mesh network Practical Guide

導入まで

下準備

GNU socialには - PHP - MariaDB - サーバ

の3つが必要なので、 GNU socialのインストール - Akionux-wiki を参考にしてインストールします。

nginxを用いる場合、

sudo apt-get install git nginx php5 mariadb-server mariadb-client php5-curl php5-gd php5-intl php5-gmp php5-json php5-mysqli openssl exif gettext

で揃います。

MariaDBの設定

MariaDBにログインして、データベースを作ります(ここではsocialとします)。

CREATE DATABASE social;
GRANT ALL on social.* TO 'social'@'localhost' IDENTIFIED BY 'agoodpassword'

GNU socialのダウンロード

GNU Socialを適当なディレクトリにダウンロードします。

git clone https://git.gnu.io/gnu/gnu-social.git

ダウンロードしたら公開するディレクトリ(ここでは/var/wwwとします)にgnu-socialを移動して、書き込み権限を与えます。

sudo chmod a+w /var/www/gnu-social/

gnu-socialに - avatar - background - file

というディレクトリを作って書き込み権限を与えます。

nginxの設定

nginxの設定を GNU Social · Mesh network Practical Guide の"Confiugre Nginx Web Server to Server GNU Social"を参考にして行います。

基本的には参考元の設定(server_nameの名前は変える、httpsを使う場合はポート番号を443にしてSSL設定を追加する)を使えばいいのですが、httpでアクセスされた時にhttpsに変換するために次の設定を追加しました。

server {
  listen 80;
  server_name example.com;
  rewrite ^ https://$server_name$request_uri? permanent;
}

アクセス

アクセスしてうまく設定ができていれば初期設定ができます。初期設定ができれば導入完了です。

最後に

2ヶ月ほどの試行錯誤の末、GNU socialを導入することができました。

自分で立てたインスタンスなので、何をやっても自由です。 みなさんも自由な自宅SNSを立ててみてください。

グローバルIPの変更をメールで通知するシェルスクリプト

グローバルIPアドレスは固定サービスを使わない限り変わります。 IPアドレスが変わってしまうといろいろ困るため、メールで通知するようなシェルスクリプトを書きました。 DiCE使えばこんな面倒なことしなくていい

#!/bin/sh -eu

MAIL_TO="TO"
SUBJECT="SUBJECT"

globalip="/var/tmp/globalip" #"XXX.XXX.XXX.XXX"だけ書かれたファイル
tmp=`mktemp`
curl -sS inet-ip.info > ${tmp}
set +e
cmp ${globalip} ${tmp} > /dev/null
res=$?
set -e

ip=`cat ${tmp}`

mail_send () {
echo ${ip} | mail -s "$SUBJECT" "$MAIL_TO"
}

if [ $res -eq 1 ]; then
        mail_send
        cat ${tmp} > ${globalip}
fi

exit 0

このスクリプトの問題点はcurlを使うことで、この手のグローバルIPを教えてくれるサイトはよく落ちます。
そのため、複数の候補から応答するものを使うようにしようと思っています。 また、以前のIPが書いてあるファイルがなければ作るなど改良したい所はいろいろあります。

librubyのためにVimが起動できない(OSX)

Vimを起動しようとしたところ、

dyld: Library not loaded: /usr/local/opt/ruby/lib/libruby.2.3.0.dylib
  Referenced from: /usr/local/bin/vim
  Reason: Incompatible library version: vim requires version 2.3.1 or later, but libruby.2.3.0.dylib provides version 2.3.0

libruby.2.3.0.dylibがロードできないらしく、2.3.1のlibruby2.3.0.dylibを使って欲しいらしい。

こちらのサイト http://blog.masu-mi.me/2014/06/27/otool_vim.html を参考にして

ln -s /usr/local/Cellar/ruby/2.3.1/lib/*.dylib /usr/local/opt/ruby/lib/

上のようにするとすでに存在すると言われる。

ln: /usr/local/opt/ruby/lib//libruby.2.3.0.dylib: File exists
ln: /usr/local/opt/ruby/lib//libruby.2.3.dylib: File exists
ln: /usr/local/opt/ruby/lib//libruby.dylib: File exists

無理やり上書きするために

ln -snf /usr/local/Cellar/ruby/2.3.1/lib/*.dylib /usr/local/opt/ruby/lib/

とすると、Vimが使えるようになった。

Raspberry Pi 2 Model B購入

自宅サーバを作ろうと思いRaspberry Pi 2 Model Bを購入しました。
一式揃えて1万円ぐらい、安いです。
ラズパイ自体の初期設定は1時間ほどで済みました。
セキュリティ設定などが整うまでは我慢です。

XORの使用例

はじめに

みなさんはXOR(eXclusive OR, 排他的論理和)を使っているでしょうか? 排他的論理和は論理演算の中でも難しいと言われているので難しく感じるかもしれませんが、すごく応用が利きます。

XOR

XORは入力をx, yとしたとき、xとyが同一なら0、違えば1を出力します。

x y 結果
0 0 0
0 1 1
1 0 1
1 1 1

XORの特性として、2回同じ値でXORをとると元に戻ります。
例:

01101
10101
------
11000 ←1回目の計算結果
10101
------
01101 ←2回目の計算結果

また、x ^ y = zのとき、x ^ z = yとy ^ z = xを満たします。

使用例

使用例を見ていきましょう。

チェックサム

データが正しいかどうか調べるときに、一定の長さごとにXORをとって、全て0ならば、 そのデータは正しいと言えます。

XOR交換

XORを用いることにより、一時変数を用いずに値の交換が可能です。 x ^ y = zならばx ^ z = yとy ^ z = xを利用しています。

x = x ^ y;
y = x ^ y;
x = x ^ y;

1行目でxにx ^ y、つまりzが代入されます。
2行目でyにz ^ y、つまりxが、3行目でxにz ^ x、つまりyが代入されることになります。
一時変数を使わないのでメモリを節約できますが、CPUなどによっては一時変数を用いたほうが早いことがあるようです。

XOR暗号

2回同じ値でXORをとることで元に戻る特性を利用することにより、暗号鍵と復号鍵が同一な暗号を作成できます。
単一換字式暗号で暗号強度はとても弱いですが、非常に簡単に実装できます。

Xorshift

Xorshiftは擬似乱数生成アルゴリズムの一種で、実装が簡単で、高速です。
wikipediaに実装例が載っているのでそちらをどうぞ。

最後に

XORは非常に単純ながら、様々なことに応用できます。
論理回路を学んだとき、XORは便利と聞いて、何が便利なのか疑問に思っていましたが、実際便利です。
もしかすると、将来の技術もXORを利用する技術かもしれません。

日本語プログラミング言語 なでしこ

この記事はSLP KBIT Advent Calendar 2015 - Adventarの7日目の記事です。

なでしこについて

なでしこはクジラ飛行机氏によって作られたインタプリタ方式のスクリプタ言語です。この言語の最大の特徴は日本語でプログラミングができるということです。
ダウンロードは次のサイト(http://nadesi.com/top/)からできます。ダウンロードをしてすぐに使えます。

日本語プログラミング

大抵のプログラミング言語はアルファベットで記述します。日本語が使えるのはコメント、文字列、変数(Javaなど一部の言語)ぐらいでしょう。
日本語でプログラミングできるのはなでしこ、ひまわり、ドリトル、Mind、プロデル、Prolog(一部の処理系のみ)ぐらいであまりありません。トミー・・・ぴゅう太・・・頭の中で何かが

日本語プログラミング言語が少ない理由として、字句解析が難しいことがあります。ひまわりでは、読点やスペースで字句を区切らないといけないです。なでしこでは、助詞区切りを用いることにより自然に近い日本語で記述することが可能です。(「こんにちは」が「こん に ちは」と区切られるという問題があったりしますが)

日本語プログラミングの利点は何でしょうか?それは日本語圏の人が直感的にプログラミングできることでしょう。アルファベットを用いてプログラミングをするとき、日本語から英語に変換する必要があります。日本語プログラミングではその手順が必要ないのです。英語の方がわかりやすいとか言わない

書き方

なでしこは日本語プログラミング言語なので演算子等は全角でも可能です。

hello world

手始めにhello worldをしてみましょう。

「こんにちは、世界」と言う。

メッセージボックスが出ます。

こんなことも出来ます。

クジラが「こんにちは、世界」と言う。

クジラが「こんにちは、世界」と言いましたね。 このように、なでしこはGUIが作りやすいです。

変数

変数は文字列、整数、数値、配列、ハッシュの型があります。動的型付けになっています。 型宣言は

aとは変数。

と書き、変数宣言は

aは10
a = 10
10をaに代入。

の3種類があります。

四則演算

四則演算は演算子を使えますし、日本語で書くことも可能です。

aは10と5を足したもの
aは10と5の和
a = 10 + 5

条件分岐

条件分岐は、もし(if)、ならば(then)、違えば(else)を使います。

もし、aが10以上ならば
    「aは10以上」と表示する。
違えば、
    「aは10より小さい」と表示する。

繰り返し

n回繰り返したいときは、

n回
    (処理)

Cのfor文のようにカウンタで繰り返したいときは、

iで0から9まで繰り返す
    (処理)

while文のように条件が真の間繰り返したいときは、

iが9以下の間
    (処理)

配列

配列のアクセスは、

a¥0
a[0]

の2種類です。多次元配列は、

a¥0,1
a[0,1]

です。

ハッシュ

ハッシュは

香川@「うどん」は「さぬきうどん」
香川@「県庁所在地」は「高松市」

と書きます。マニュアルによると"@"は日本語の「の」に似ているからとのことです。

おすすめサイト

関連製品

  • なでしこデラックス版
    機能拡張版。2015年12月現在、一般版は10800円で、学生優待版は3240円(!)。(共に税込み)
  • 日本語プログラム言語なでしこ公式バイブル
    クジラ飛行机氏による公式解説本。欲しいです。

最後に

なでしこは文系サラリーマンのために役立つ言語と言われるように、MS Officeなどでの仕事の効率化を図ることができます。
もちろんそれ以外も可能で、様々なアプリケーションを作ることが可能です。
日本語のみで書けるので、英語がわからない人でも簡単にプログラミングを行うことができると思います。僕が最初に触れたプログラミング言語はひまわりでした。
今のなでしこはWindowsでのみ動きますが、現在開発されているなでしこ2.0ではC#で書かれているので、MacLinuxでも動くようになります。楽しみですね。