brown water

ゲームやアニメの感想とかプログラムとか

さくらのVPSに挑戦2(プログラム実行編)

前回VPSの環境を整えたので、今回は実行するプログラムを作っていきます。

作るプログラム

PHPで定期的にTwitterのトレンドを取得して、データベースに保存するプログラムです。
TwitterAPIを使うためにアカウント、アクセスキー等を取得する必要がありますが、方法は割愛します。

データベースの作成

今回はtwget_dbというデータベースを作り、twtrendというテーブルを作ってその中にデータを入れていきます。

mysql -u root -p

でログイン

create database twget_db;
grant all on twget_db.* to twuser@localhost identified by 'paSS%888';

↑twuserは適当なユーザー名、byの次の文字列はパスワード設定です。
これで、twuserがtwget_dbにアクセス出来るようになりました。
次にテーブルの作成

use twget_db
create table twtrend (
    name text,
    day datetime
);

トレンドで取得した単語と日時を格納するテーブルです。
一旦exitで抜けて、

mysql -u twuser -p twget_db

でログインします。
先ほど作ったtwuserでログイン出来ました。
後で確認するためにこれは開いたままにしておきます。

PHPの作成

TwistOAuthという、TwitterAPIから取得するために便利なライブラリを用意します。
github.com ダウンロードした中にある、「TwistOAuth.phar」というファイルを使います。

設定用の値は後で使い回すため、config.phpにまとめておきます。
CONSUMER_KEY等はTwitterで取得した値を入れます。
DB_〜は今回設定したデータベース名、ユーザー名、パスワードです。

//config.php
<?php
define('CONSUMER_KEY', 'xxxxx');
define('CONSUMER_SECRET', 'xxxxx');
define('ACCESS_TOKEN', 'xxxxx');
define('ACCESS_TOKEN_SECRET', 'xxxxx');

define('DB_DATABASE', 'twget_db');
define('DB_USERNAME', 'twuser');
define('DB_PASSWORD', 'paSS%888');
define('PDO_DSN', 'mysql:dbhost=localhost;dbname='.DB_DATABASE);
//twtrend.php
<?php
require_once('config.php');
require_once('TwistOAuth.phar');

$connection = new TwistOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);

try {
    $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $params = ['id' => '1110809', 'exclude' => 'hashtags'];
    $tweets = (array) $connection->get('trends/place', $params);
    
    #日時を変換
    $day = date('Y/m/d H:i:s', strtotime($tweets[0]->created_at));
    
    foreach($tweets[0]->trends as $tweet) {
        $stmt = $db->prepare("insert into twtrend (name,day) values (?,?)");
        $stmt->execute([$tweet->name, $day]);
    }
    
} catch (PDOException $e) {
    echo $e->getMessage();
    exit;
}

APIにある「trends/place」を使って取得しています。
id 1110809は日本、exclude hashtagsはハッシュタグを除くという設定です。

syncer.jp ここのページを見ると他にも応用が出来ると思います。

ラブライブ!コラボキャンペーン

PHPからMySQLに接続するPDOに関しては、ドットインストール等を参照して下さい。
今回作成したconfig.php、twtrend.phpと、ライブラリのTwistOAuth.pharを転送ツールでアップロードします。
FileZillaというソフトを使いました。
アップロード先は/var/www/html/の中です。
アップロードしたら、ブラウザからIPアドレスを入力し、
xxx.xxx.xxx.xx/twtrend.php
でアクセスすると起動します。

今回は取得して書き込むだけのため、画面には何も表示されません。 先ほど開いておいたmysqlの画面で、

select * from twtrend;

を実行して内容が表示されれば成功です。
f:id:chaz4:20180212194401j:plain 短時間で何度もPHPを実行すると同じ内容がどんどん追加されていってしまいます。

delete from twtrend;

でテーブルの中身を空にすることが出来ます。

crontabで定期実行

トレンドを一定時間ごとに取得したいので、crontabを使います。
サーバーにログインした状態で、

crontab -e

でファイルを開き、記述していく。

*/10 * * * * /usr/bin/php /var/www/html/twtrend.php

