頑張って、長続きしたい。

メモ書きをひたすら書く。継続は力なり。

JJUG CCC 2015 fallに参加しました

会社の同期に誘われ、JJUG CCCに参加してきました。
Timetable / JJUG CCC 2015 Fall(11月28日開催) | 日本Javaユーザーグループ
せっかく参加したので、メモ書き程度に参加記を残しておきます。

Java

高校・大学の授業で触ったぐらい。
会社に入社してからはMapReduceを書くために使い始めました。

発表資料

既にまとめてくださっている方がいました。d.hatena.ne.jp

講演の感想

(参加中メモを取らずに聞いていたので、かなり適当です。)

keynote-2 基調講演2: Java EE 8 – Work in Progress

Java EEって聞いたことある程度だったので、講演を聞きながらググってました。

CD-1 苦手克服!例外スタックトレースから読み解くバグ

立ち見が大量に出るほど人気な部屋だった。
途中から自作ツールの宣伝になっていたような気がするけど、きっと気のせい。
IntelliJの補完を巧みに使ってたのが印象的。

EF-2 How to speed up your application using JCache[通訳あり]

10年ぐらいかけて仕様策定されたぜ!
Cache使わずにMap使ってるだけだったらCache使うと良いYO!
みたいなセッション(適当)
時間配分を完全に間違えてたみたいなので、資料が上がったらちゃんと読んでみたい。

GH-3 マイクロサービスアーキテクチャアーキテクチャ設計と開発プロセスの歴史を背景に

この日に聞いていた中でプレゼンがとても分かりやすかった。
自分が関わっているところもマイクロサービスは意識されているなーと思った。
けど、わざと本番環境を落とすChaos Monkeyは怖すぎるw

www.publickey1.jp

GH-5 サーバサイドのビュー処理エンジンForneusの開発秘話

要求される仕様に合うテンプレートエンジンがない(当時見つからなかった)から作った時のお話。
Web系知識もあまりないので、そんなことできるんだと思うことばかりでした。
今回はとにかくスピード!って感じで開発されていて、何かにこだわって開発するといい物ができるのかなと思いました。

EF-6 Real World Machine Learning in Java 8 at Fumankaitori.com

不満買取センターという不満を投稿して、不満の質が良ければたくさんポイント貰えるサービス。
このポイント設定を手動でやってたけど、機械学習で自動でやったという事例を使った発表。
とにかく英語が聞き取りやすかった。

fumankaitori.com

懇親会

一緒に来ていた同期と話していた。
LT大会がやってたけど、お酒が入ってるテンションからか(良い意味で)くだらない発表が多かったw
反省点はもっと色んな人と交流を持てたらよかった・・・。

参加してみて

勉強会というかこういうコミュニティに参加することは2回目ですが、モチベーションを高めることができました。
モチベーションが下がり始めたら勉強会とか参加するようにしよう。

Vim scriptのmap系コマンドの後ろにコメントは書けない

タイトルの通り。そんな仕様知らなかった・・・。

map

以下のようにmap系のコマンドを使えば、キーマッピング設定が書ける。*1

inoremap jj <ESC>

これは、インサートモード時にjjを入力するとESCキーと同様の操作(ノーマルモードに変更)をするという、よくあるキーマッピングである。

コメント

また、「"」以降はコメントとなる。 もちろん、コマンドの行末にコメントを記入することもできる。

" this is a comment.
set number " show line number

mapコマンドのコメント

しかし、map系コマンドの場合コメントと認識されない仕様*2がある。

inoremap jj <ESC> " this is not comment.

このような設定をした場合、jjを入力するとESCキー、半角スペース、「"」、半角スペース、「t」「h」「i」「s」・・・の順に入力されてしまう。

結論

map系コマンドの行にはコメントを書かない。 変な挙動なまま1年間ぐらい使ってました・・・。 シンタックスハイライトされないなー・・・。と思ってた時に気付いていれば・・・。

ニコニコ動画検索APIが公開されたので触ってみた。

ニコニコ動画の公式から検索用APIが公開されてたのでPythonで関数にしてみた。

ニコニコ動画 『スナップショット検索API』 ガイド


ちなみにPythonは勉強したてなので,Pythonの練習も兼ねて。

# coding:utf-8

import urllib2
import json
import sys
import codecs
sys.stdout = codecs.getwriter('utf_8')(sys.stdout)


