人生シーケンスブレイク

シーケンスブレイク(Sequence breaking、シークエンスブレイクとも)とは、テレビゲームにおいて開発が想定している攻略ルートを逸脱し、ショートカットする行為のことである。

Dein.vimにしたので折角だしこのタイミングでvimrc構成を整える

NeoBundle.vimからDein.vim移行に伴い、Vimの設定ファイル群の整理も行ったのでその記録。

設定ファイル群の構成

ざっくり以下の構成に整えました。

dotfiles/
└── .vim/
     ├── colors/     // カラースキーム置き場(今回は説明しません)
     ├── ftplugin/   // filetypeごとの固有設定ファイル置き場
     ├── gvimrc
     ├── rc/
     │   └── *.vim   // 各種設定ファイル
     ├── template/   // template置き場
     └── vimrc       // メインのvimrc

vimrc, gvimrc の設置箇所について

:help vimrc によると、

個人の初期化ファイルの配置場所:
Unix $HOME/.vimrc、$HOME/.vim/vimrc

初期化ファイルは上記の順に検索され、最初に見つかったものだけが読み込まれる。

推奨: Vimの設定ファイルは全て $HOME/.vim/ ディレクトリ(MS-Windowsでは$HOME/vimfiles/)に置くこと。そうすれば設定ファイルを別のシステムにコピーするのが容易になる。

とあります。

今まで$HOME直下にVim設定ファイルとして、 .vimrc, .vim/, .gvimrc の3つをシンボリックリンクでつなげてましたが、$HOME直下は.vim/だけで済むようにしました。

ftplugin ディレクトリについて

ファイルタイプごとに固有の設定は

.vim/ftplugin/<filetype>.vim
.vim/ftplugin/<filetype>_<name>.vim
.vim/ftplugin/<filetype>/<name>.vim

の箇所に配置すると、各ファイルタイプに応じて読み込まれます。
pythonを例にすると、python.vim でも python_hoge.vim でも python/hoge.vim でも読み込まれます。

.vimrc にすべてのファイルタイプの設定を書くのでなく、
各ファイルタイプごとに設定ファイルを用意することでリーダブルにします。

rc ディレクトリについて

私のVim環境下では、 .vim/rc/以下の *.vim ファイルをすべて読み込むように設定しています。
こうすることで、例えば Dein用の設定ファイルは.vim/rc/dein.vimのように、pluginごとの設定は.vim/rc/<plugin_name>.vim に分割することが可能です。

設定方法は、大本のvimrcに以下のように記述するだけです。

