C88頒布情報

C88に当選しておりました。 やっとこさ本が出来上がったので、頒布情報を公開します。

  • 書名:大石泉が教えるJavascript -レナとマキノのポーカースクール-
  • 価格:\200
  • 場所:3日目東ラ60a

友人との合同サークルになります。

お品書きはこちらで、友人の新刊と合わせてセット価格\500になりますので是非セットでお求めください。

AppleScriptを利用したscreencaptureの座標自動取得

もうちょっと奇麗にしてから公開しようと思いつつ、全く手に付かないので諦めて公開します。

なんで作ったのか

艦これをしているとき、記念にスクリーンショットを撮ることがあるのですが、いちいちCmd+Shift+4で撮影する範囲を指定することが面倒だったので、どうにか自動化できないかと思い作成しました。

最初はターミナルから予め調べた座標を渡して撮影すればいいと思っていましたが、ちょっとウィンドウがずれるとまた座標を調べ直さないといけません。いちいち調べ直すのも面倒ですし、もう座標がずれることを前提に、自動取得した方が早いと思ったため、いろいろ調べたらAppleScriptに辿り着きました。

Yosemite以降では同じことをJavascriptで出来るようなので、多分レガシーな技術になっていくんでしょう。ただまあMavericks以前の人と自分のために残しておきます。

実現方法

方法は簡単で、AppleScript艦これFlashが表示されている座標を調べて、当該サイトのソースを見て幅と高さを固定値で渡すだけです。

on getFlashPosition()
    tell application "System Events"
        return (get value of attribute "AXPosition" of group 1 of UI element 1 of scroll area 1 of group 3 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window "艦隊これくしょん~艦これ~ - オンラインゲーム - DMM.com" of process "Safari")
    end tell
end getFlashPosition

set position to getFlashPosition()
set x to (item 1 of position) as text
set y to item 2 of position as text
set w to 800 as text
set h to 480 as text
set param to x & "," & y & "," & w & "," & h as text
set p to " ~/Desktop/\"スクリーンショット `date '+%F'` `date '+%H.%M.%S'`.png\""
set com to "screencapture -R" & param & p as text
do shell script com

AppleScript艦これのウィンドウを探す処理が決め撃ちなので美しくありませんが、実現できないよりはまぁマシだろうと。

screencaptureに渡すファイル名でdateコマンドを2回使っていますが、どうもscreencaptureに渡すとき1回の使用ではどうやってもスペースを実現できず2回使うことに。これも美しくない。

Qiitaで教えていただいた方法も試しましたが、screencaptureへ渡すときにエラーが発生してしまいます。誰か解決方法を教えてください……。

反省

AppleScriptは産まれて初めて描いたのですが、調べようにも日本語の資料に乏しく難儀しました。きっともっといい書き方があるはずです。

Jasmine-nodeを使ったNode.jsのテスト

Node.js + Jasmine-nodeを使ったテスト

まずNode.jsとJasmine-nodeをインストールする。

Node.jsがインストールされていれば、Jasmine-nodeは以下のコマンドでインストールできる。(nodebrewを使ってNode.jsをインストールした場合)

$ npm install -g jasmine-node

インストールの確認は以下のコマンドで行う。

$ jasmine-node -h

ヘルプが表示されればインストールは正常に完了している。

ソースファイルが置かれているディレクトリに spec ディレクトリを作成し、その中にファイルネームを xxSpec.js としたテストコードを格納する。

test
---sourceCode.js
 |---spec
    |---xxSpec.js

テストしたいコードでは関数を exports する必要がある。

function sample(){
  return 0;
}

exports.sample = sample;

テストコード内で exports した関数を require したオブジェクトから読み込む。

var source = require('../sourceCode');
var sample = source.sample;

describe('テストブロックのコメント', function(){
  it('テスト単体のコメント', function(){
    expect(sample()).toEqual(0);
  });
});

テストをする場合は以下のコマンドを実行する。

$ jasmine-node spec

もちろんだが、 pwd にspecディレクトリがなければ意味がないので注意。

poh4で書いたコード

今一番できる言語のJavaScriptで挑んだものの、ブラウザでしか動作確認したことが無いからnode.jsに戸惑いながらの作業だった。

//input
process.stdin.resume(); //デフォルトでは標準入力に対するストリームが中断されているため、読み込みのために呼び出す必要がある。
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk){
  var lines = chunk.toString().split('\n');

//標準入力の値を格納した配列を分割する
var N = lines[0];
var S = lines.splice(1, lines.length - 2);

var numbers = S.map(function(elem){
  return parseInt(elem);
});

var result = numbers.reduce(function(sum, elem){
  return sum + elem;
});

console.log(result);

});
//input
process.stdin.resume(); //デフォルトでは標準入力に対するストリームが中断されているため、読み込みのために呼び出す必要がある。
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk){
  var lines = chunk.toString().split('\n');

//標準入力の値を格納した配列を分割する
var N = lines[0];
var S = lines.splice(1, lines.length - 2);

var numbers = S.map(function(elem){
  return elem.split(" ").map(function(item){
    return parseInt(item);
  });
});

var midway = numbers.map(function(elem){
  if (elem[0] > elem[1]){
    return (elem[0] - elem[1]) * elem[2];
  }else{
    return 0;
  }
});
var result = midway.reduce(function(sum, elem){
  return sum + elem;
});

console.log(result);

});

3問目はまだ100点を取ってないので後日書く。 1問目2問目もひどいコードなので、3問目を解き終わったら手直ししよう。