左端が「分」で、今回は10分ごとに実行します。
phpファイルの実行には /usr/bin/php の記述が必要なようで、その後に実行したいファイル名を書いていきます。
保存して抜けた後、

service crond restart

で有効にしておきます。
これで10分ごとに先ほどのプログラムが実行されて、データベースに書き込まれるはずです。

表示用ファイルの作成

ブラウザから見るためのファイルを作っていきます。
単に全件取得してulタグの中に入れていくだけです。
そのままだと見づらいので、cssも設定してみました。

//puttrend.php
<?php
require_once('config.php');

$twdata = '';

try {
    $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $db->query("select * from twtrend");
    $twdata = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (PDOException $e) {
    echo $e->getMessage();
    exit;
}
?>

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="utf-8">
   <title>tw trend</title>
   <link rel="stylesheet" href="tw.css">
</head>
<body>
    <ul>
        <?php
            if($twdata) {
                foreach ($twdata as $tweet) {
                    echo "<li><span class='name'>".$tweet['name']."</span><span class='day'>(".$tweet['day'].")</span></li>";
                }
            }
        ?>
    </ul>
</body>
</html>

f:id:chaz4:20180212194822j:plain

無事にブラウザからも表示することが出来ました!
今回は単にそのまま表示するだけでしたが、SQL文を変えると単語を集計して多い順に並べて表示する等も簡単に出来ます。


Amazon.co.jpアソシエイト

さくらのVPSに挑戦1(環境構築編)

さくらのVPSを使って、2週間の無料お試し期間の間に設定等をしてみました。

ドットインストールにレッスンがあるので、それを見ながら進めていたのですが、途中ハマった箇所等があったのでメモしておきます。

環境等

ローカルの環境はUbuntu16を使います。

登録後、メールでパスワード等が送られてくるので、ブラウザでそこに記載されているコントロールパネルのURLにアクセスし、ログインします。

OSのインストール

f:id:chaz4:20180212192050j:plain 標準OSの中の「CentOS6」を選択します。
管理ユーザー名が「root」であることを覚えておき、あとは好きなパスワードを設定します。
インストールを開始し、稼働中になれば完了です。

作業をしていってどうにもならなくった時に、OSの再インストールをしてやり直すというのを何度かしました(汗)

OSもいくつか試しましたが、インストール自体は30秒くらいで終わるので思ったよりも気軽に出来ます。

インストール後、アップデートをかけるわけですが、CentOS7とUbuntu16はアップデートの時間が結構長いのに対し、CentOS6はアップデートがないためすぐ使えます。(2018/2/12現在)

今回はセットアップの練習用だし、すぐにやり直し出来るCentOS6が良いと思いました。

あと、プライベートではUbuntuをメインに使ってるからサーバーもそうしたいと思ったのですが、サーバー関係の情報はCentOSの方が多いようです。

サーバーにログイン

何度かやり直しているせいか、秘密鍵があるとログイン出来ないようです。
秘密鍵を複数管理したり、設定し直すやり方は知らないので、簡単にするために先に削除しておきます。
/home/ユーザー名/.ssh/ の中にあるので、ディレクトリの中を空にしておく。
準備が整ったらローカルで端末を起ち上げ、

ssh root@xxx.xxx.xxx.xx

でログイン。xxxは記載されているIPアドレス
yesで答え、インストール時に設定したパスワードを入力するとログイン出来ます。

本来ならこの後、秘密鍵を作ったり作業用ユーザーを作ったりするのですが省略してrootのまま続行します。

ポート番号の変更

デフォルトでは22になっていて広く知られているため、適当な番号に変更します。1024~65535の間で設定可。
念の為にバックアップをとってから編集していきます。

sudo vim /etc/ssh/sshd_config

上の方に「#Port 22」と書いてある所があるので、#を外して有効にします。
この次の行に好きな番号を「追記」します。
ここの22を書き換えてもいいのですが、そうするとハマりました。
書き換えた番号のポートでログイン出来るようになるはずですが、ファイアウォールの方も同じ番号を開放しないとログイン出来ません。
なので、書き換えてしまうとログアウトした後に22も使えなくなり、ログイン出来なくなります・・・。
失敗したらOS再インストールすれば大丈夫です(笑)

とりあえずは新しい番号と22の両方を指定しておきます。

Port 22
Port 12345

保存して抜ける。

ファイアウォールの設定

こちらもバックアップをとってから編集していきます。

sudo vim /etc/sysconfig/iptables

dport 22というのが書かれている行をそのままコピーして、こちらも新しい番号を追記していきます。
先ほど設定したPort番号と、あとは80も同じように追記します。
80はhttp通信を行うポートで、これを開けておかないとブラウザから見ることが出来ません。これもハマった・・・。

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 12345 -j ACCEPT

保存して抜けたら、設定を有効にする。

service sshd restart
service iptables restart

一旦exitで抜けて、ポート番号を指定してログイン出来るか確認する。
-pの後に先ほど設定したポート番号を入れる

ssh -p 12345 root@xxx.xxx.xxx.xx

ログインに成功したら完了。
まだポート22からアクセス出来る状態なので、
sshd_configとiptablesの22を削除し、設定を有効にすればOKです。

全国送料無料!IT書、ビジネス書、資格書が豊富なSEshop

アパッチのインストール

yum install httpd

chkconfig httpd on
service httpd start

インストール後に設定ファイルを変更するのですが、省略。このままでも動くようです。
アパッチが起動したらブラウザからIPアドレスを入力し、初期画面が表示されたら成功です。
f:id:chaz4:20180212193020j:plain /var/www/html/ のディレクトリにあるファイルを読むので、ここにindex.html等を入れてページを表示させることができます。

PHP7のインストール

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

yum install --enablerepo=remi,remi-php70 php php-mysqlnd php-gd php-xml php-xmlrpc php-mbstring php-mcrypt php-fpm php-opcache php-apcu -y

インストール後、設定ファイルを書き換えます。
/etc/php.ini

error_log = php_erros.log を /var/log/php_errors.log
date.timezone = "Asia/Tokyo"
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.detect_order = auto
expose_php = on を off

行頭のコメント(;)を外して有効にする、または書き換える。
保存したらhttpd再起動

service httpd restart

MySQL5.7のインストール

yum localinstall http://dev.mysql.com/get/mysql57-community-release-el6-8.noarch.rpm

yum install --enablerepo=mysql57-community mysql-community-server

chkconfig mysqld on
service mysqld start

無事にインストール&起動が出来たらパスワードの変更をしていきます。
/var/log/mysqld.logに初期パスワードが書かれているので開いてメモっておく。
見づらいのですが、6行目にありました。

A temporary password is generated for root@localhost:  ★★★

★の所がパスワードです。
なお、パスワードは大小の英文字、数字、特殊文字がそれぞれ1つ以上含み、8文字以上の長さが必要です。

mysql_secure_installation

で先ほどメモったパスワードでログインすると、新しいパスワードを聞かれるので入力、そして再度入力。
他はEnterを押して抜けます。 今回は Pass!555 にしてみました。

続いて /etc/my.cnf を編集していきます。

character-set-server=utf8
default-storage-engine=InnoDB
[mysql]
default-character-set=utf8

上記を追記して保存、

service mysqld restart

で再起動して設定を有効にします。

これで各種インストール&設定が終わったので次回はこれを使ってプログラムを書いていきたいと思います。


Amazon.co.jpアソシエイト

【ブレズオブザワイルド】祠120箇所クリア!

今更ですが、ゼルダBtoWの祠全120箇所をクリアしました。

発売日に買ってから約9ヶ月、最近はたまにちょこちょこプレイするぐらいでした。
毎日少しずつですが進捗状況が更新されていってました。コログ見つけた等。
祠に関しては、何度同じ場所を探し回ったことか・・・。

最後の祠、場所はここだろうというのは分かってたんですが、イベントが発生しなくて。
ほこらチャレンジに載っていなかったので確信はなかったけど。

何度も通っていたらある時に他のイベントが発生し、その後祠イベントも発生してようやく進むことが出来たのでした。

祠コンプに貰ったご褒美がこれ。

f:id:chaz4:20180107224728j:plain

やっぱりリンクと言えばこの緑の服ですね。


Amazon.co.jp アソシエイト

ペーパードライバー教習

車を運転しなければならなくなったため、ペーパードライバーを克服するべく教習を受けてきました。

田舎に住んでいた時は車が必要だったために通勤等で毎日運転していたのですが、都会に住んでからはほとんど運転していませんでした。
この度必要に迫られ、実に20年ぶりに運転してきました。

どんな所があるのか

20年ぶりにというわけで、いきなり一人で運転するのはやっぱり怖いので、ペーパードライバーのための教習を探していました。
自動車学校で行っている所と、出張専門の所があるようで、今回は出張の方を選びました。

出張の方が料金的にも安いようで、1時間あたり5~6000円くらいが相場のようです。
あと、出張だと自宅付近まで迎えに来てくれるので楽です(笑)
イカー持ってないので教習車で来てもらいました。
イカーでしか受けられない所もあるのでよく確認しましょう。

不安な点は、出張だと最初から公道を走ることです。この辺は教習所だと広い敷地内の道路で練習出来るので気が楽ですね。

 

今回はここで教習を受けました。

ペーパードライバー教習のサワムラガク東京 l 1日卒業のペーパードライバースクール

 

この記事も読み、アイドルも受講してるんだ!と思って予約しました(笑)

car-moby.jp

予約していよいよ実践へ

前日から降り続いている雨が止まず、この天気で運転するのかと気が滅入っていましたが、予約時間の30分前から雨が止んで晴れてきた!
約束の時間に待ち合わせ場所の駅前で車を探す。
フィットということで探したが見つからず、しばらくして一台の車から人が出てきて声をかけてきたので無事合流、軽く挨拶をしながら助手席に乗り込んで、とりあえず広い道路がありそうな所まで行った。

f:id:chaz4:20171230003914j:plain
あまり車には詳しくないけれど、フィットと言えば特徴がある形をしているし、↑これですよね。

しかし実際に来た車はこれ。↓

f:id:chaz4:20171230004012j:plain

普通のセダンだし、これじゃ分かりません。
書いてた車と違うじゃないか!と思ったんですが、この車は「フィットアリア」という名前のようです・・・。
間違ってはいないけど、う〜ん(笑)

 

補助ブレーキを装着、どんなのだろうと思ってたけど単に棒の先をブレーキに巻きつけてるだけだった。
席を交代し、いよいよ運転席へ。
シートベルトを締め、座席の調節、ミラーの確認。こういう基本的で忘れてしまっていることもちゃんと指導してくれます。

そして遂に発進。緊張しながらシフトをDへ・・・あれ?
サイドブレーキがかかってますよ」
「あとウインカーも付けないと」
・・・先が思いやられます。

慣れてくると楽しい

ようやく発進。まずはゆっくりとしたスピードで周りに注意しながらほぼ直進のみ。
住宅街のため細い道が多かったが、あまり怖さは感じずに進めました。
20年ぶりに感じた、この運転しているとう感覚はなかなか楽しい。

しばらく慣れてきた所で別の道路に行くことに。
こちらは大きい通りのため先ほどよりは交通量が多いが、道も広いため運転はしやすい。
また直進ばかりですが、他の車もそれなりに走っているので注意が必要だし、路上駐車等もかわしながら進まないといけません。

交通の流れに乗って信号や標識に注意しながら停止と発進、右左折。当たり前のことですが、この感覚をようやく思い出してきて、運転しているという感じになってきました。

だいぶ慣れてきたところで再び住宅街に入り、細い道での右左折の練習をすることに。
これがなかなか難しく、左折する時に前方に大きく膨らんでしまったり、早めにハンドルを切ると今度は電柱にぶつかりそうになり・・・タイミングが掴めない。

一度指導員の方に交代して実技で見せてもらいながら説明を受けたら何となくは分かってきました。
それでも実際にやってみると上手くいかず、やはり何度も練習して慣れるしかないようです。

右折の方は楽だった。左折時よりも距離があるからのようです。

駐車が難しかった

ここで一旦休憩するためコンビニの駐車場に停めることになった。
空いてるスペースにもちろんバックで入れるわけですが、とても無理です・・・。
指導員の指示に従いながらハンドルとシフトを操作、少しずつバックしていくのだが、ミラーを見てると隣の車にぶつかりそうにしか見えないが、何とかぶつからないようだ(汗)
車体が真っ直ぐになったところでハンドルを戻しての指示。
しかし戻し過ぎで逆方向に進んでる・・・。
何回ハンドル回しましたか?と聞かれたが分からず(笑)
一旦前進したらハンドルが自動で戻ってきた。
ここで再びバックをして無事に駐車成功。一人だったらまず無理ですね・・・。

休憩後、気を取り直して出発。大通りを通って自宅方面に向かいます。
今回の教習も終盤、後は普通に走行するようです。
これぐらいが一番楽しい。

最初の待ち合わせの場所に行く予定でしたが右折の車線に入るタイミングが遅れて通り過ぎてしまった。
自宅から少し離れてしまったが、ここで終了でも良いですかと聞かれたので了承。
今回の運転についてアドバイスをいただき、採点された用紙も貰いました。後、初心者マークも貰ったのでこれは車を買った時に使わせてもらいます。

乗れるようになって一安心

今回は初回限定の2時間コース、9800円。
料金を払い解散です。
優しい指導員の方で良かったです。

2時間はあっという間でした。
運転への恐怖心も和らぎ楽しかったので早く自分の車が欲しくなってしまった。
またここで、後1~2回ほど教習を受けようかなと思っています。


迷路の探索

前回の迷路作成に続き、今回は探索です。

幅優先探索

迷路探索の方法は色々あるようですが、今回は幅優先探索でやってみようと思います。
スタート位置から4方向を調べ、道がある方向へ移動して毎回4方向を調べるというのを1マスずつ繰り返していき、分岐がある場合は平行して調べていくという方法。

1.迷路を作成する
2.各マスの訪問履歴を作成する
3.スタートのマスをキューに格納する
4.キューの先頭から一マス取得する
5.取り出したマスがゴールなら終了
6.手順4で取り出したマスから上下左右の何れかに移動する
7.移動先のマスが迷路外でないことを確認する(迷路外の場合は手順6に戻る)
8.移動先のマスが道またはゴールであることを確認する(道でもゴールでもない場合は手順6に戻る)
9.移動先のマスが未訪問であることを確認する(訪問済みの場合は手順6に戻る)
10.移動先のマスをキューに格納し、訪問履歴を更新する
11.4から10をキューが空になるまで繰り返す

引用:全探索アルゴリズム入門

これをJavaScriptで作成していきます。
迷路作成部分は前回の物をそのまま使用します。
迷路描画は正方形の壁の方で。
とりあえずはスタートは左上、ゴールは右下にしておきます。

f:id:chaz4:20171120220553p:plain

グレーの線が探索してきたマスで、赤の線がゴールまでの道順です。無事にスタートからゴールまで辿り着いているのが分かります。
ほとんどのマスを探索しているようで大変そうです。
分岐地点を並行して調べていってるので、赤線は(多分)最短経路です。

キューに追加する時に、探索位置x,yの他に今までの経路rtも一緒に保存するようにしています。rtの中身もキューというかスタックのような物です。
キューから取り出したものがゴール位置だった場合、一緒に保存されているrtにはスタートから今までの経路が入っているということになります。

スタートとゴール地点のランダム化もしてみました。

f:id:chaz4:20171120220557p:plain

注意点等

迷路と関係ないんですが、JavaScriptの2次元配列の初期化は注意が必要です。

他、経路を保存する時にもハマりました。
キューから取り出したrtですが、経路を追加する時にそのままrtに追加すると上手くいきません。
これで3日くらい悩みました(笑) そしてJavaScriptの配列は参照渡しということを思い出したのです。他の言語もそうかもしれないが。
そのまま追加だと、全て同じ配列に追加されていたのだった。
というわけで、newRouteという配列を新しく作り、そこにrtの内容をコピーしてからnewRouteに新しい経路を追加するというやり方で上手く動作しました。