set rtp+=$HOME/.vim/
runtime! rc/*.vim

Dein.vim 用の call dein#add(...) を記述しまくった設定ファイルもここに設置しています。

template ディレクトリについて

テンプレートファイル置き場です。
Vimでのテンプレートは以下の設定で実現可能です。

例: Pythonのテンプレートファイルを設置する場合

.vim/template/skeleton.py として、以下を記述したファイルを設置します。

# coding: utf-8

次に、 .vim/rc/skeleton.vim に以下を記述したファイルを設置します。
(.vim/ftplugin/python.vim 内に記述しても可能です。)

augroup template
  autocmd!
  autocmd BufNewFile *.py 0r $HOME/.vim/template/skeleton.py
augroup END

$ vim new.py とすると、自動で "# coding: utf-8" が挿入されます。

:help skeleton もご参照ください。

まとめ

上記のような構成にすることで、Vimの設定ファイルをすべて .vim/ 配下で完結しつつ、ファイルタイプや用途ごとに適切に分割することができました。

以前より見通しがよくなった為、管理もしやすいです。
もし今まで.vimrcひとつで管理してた人は、分割も試してみてはいかがでしょうか?

それでは良いVimライフを!!

Activité Pop のバッテリーは3ヶ月程度しか持たなかったよ

Withings Activité Pop を買って7ヶ月ほど経ちました。

f:id:ShineSpark:20160116234926p:plain

Withings Activité Pop

歩数、運動量、睡眠のトラッキングが可能な腕時計。
公式だと20,800円だが、Amazonでは現在15,000円ほど。

値段に対する満足度としては非常に満足している。

Apple Watch が出る直前に並行輸入で購入したのだけれども、アナログな文字盤と歩数達成率のシンプルなデザインで非常に使いやすい。

同メーカーのハイエンドモデルである Activité の方がデザインは洗練しているが、 運動、睡眠計測の為に付けっぱなしになりがちであることから、安価な Activité Pop の方が気楽に使用できるのでこちらを購入した。

f:id:ShineSpark:20160117000325j:plain
アプリの画面。元々Withingsアプリで健康管理を行っている人には違和感なく移行できると思う。

バッテリー持ち

f:id:ShineSpark:20160116234945p:plain

公称ではバッテリーが8ヶ月と謳っている。Apple Watch のバッテリーが1日しか持たないと話題になっていた時期だったのもあり、Activité Pop は非常にバッテリー持ちするように見受けられる。

ところが...

f:id:ShineSpark:20160116234943p:plain

バッテリー残量が足りなくなると届くメール通知。

6月購入から、どう見ても3ヶ月程度しか持ってません。本当にありがとうございました。

しかも、上記のメール通知が届く前後から時計がズレ始める。時計なのに正しい時刻を示さなくなるなんて...

早く電池を交換しろってことか...と思い、電池を交換したらまた再び正しい時刻を示すようになった。

ついでなので電池交換の仕方

Activité Pop は自分で電池交換可能です。

f:id:ShineSpark:20160116235044j:plain

コンビニでも売っているボタン電池 CR2025 と、付属の時計蓋外しを用意して、

f:id:ShineSpark:20160116235012j:plain
パカーっと裏を外して、

f:id:ShineSpark:20160116235035j:plain

電池を外すと、「この向きで電池嵌めるんやでー」っと書いてあるのでその通りに嵌めるだけ。

蓋を閉める際は、防水仕様もあってかかなり力を要する。 テーブルの上に時計を置いた状態で、手のひらを時計の上に載せて、ちょっとジャンプして全体重を掛ける位でやっと嵌まる。

f:id:ShineSpark:20160116235004j:plain

これでまた3ヶ月は使えます。 最大8ヶ月というのは、きっとアラームを使わず、運動量の計測もあまりしない時なんだろうな...

とはいえ

スマートウォッチとしては非常に満足しています。 電池交換自体には2回目というのもあって全然時間がかからないし、8ヶ月も3ヶ月も電池交換に要する感覚としては苦になっていない。 むしろ、毎日の睡眠の記録や、歩いた距離に応じたachievementの通知が楽しいのでもっともっと使いたい。

値段もお手頃なので買って後悔はしないですよ。

NERDCommenterでfiletypeごとのコメントフォーマットを変更したい

SCSSを scss-lint でチェックしてるんだけど、デフォルトで推奨されているコメントが // となっている。 しかし、NERDCommenterコメントアウトした際には /* */ となっていて面倒なのでSCSSのデフォルトのコメント設定を変更したい。

.vimrc に以下のように追記する

let g:NERDCustomDelimiters = {
  \  'scss': { 'left': '//'}
  \}

まだ著作権表記で消耗してるの?

年末年始対応の時期ですね。

f:id:ShineSpark:20151216014450p:plain
svg画像を 著作権表示 - Wikipedia より。

企業で働くエンジニアは、あけおめ対策をはじめとした年末年始の対応準備に時間を割いていることでしょう。
その中でも、毎年恒例の著作権表記、特に年号更新の対応に追われる方が多いでしょう。

アレ、不要なので辞めましょう。

要点

  • 著作権表記は現在いちいち書く必要性はありません。
  • 年号表記も特に意味はありません。
    • そんな対応に時間をとられる必要はありません。辞めましょう。
  • もっと言えば "All rights reserved." も不要です。辞めましょう。

どゆこと?

そもそも著作権表記とは?

著作権表示(ちょさくけんひょうじ)は、著作物の複製物につける著作権者や著作物の発行年等に関する表示である。著作者が著作権を取得するため、著作物の創作のほか、何らかの手続き等(方式)が必要な法域においては、著作権表示は重要な意味があるが、現在は、ほぼ全ての法域で著作権は、著作物の創作とともに発生するので、重要性は失われている。
著作権表示 - Wikipedia より引用

日本国内に於いては、1971年7月24日にパリで改正された万国著作権条約に受諾しており、現在はこちらの内容に批准しています。 その第三条四項には以下のように定められています。

4  各締約国は、他の締約国の国民の発行されていない著作物を、方式の履行を要することなく保護するための法的手段を確保する。
千九百七十一年七月二十四日にパリで改正された万国著作権条約 - Wikisource より引用