def nico_search(query, service=['video'],
                search=['title', 'description', 'tags'],
                join=['cmsid', 'title', 'view_counter'],
                issuer='nico_api'):
    req = urllib2.Request('http://api.search.nicovideo.jp/api/snapshot/')
    req.add_header('content-type', 'application/json')

    data = json.dumps({'query': query, 'service': service, 'search': search,
                       'join': join, 'issuer': issuer})

    res = unicode(urllib2.urlopen(req, data).read(), 'utf-8')
    return res

if __name__ == '__main__':
    res = nico_search('初音ミク')
    print res
{"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","type":"hits","values":[{"_rowid":0,"cmsid":"sm23720459","title":"初音ミク","view_counter":581},{"_rowid":1,"cmsid":"sm19065818","title":"初音ミク","view_counter":54},{"_rowid":2,"cmsid":"sm15309998","title":"初音ミク  綠光","view_counter":322},{"_rowid":3,"cmsid":"sm22962024","title":"初音ミク","view_counter":148},{"_rowid":4,"cmsid":"sm23739051","title":"初音ミク2","view_counter":216},{"_rowid":5,"cmsid":"sm23486084","title":"Google × 初音ミク CM","view_counter":389},{"_rowid":6,"cmsid":"sm3027541","title":"MUGEN初音ミク","view_counter":2116},{"_rowid":7,"cmsid":"sm22908770","title":"LEGO 初音ミク","view_counter":105},{"_rowid":8,"cmsid":"sm24514916","title":"初音ミク bgm1.mp4","view_counter":31},{"_rowid":9,"cmsid":"sm20491983","title":"初音ミクprojectDIVAf OP","view_counter":130}]}
{"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","type":"stats","values":[{"_rowid":0,"service":"video","total":230168}]}
{"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","endofstream":true,"type":"hits"}
{"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","endofstream":true,"type":"stats"}

検索キーワードを指定すると検索結果(今回は動画ID・タイトル・再生数)が返ってくるだけ。
超シンプル。

まだまだオプションがあるので、弄ってみようと思う。

一応Githubにも公開しておきます。
https://github.com/otomarukanta/nicosearch

MacにVirtualBoxとVagrant入れて、CentOS7.0にDjango環境を構築した。

タイトルの通り。
Mac OSのバージョンは10.9.4

VirtualBoxVagrantのインストール

Homebrewを使ってインストール

brew cask install virtualbox
brew cask install vagrant

バージョンは
VirtualBox:4.3.16
Vagrant:1.6.5

CentOS7.0のBoxを追加

以下のURLから使用したいBoxを選ぶ。
A list of base boxes for Vagrant - Vagrantbox.es

今回はCentOS7.0のBoxを選択。

$ vagrant box add centos70 https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box
==> box: Adding box 'centos70' (v0) for provider:
    box: Downloading: https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box
==> box: Successfully added box 'centos70' (v0) for 'virtual box’!

仮想マシンの作成・起動

ダウンロードしたBoxを使って仮想マシンを作成・起動してみる。
$ mkdir -p ~/Vagrant/CentOS70
$ cd ~/Vagrant/CentOS70
$ vagrant init centos70
$ vagrant up

すると以下の様なマウントできねぇよ!みたいなエラーが出てくる。

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

ちょっと調べると解決方法が見つかるのでそれを実行。

vagrantでmountエラーの解決方法 - Qiita

$ vagrant ssh
[vagrant@localhost ~]$ sudo /etc/init.d/vboxadd setup
[vagrant@localhost ~]$ exit
$ vagrant reload

無事エラーが出ずに仮想マシンの起動に成功!

Djangoの開発環境構築

まず、Pythonのバージョンを確認。

[vagrant@localhost ~]$ python -V
Python 2.7.5

次にpipをインストール。

[vagrant@localhost ~]$ wget http://peak.telecommunity.com/dist/ez_setup.py
[vagrant@localhost ~]$ python ez_setup.py
Setuptools version 0.6c11 or greater has been installed.
(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)
# 既に入ってたorz
[vagrant@localhost ~]$ sudo easy_install pip

そしてDjangoをインストールと確認。

[vagrant@localhost ~]$ sudo pip install django
[vagrant@localhost ~]$ python
Python 2.7.5 (default, Jun 17 2014, 18:11:42)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print django.get_version()
1.7
>>> exit()

Djangoのプロジェクトを作成・サーバー起動