ここでいう "方式" とは、著作権の無方式主義と方式主義のことです。

無方式主義 著作物を著作もしくは発表した時点で自動的に著作権が発生し、それ以外には何らの方式(又は手続)の履行を要求しない法制 方式主義 納入、登録、表示、官庁への納入、登録、登録手数料の支払い、自国内における製造もしくは発行などといった「方式」を履行することにより著作権の発生要件とする法制
著作権表示 - Wikipedia より引用

またまたWikipedia引用ですみません。ちなみに私はこの件について8年程前から疑問を抱き、毎年この時期になる度に当該Wikipediaページをwatchして参りました(編集は一切してない)。昔に比べると非常に明瞭になっており、私以外にもこの件で戦ってきた人が居るのかと思うと非常に感慨深いものがあります。 当時はガラケー全盛期の為、All rights reserved. を書くだけでフッターに無駄な改行が入ったのです。

要するに、「万国著作権条約に締約している国の国民は、何もせずとも著作物の権利を保護する法的手段を持っている。」ということになります。
何もせずとも、です。

つまり要らないのです。

ちなみに (c) 表記について

前述の通り不要なのですが、方式主義に於いて認められているのは © であり、(c) は認められていません。

その為、.txt ファイルとかに (c) と書いていても無効なので書くのは辞めましょう。

ちなみにAll rights reserved.は?

こちらは万国著作権条約には関係ありません。万国著作権条約制定前に策定されたブエノスアイレス条約という条約があるのですが、この条約では「権利を所有している」表記が必要でした(方式主義)。

アメリカ合衆国をはじめとした国々が締約し、「権利を所有している」表記として、All rights reserved. が使われました。 現在では、アメリカを含め殆どの国がベルヌ条約*1及び万国著作権条約にも締約している為、この表記は現在は不要です。

ちなみに、 日本はこのブエノスアイレス条約に締約していません。
したがって、 日本では全く意味がありません。
アメリカ企業の権利表記を日本企業がコピペしたものが蔓延したんでしょうねぇ...

All rights reserved. のデメリット

All rights reserved. の直訳は、「すべての権利を保有している」です。
イマドキのWebサービスに於いて、そのようなケースが果たして本当に成立しているのでしょうか?

  • CGM
    • ユーザが投稿した写真やデータ。規約にも運営側に帰属する旨記載して、規約との齟齬はありませんか?
    • ユーザが投稿した歌詞や第三者が著作権を保有している画像。これも運営者が権利を保有しているのでしょうか?
  • 外部データ
    • 他者からAPI取得 または購入したデータ
    • オープンデータ
    • OSSやライブラリ

意味の無い All rights reserved. を書くことで、逆に訴訟や炎上リスクを招く可能性もありそうです。

規約の話ではありますが、mixi規約改定時に問題になりましたね。
ミクシィの利用規約改定問題が示すCGM時代の権利処理のあり方 - ビジネススタイル - nikkei BPnet

他の例として、有名なCGMサービスとして ボケてがありますが、全ページのフッターに All rights reserved. と書いてあります。
しかし、利用規約には、

第17条 弊社の財産権
( 1 ) 利用者が送信(発信)したコンテンツおよび情報を除き、本サービスに含まれる一切のコンテンツおよび情報に関する財産権は弊社に帰属します。

と書いてあり、Allとは一体...うごごごごご...と思ったりします。*2

利用者が投稿したコンテンツおよび(他者の著作物を含む)画像の権利の帰属を宣言しない辺り、ボケてはしっかりしている方かも知れません。

お前専門家じゃねーだろ。ただのエンジニアがナマいってんじゃねーぞ。

はい。専門家ではありません。ぜひとも専門家からの意見もいただきたいところです。 弁護士ドットコム - 無料法律相談や弁護士、法律事務所の検索 でニュースとして取り上げていただけること、お待ちしております。

とはいえ根拠も無いままではアレなので、ここは最強法務部と名高い任天堂法務部のチェックを通ったであろう任天堂公式サイトを確認してみましょう。

f:id:ShineSpark:20151216005543p:plain
任天堂ホームページ|Nintendo より

お、超シンプルです。私が思う理想形です。

先日 サムスンから賠償金5億4800万ドルせしめた Appleはというと、

f:id:ShineSpark:20151216005906p:plain
Apple より

あ、年号もAll right reserved. がありました。

お次はGoogleです。
f:id:ShineSpark:20151216011814p:plain
Google より

本気で何も書いてない...

思ったよりバラバラの模様です。

対応

原理主義的な話を散々述べましたが、本懐は「毎年毎年、年号を更新するだけの無駄なクソ作業を無くしたい」です。
現実として、社内の一エンジニアや受託エンジニアでまるっと無くすというのは現実的ではないでしょう。

その場合の対応として、以下の解決策を検討しましょう。

動的ページ

Date() 関数などから現在の年号を表記するなどして動的に出力しましょう。

静的ページ

404.html とか 500.html などは、コンテンツなんてあってないようなページなので、© 会社名 または© 会社名 All rights reserved. にして年号は無くしましょう。

クライアント側で実行するJavaScriptでの年号出力は推奨しませんが、どうしても上長がOKしてくれない場合や、一時的なキャンペーンページなどの静的ページではJavaScriptでの実行もアリかもしれません。JavaScript無効設定での著作権表記について問題視する上長ならば、著作権表記自体の不要性やコストについても議論の余地がありそうです。

いずれにせよ手動更新は辞めましょう。

上長を説得する材料として

以下のサイトを判断材料にしてもらいましょう。

こんなことに時間を浪費しているうちはスピーディな開発なんて出来やしない。

*1:長くなるのでこのエントリでは言及しない。

*2:CGMとして有名な為取り上げましたが、All rights reserved.の含有する矛盾を問題提起するのが目的であり、ボケてサービスを批判する意図は全くありません。

gulp-sassで自動でSass/SCSSからcssファイルを生成する

フロントエンド開発に便利なNode.js環境で、ファイル変更時に自動でSass(SCSS)からCSSファイルを生成したい。

2016-06-17 追記

上位互換記事を書きました。

gulp-sassで自動でSass/SCSSからcssファイルを生成したり、他にもいろいろする - 人生リアルタイムアタック

準備

以下のようなディレクトリ構成を想定。

.
├── css
│   └── // cssファイルの生成先
└── assets
    └── sass
        └── main.scss

インストール

gulpとgulp-sassをインストールする

$ npm install gulp gulp-sass

gulpfile.jsの作成

まずは最も簡単な例として、*.scssに変更があれば自動で*.cssを生成する例。

var gulp = require('gulp');
var sass = require('gulp-sass');

// Sassコンパイルタスク
gulp.task('sass', function(){
  gulp.src('./assets/sass/**/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./css/'));
});

// watchタスク(**/*.scss変更時に実行するタスク)
gulp.task('sass-watch', ['sass'], function(){
  var watcher = gulp.watch('./src/sass/**/*.scss', ['sass']);
  watcher.on('change', function(event) {
    console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
  });
});

// gulpのデフォルト動作としてsass-watchを実行
gulp.task('default', ['sass-watch']);

実行

$ gulp

を実行するだけで、後はSCSS変更時に自動でCSSが生成されるようになる。 **/*.scss としている場合、hoge/hoge.scsscssの出力先も hoge/hoge.css としてくれる。親切。

出力フォーマットを変更したい。

gulpfile.js内の .pipe(sass()) を、 .pipe(sass({outputStyle: 'expanded'})) にすると、よくみるcssフォーマットで生成されるようになる。

構文ミス時にgulpごと落ちるのを何とかしたい

gulp-plumber を使う。

var gulp = require('gulp');
var sass = require('gulp-sass');
var plumber = require('gulp-plumber');

// sassコンパイルタスク
gulp.task('sass', function(){
  gulp.src('./src/sass/**/*.scss')
    .pipe(plumber()) // ←ここが追加
    .pipe(sass())
    .pipe(gulp.dest('./css/'));
});

// watchタスク(Sassファイル変更時に実行するタスク)
gulp.task('sass-watch', ['sass'], function(){
  var watcher = gulp.watch('./src/sass/**/*.scss', ['sass']);
  watcher.on('change', function(event) {
    console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
  });
});

gulp.task('default', ['sass-watch']);

こうするとエラー時にも落ちない。

browser-syncと併用したい。

var gulp = require('gulp');
var sass = require('gulp-sass');
var bs = require('browser-sync').create();