[vagrant@localhost ~]$ mkdir django
[vagrant@localhost ~]$ cd django/
[vagrant@localhost django]$ django-admin.py startproject helloworld
[vagrant@localhost django]$ cd helloworld/
[vagrant@localhost helloworld]$ python manage.py migrate
[vagrant@localhost helloworld]$ python manage.py runserver

無事成功したが、仮想マシン上でのサーバー起動なため、単純にWebブラウザからアクセスできない。
Vagrantfileを編集することで、指定したポートへのアクセス(ホストOS)をゲストOSの指定ポートに転送してくれるみたい。

Vagrant で Python(Django) 開発環境を準備する - Qiita

# config.vm.network "forwarded_port", guest: 80, host: 8080
# 以下に変更
config.vm.network "forwarded_port", guest: 8000, host: 8080

仮想マシンを再起動、もう一度Djangoプロジェクトのサーバーを起動。

$ vagrant reload
$ vagrant ssh
[vagrant@localhost ~]$ cd django/helloworld/
[vagrant@localhost helloworld]$ python manage.py runserver 0.0.0.0:8000

Webブラウザからlocalhost:8080にアクセス・・・できない。

悩むこと1日。あ、ポート開放してないじゃんと気づく。
CentOS7.0からはfirewallコマンドというのを使って設定するらしい。

[vagrant@localhost helloworld]$ sudo firewall-cmd --permanent --add-port=8000/tcp
[vagrant@localhost helloworld]$ sudo systemctl restart firewalld.service

そしてもう一度Webブラウザからlocalhost:8080にアクセスするとIt Works!の文字が!

文字を文字コードに変換する

文字を文字コード(今回はSJIS)に変換する必要があった。
例えば’A’を’8260’など。

以下のようなWEBサービスでは結構でてくるのに、処理の中身自体がなかなか見つからない。
文字コード変換 WEBアプリケーション、フリーCGI配布 ---ahref.org


が、ついに今日!

以下のページを見つけた!!
あの文字のバイト列は何になるんだっけ 各文字コードの16進数表記を求める(PHP/JavaScript/Perl/Ruby/Python) - INASOFT 管理人のふたこと


まさに探していた情報!!

結構前から探してたけど、少し前に公開されていたみたい。感謝。

というわけで、Pythonのソースを参考に以下のコードを作成。

# -*- coding: utf-8 -*-
import binascii

def char2sjis(c):
    return binascii.hexlify(c.encode('sjis')).upper()

if __name__ == '__main__':
    c = u'A'
    print char2sjis(c)

とてもシンプル。

Apache + PHP + MySQL on MacBookPro

MacBookPro、OS X 10.9.4上にWEB開発環境を構築する。

以下のサイトを参考(そのまんま)にApache+PHPMySQLの環境を構築。


いちいちsudo〜ってコマンドでファイルを編集したくなかったので、
DocumentRootを変更した。
すると403 Forbiddonに。


[Mac] apacheでローカルサーバーを構築する方法 | Memo on the Web

一箇所だけじゃなく、もうひとつ変更しなければならなかった。

/etc/apache2/httpd.confの以下2つを任意のパスに変更することで正しく動いた。

DocumentRoot "/Library/WebServer/Documents"

typeidの罠

クラスの型を調べるtypeid演算子というのがある。

でも、実際に使ってみると正しい結果を出してくれなかった。

結果として、継承元のクラスに仮想関数がなかったらダメということ。

ダメな例

#include <iostream>
#include <typeinfo>

class A{
};

class B : public A {
};

int main(int argc, char **argv) {

	A *aa = new A();
	A *ab = new B();
	B *bb = new B();

	std::cout << typeid(A).name() << std::endl;
	std::cout << typeid(B).name() << std::endl;
	std::cout << typeid(*aa).name() << std::endl;
	std::cout << typeid(*ab).name() << std::endl;
	std::cout << typeid(*bb).name() << std::endl;

    return 0;
}
1A
1B
1A
1A // ここはBになって欲しい
1B

クラスAに仮想関数を持たせると

#include <iostream>
#include <typeinfo>

class A{
	virtual void hoge() {}↲
};

class B : public A {
};

int main(int argc, char **argv) {

	A *aa = new A();
	A *ab = new B();
	B *bb = new B();

	std::cout << typeid(A).name() << std::endl;
	std::cout << typeid(B).name() << std::endl;
	std::cout << typeid(*aa).name() << std::endl;
	std::cout << typeid(*ab).name() << std::endl;
	std::cout << typeid(*bb).name() << std::endl;

    return 0;
}
1A
1B
1A
1B // Bになった!
1B