// browser-sync
gulp.task('bs', function(){
  var bsOptions = {}
  bsOptions.files = ['template/**/*.html', 'css/**/*.css'];
  bsOptions.port  = 3000;
  bs.init(bsOptions);
});


// sassコンパイルタスク
gulp.task('sass', function(){
  gulp.src('./src/sass/**/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./css/'));
});

// watchタスク(Sassファイル変更時に実行するタスク)
gulp.task('sass-watch', ['sass'], function(){
  var watcher = gulp.watch('./src/sass/**/*.scss', ['sass']);
  watcher.on('change', function(event) {
    console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
  });
});

gulp.task('default', ['bs', 'sass-watch']);

こんな感じかなー

FlaskでもHamlを使う - hamlish-jinja

Flask 最近書いてるんだけれども、今更閉じタグなんて書きたくないんじゃ!ということで、様々HTML Template触った結果最も書きやすかったHamlを使いたい。

ということで hamlish-jinja を使う。

使い方の基本

Flaskのdefault template engineであるjinjaのoptionsに、hamlish-jinjaを渡したclassを生成して実行する。

from flask import Flask, render_template
from werkzeug import ImmutableDict


class FlaskWithHamlish(Flask):
    jinja_options = ImmutableDict(
        extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_', 'hamlish_jinja.HamlishExtension']
    )
app = FlaskWithHamlish(__name__)


@app.route('/')
def index():
    return render_template('index.haml')

if __name__ == '__main__':
    app.run()

オプション

hamlish-jinjaには幾つかのオプションが用意されている。 以下はその一例。

  • app.jinja_env.hamlish_enable_div_shortcut = True
    • divタグを省略可能にする。div.classname を .classnameだけで記述可能になる
  • app.jinja_env.hamlish_mode = 'indented'
    • 出力HTMLにインデントをつける。開発中はこちらが良いだろう。

https://github.com/Pitmairen/hamlish-jinja#configuration

Syntaxについて

あくまでHamlishであって、Hamlと全く同じではない。

複数のAttributeを {} で記述できない。

Hamlで可能な記述(hamlish-jinjaでは不可)

    %meta {name:'viewport', content:'width=device-width, initial-scale=1'}

hamlish-jinjaで可能な記述

    %meta name='viewport' content='width=device-width, initial-scale=1'

!!!5 が適用されない。

他の方法でできるからいいじゃんという話になっている。

Added doctype strings. by totkeks · Pull Request #15 · Pitmairen/hamlish-jinja · GitHub

このケースでは、app.py側に以下のように書いたらいいじゃんという話。

import jinja2 

jinja_env.globals['html5'] = jinja2.Markup('<!DOCTYPE html>')

つまり、hamlとまったく同じ記述ができるというわけではなく、あくまでもhamlっぽく書けるという話。

コメント書式が異なる

hamlish-jinjaでのコメントは ; です。なんでや。

;Test comment

hamlからhamlishに変換したい

↓ を使いましょう。

hamlish-jinja/haml2hamlish.py at master · Pitmairen/hamlish-jinja · GitHub

まとめ

それでもhamlishなtemplateは記述量の少なさから得られる恩恵が大きいのでもうちょっと使って見る予定。 とはいえ、hamlと完全互換では無いので、そこの差異を認識した上で利用するのが望ましそう。

SSL証明書が正しくないサイトに対してPythonでアクセスする

HTTPSで提供しているサービスのローカル開発環境にPythonでアクセスを試みたらエラーが出た。

Traceback (most recent call last):
  File "/main.py", line 36, in <module>
    main()
  File "/main.py", line 18, in main
    soup = BeautifulSoup(opener.open(conf['login_url']).read().decode('utf-8'), 'html.parser')
  File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 465, in open
    response = self._open(req, data)
  File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 483, in _open
    '_open', req)
  File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 443, in _call_chain
    result = func(*args)
  File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 1283, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 1242, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:646)>

PEP 0476に従い、Python2.7.9以降はSSL証明書が正しくない場合にはデフォルトでSSL認証エラーを出すようになった模様。 PEP 476 -- Enabling certificate verification by default for stdlib http clients | Python.org

開発環境にアクセスするだけのコードだったので、

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

上記を書いて実行したらアクセス可能になった。
セキュリティ上は安全と保証されないことを認識の上でご利用ください。

みんなのPython 第4版

みんなのPython 第4版