2016年2月6日土曜日

正月太りの解消


体重のコントロールに成功したので、記録に残す

実績

1ヶ月で5kg減量

1/4時点で、体重76kgであったところ、
2/5時点で体重が71kg。

やったこと

食事

概要


  • 糖質制限食
    • エネルギーは脂質で摂る
    • 野菜を多く摂り、咀嚼回数で満腹感を得る
    • タンパク質は1日100g程度。

献立

  • 朝食
  • 昼食
    • 野菜
      • ブロッコリー、ロマネスコ、芽キャベツ (ボイル)
      • ほうれん草、小松菜 (ボイル)
      • わかめ、めかぶ、切り昆布 (湯通し)
      • 大根 (生、煮物)
      • ラディッシュ (生)
      • グリーンリーフレタス、ロメインレタス(生)
      • アボカド、オリーブ 
      • きゅうり (生、軽く塩漬け)
      • 白菜 (軽く塩漬け)
      • こんにゃく (煮物)
    • 肉・魚
      • ローストビーフ(オーブン160度以下)
      • 刺身 (鰯、鯵など青魚系が中心)
      • しめ鯖、コノシロ (甘味料としてステビア利用のもの)
      • 牛すじ (煮物)
      • 茹で卵・半熟玉子
    •  汁物
      • インストタントのスープ
        • 中華スープ、卵スープ、わかめスープなど
  • 夕食
    • 昼食の内容とほぼ同じだが、2日に1回程度、野菜や果実を摂る
    • 肉・魚
      • ラム肉 (ボイル、もしくはココナッツオイルで低温ロースト)
        • 脂が固まりやすく、調理後すぐに食べたいため夕食限定
      • 焼き魚 
        • 鰤、ホッケ、鮭、秋刀魚など (オーブンで160度以下、直火禁止)
    • 野菜
      • かぼちゃ (蒸す)
      • 人参 (蒸す)
      • さつまいも (蒸す)
    • 果実
      • りんご (生、国産)
      • みかん・金柑 (生、国産)
    • 汁物 
      • 海藻スープ
        • わかめ・切り昆布に鰹だしか中華だし150cc
        • 食塩・醤油は使わない

補足


  • 調味料(と用途)
    • 海塩 : 基本の味付け
    • リンゴ酢 : ドレッシング
    • レモン汁 : ドレッシング
    • オリーブオイル : ドレッシング
    • ココナッツオイル : 肉の低温ソテーに使う
    • オレガノ : 肉の臭み消しとドレッシング
    • ローズマリー  : 肉の臭み消し
    • ターメリック  : 肉の臭み消し
    • コリアンダー  : 肉の臭み消し
    • パプリカペースト : 肉をロースト後のグレービーソースに追加
    • 醤油 : 煮込みの味付け、刺し身
    • 鰹だし : 煮込み、海藻スープ
    • 中華だし :  海藻スープ
    • エリスリトール : 飲み物の甘みづけ
  • おやつ
    • 昆布 (練り梅のついていないもの)
    • 焼きめざし
    • ビーフジャーキー 
    • チョコレート
      • カカオ85%以上のもの
      • 摂取するとしても午後16時以降から
    • 蜂蜜
      • 寝る前に小さじ1杯
  • 飲み物
    • 緑茶
    • 紅茶
      • ストレート
      • 濃い目のアッサムに無塩バターを加えて撹拌
    • コーヒー
      • ブラック
      • シナモン、ココア(無糖)、無塩バターを加えて撹拌



運動

  • ウォーキング(20分) を 1日1回ないし2回
    • 通勤時に駅まで歩く


副次効果

体重の減少以外に下記の影響があった。

良いもの

  • 昼食後の眠気がない
  • 偏頭痛が起きない

悪いもの

  • 慣れるまで空腹感がある
  • 食事のレパートリーが減る
  • 外食ができなくなる

参考文献


   

2013年12月31日火曜日

軽い気持ちでコードを書いたらフルボッコされた

職場でフィボナッチ数を求めるプログラムぐらい書けるという話題が出た。
テキトーにコードを書いたらアルゴリズムやらテスト手法やら突っ込みを受け、
大変よい勉強になったので備忘録として残す。

最初に書いたプログラム

再帰を使用。 諸先輩から計算量どうなってるのと突っ込みを受ける。

<?php

class FibCalc {
static function getFib( $num ) {
if (intval($num) < 0  || !is_int($num)) {
   throw new Exception('Invalid argument');
}
if ($num < 2) {
return $num;
}else {
return self::getFib( $num - 2) + self::getFib( $num - 1 );
}
}
}

class FibTest extends PHPUnit_Framework_TestCase
{

public function testFibZero() {
$this->assertEquals( 0, FibCalc::getFib(0) );
}

public function testFibOne() {
$this->assertEquals( 1, FibCalc::getFib(1) );
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testMinusOne() {
FibCalc::getFib(-1);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testString() {
FibCalc::getFib("test");
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testNull() {
FibCalc::getFib(NULL);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testFloatZero() {
FibCalc::getFib(0.0);
}

/**
* @note http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0
*/
public function testFromWikipedia() {
$answers = array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946);
foreach ($answers as $i => $value) {
$this->assertEquals($value, FibCalc::getFib($i));
}
}
}

再帰をやめたプログラム

過去のフィボナッチ数の直近2件を保持。
これならと社内に公開したところ、メソッド名が安直、イテレータにしたほうがまだわかりやすいと指摘を受ける。

<?php

class FibCalc {
private $index;
private $pastValues;

function __construct() {
$this->index = 1;
$this->pastValues = array(0,1);
}

public function getNext() {
$ret = array_sum($this->pastValues);
array_shift($this->pastValues);
$this->pastValues[] = $ret;
$this->index++;
return $ret;
}

public function getIndex() {
return $this->index;
}



static function getFib( $num ) {
if (intval($num) < 0  || !is_int($num)) {
   throw new Exception('Invalid argument');
}
if ($num < 2) {
return $num;
}

$calculator = new FibCalc();
do {
$result = $calculator->getNext();
} while ( $num > $calculator->getIndex() );
return $result;
}
}

class FibTest extends PHPUnit_Framework_TestCase
{

public function testFibZero() {
$this->assertEquals( 0, FibCalc::getFib(0) );
}

public function testFibOne() {
$this->assertEquals( 1, FibCalc::getFib(1) );
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testMinusOne() {
FibCalc::getFib(-1);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testString() {
FibCalc::getFib("test");
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testNull() {
FibCalc::getFib(NULL);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testFloatZero() {
FibCalc::getFib(0.0);
}

/**
* @note http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0
*/
public function testFromWikipedia() {
$answers = array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946);
foreach ($answers as $i => $value) {
$this->assertEquals($value, FibCalc::getFib($i));
}
}
}

インタフェースを改修

ついにimplements Iterator。
ついでにテストもデータプロバイダを利用。
<?php

class FibCalc implements Iterator{
private $index;
private $pastValues;

function __construct() {
$this->rewind();
}

function rewind() {
$this->index = 1;
$this->pastValues = array(0,1);
}

function current() {
return array_sum($this->pastValues);
}

function key() {
return $this->index;
}

function next() {
$ret = $this->current();
array_shift($this->pastValues);
$this->pastValues[] = $ret;
$this->index++;
return $ret;
}

function valid() {
if ($this->index < 0) {
return false;
}

return true;
}




static function getFib( $num ) {
if (intval($num) < 0  || !is_int($num)) {
   throw new Exception('Invalid argument');
}
if ($num < 2) {
return $num;
}

$calculator = new FibCalc();
do {
$result = $calculator->current();
$calculator->next();
} while ( $num > $calculator->key() );
return $result;
}
}

class FibTest extends PHPUnit_Framework_TestCase
{

public function testFibZero() {
$this->assertEquals( 0, FibCalc::getFib(0) );
}

public function testFibOne() {
$this->assertEquals( 1, FibCalc::getFib(1) );
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testMinusOne() {
FibCalc::getFib(-1);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testString() {
FibCalc::getFib("test");
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testNull() {
FibCalc::getFib(NULL);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Invalid argument
*/
public function testFloatZero() {
FibCalc::getFib(0.0);
}

/**
* @dataProvider providerFromWikipedia
*/
public function testFromWikipedia($input, $output) {
$this->assertEquals($output, FibCalc::getFib($input));
}

/**
* @note http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0
*/
public function providerFromWikipedia()
{
return  array( 
array( 0,    0),
array( 1,    1),
array( 2,    1),
array( 3,    2), 
array( 4,    3), 
array( 5,    5), 
array( 6,    8), 
array( 7,   13), 
array( 8,   21), 
array( 9,   34), 
array(10,   55), 
array(11,   89), 
array(12,  144), 
array(13,  233), 
array(14,  377), 
array(15,  610), 
array(16,  987), 
array(17, 1597), 
array(18, 2584), 
array(19, 4181), 
array(20, 6765), 
array(21, 10946)
);
}
}




2013年11月19日火曜日

アプリの継続開発に必要な仕組み


アプリを開発していると、アプリにバグが入ったり、サーバをメンテしたりするときがある。そんなときにアプリが備えていると安心な仕組み。

アプリのバージョン制御(強制バージョンアップ)

万が一、深刻なバグのあるアプリをリリースしてしまっても、そのバージョンを利用不可にできる。

用意するもの:APIサーバ


方法1 (サーバ寄せ)
  1. アプリがAPIにバージョン番号を送る
  2. APIでバージョン番号を見て、バージョンアップが必要ならURLを返す
  3. アプリはURLが返された場合、AppStoreやGooglePlayに遷移する

方法2 (アプリ寄せ)
  1. アプリはAPIにリクエストする
  2. APIは現在利用可能なバージョン番号下限とバージョンアップURLを返す
  3. アプリはAPIが返したバージョンよりも自身のバージョンが低ければ、AppStoreやGooglePlayに遷移する。
方法2ならjsonやxmlの静的ファイルをサーバに置くだけで実現できる。


メンテナンスモード

DBを止めて作業するとき(機能追加によるテーブルの変更、DBのスケールアップなど)に必要。ユーザにメンテ中であることを知らせることができる。


用意するもの:APIサーバ

実現方法
  1. アプリは起動時にAPIにアクセスする
  2. サーバからの応答が503だった場合、アプリは「サーバがメンテナンス中」と判断し、しばらくAPIサーバとの通信をしない状態にする。
    レスポンスヘッダにRetry-Afterがあれば、その時間までメンテナンスモードになるのが理想。





2013年10月14日月曜日

Using Amazon SNS Mobile Push APIs 日本語訳

日本語訳したドキュメント


Amazon Simple Notification Service
Developer Guide (API Version 2010-03-31)

http://docs.aws.amazon.com/sns/latest/dg/mobile-push-api.html

Using Amazon SNS Mobile Push APIs

Amazon SNS モバイルPush APIを使うためには、APNsやGCMなどのPush通知サービスの事前準備を行っておく必要があります。詳細情報についてはPrerequisitesのページを参照。
Amazon SNSのAPIを使ってモバイル機器へとPush通知を送るためには、最初にCreatePlatformApplicationアクションを実行しておく必要があります。CreatePlatoformApplictionアクションはPlatformApplitionArmを返すので、これを使ってCreatePlatformEndpointアクションを実行し、最終的に通知実行に必要なEndpointArnを取得できます。

EndpointArnの用途は

  • PublishアクションにEndpointArnを指定して通知メッセージを送信する
  • SubscribeアクションにEndpointArnを指定してトピックにEndpointを紐付ける

以下はAmazon SNSのモバイルPush APIについてのAPI一覧とその解説です。
APIDescription
CreatePlatformApplicationAPNsやGCMのようなPush通知サービスをサポートするplatform applicationオブジェクトを作成し、モバイル機器を登録できるようにします。
APIの戻り値としてはPlatformApplicationArnがあり、これはCreatePlatformEndpointアクションで利用されます。 詳細はAmazon SNS  APIリファレンスの、CreatePlotformApplicationの項目を参照。
SetPlatformApplicationAttributesplatform applicationオブジェクトに各属性値をセットします。
詳細はAmazon SNS APIリファレンスのSetPlatformApplicationAttributesの項目を参照。
GetPlatformApplicationAttributesplatform applicationオブジェクトの属性値を取得します。詳細はAmazon SNS APIリファレンスのGetPlatformApplicationAttributesの項目を参照。
ListPlatformApplicationsAmazonSNSがサポートしているPush通知サービスに関して、AWSアカウントで作成済みのplatform applicationオブジェクトの一覧を取得します。詳細はAmazon SNS APIリファレンスのListPlatformApplicationsの項目を参照。
DeletePlatformApplicationplatform applicationオブジェクトを削除します。 詳細はAmazon SNS APIリファレンスのDeletePlatformApplicationの項目を参照。
CreatePlatformEndpointAmazonSNSがサポートしているPush通知サービスに関して、モバイル機器用のエンドポイントを作成します。CreatePlatformEndpointアクションには、CreatePlatformApplicationアクションが返すPlatformApplicationArnを入力します。このアクションが返すEndpointArnは、Publishアクションで通知メッセージをモバイル機器へ送信する際に使われます。詳細はAmazon SNS APIリファレンスのCreatePlatformEndpointの項目を参照。

SetEndpointAttributesエンドポイントへモバイル機器やアプリに関する属性をセットします。詳細はAmazon SNS APIリファレンスのSetEndpointAttributesの項目を参照。
GetEndpointAttributesエンドポイントに紐づく情報を取得します。詳細はAmazon SNS APIリファレンスのGetEndpointAttributesの項目を参照。
ListEndpointsByPlatformApplicationAmazonSNSがサポートしているPush通知サービスに関して、エンドポイントをリストとして取得します。詳細はAmazon SNS APIリファレンスのListEndointsByPlatformApplicationの項目を参照。
DeleteEndpointAmazonSNSがサポートしているPush通知サービスに関して、エンドポイントを削除します。詳細はAmazon SNS APIリファレンスのDeleteEndpointの項目を参照。

まとめ

  • 通知を送るにはEndpointArnを指定する
    • もしくはエンドポイントとトピックを紐付けておく
  • EndpointArnを作成するには事前にPlatformApplicationArnを作っておく
    • PlatformAPplicationArnは各通知サービスごとに作成する
      • ADM、APNs本番、APNs砂場、GCM
  • 作成したエンドポイントには端末やアプリの情報を紐付けておくことができる
  • エンドポイントは削除できる(ただし、EndpointArnの指定が必要)
  • platform applicationを削除した際に、紐づくエンドポイントも連動して削除されるかは不明

2013年10月13日日曜日

Amazon SNS Mobile Push Notifications のDeveloper Guide 日本語訳


日本語訳したドキュメント


Amazon Simple Notification Service
Developer Guide (API Version 2010-03-31)

http://docs.aws.amazon.com/sns/latest/dg/SNSMobilePush.html




以下、訳した文章

Amazon SNS Mobile Push Notifications

Amazon SNSによりモバイル機器上のアプリへ通知メッセージを送ることができます。AWS上の“モバイルエンドポイント” へ送られた通知メッセージは、モバイル機器上ののアラート文言、バッジ、サウンドなどの形態で受け取られることになります。 モバイル機器への通知サービスがとして、以下に挙げるサービスが利用できます。
  • Apple Push Notification Service (APNS)
  • Google Cloud Messaging for Android (GCM)
  • Amazon Device Messaging (ADM)

以下の図はAmazon SNS がモバイルエンドポイントへ送られた通知メッセージが如何にしてモバイル機器へと届けるのか、その全体図を示します。

訳者注: Publisher = 通知の送信側 ,    Subscriber=通知を受信するモバイル機器

APNsやGCMのような通知サービスは、モバイル機器とのコネクションを保持しています。アプリとモバイル機器が通知サービスに登録されると、通知サービスはデバイストークンという端末を識別する情報を発行します。Amazon SNSはPublisher(通知送信側)からの通知要求を受け付けるために、デバイストークンを使ってモバイルエンドポイントを作成します。Amazon SNSがPublisherに変わって通知サービスとの通信するため、通信に用いるSSLの秘密鍵などの情報はAmazon SNSに前もって登録しておきます。
通常のエンドポイント指定の通知送信に加えて、”トピック”という機能を利用できます。 モバイルエンドポイントはトピックを購読することができ、トピックに通知メッセージを送ることでトピックに紐づくモバイルエンドポイントすべてへ通知を送ることができます。このため、AmazonSQS, HTTP/S、メール、SMSなどエンドポイントの種類が異なっていても、1つの通知の送信はトピックへ送信依頼の処理1回で済ませることができます。Push通知がメールなどの他のサービスと異なるのは、モバイル機器がメッセージを受信するまでの間にAppleやGoogle などの通知サービス提供者が入っていることです。以下の図はAmazon SNSのトピックを購読するモバイルエンドポイントの例です。 モバイルエンドポイントはAPNsやGCMを通じてアプリに通知メッセージを送りますが、メールなどその他の場合には直接SNSトピックから通知メッセージが送られます。


まとめ


  • 基本的に通知送信側はモバイルエンドポイントを宛先として知っていればよい
    • デバイストークンはAmazonSNS側で管理
    • SSL証明書などのパラメータは前もってAmazonSNSにアップロードしておく
  • 通知の送り先の指定方法として2種類ある
    • エンドポイントに送信
    • トピックへ送信(トピックに紐づくエンドポイントに送信)
  • トピックを使うと通知の種類をまたがった通知が簡単に実現できる
    • 例)iOSアプリにはAPNs、AndroidアプリにはGCM、PC版利用者にはメール
    • 例)iOSアプリ利用者にAPNsとメールを両方送る





2013年1月3日木曜日

残念なメンバーシップの改善方法

目的

標準的な管理手法を理解し、マネージャによるコントロールがしやすい状態にしたい。
そのために、自分が日頃何に気をつければよいか明文化し、それを守る。

改善策

なにをやるか・やらないかの確認

  • スコープ:このプロジェクトは何を作るのか
  • 職責:“自分の”役割と説明責任を理解する
  • 見積もり: 1日8時間、自分の力量を過信せずバッファ込みで

やるべきことをどんな順番でやるか

  • プロジェクトのマイルストーンは何か?いつまでに必要か?
  • 自分の成果物は何か?
    • 不確定なこと、失敗しそうなことはないか?
    • 大変なこと、面倒なことは別の方法で代替できないか?

状況の変化に対してどのように対処するか

  • 成果とスケジュールがベースラインからずれるとき、報告が必要
    • 相手が状況を理解し、対処策の判断できる状態になるまで伝えきる
    • リスクは被害の深刻さと発生確率を評価し、優先度付できるようにする

2013年の目標

はじめに

2012年はリスク管理ができず、いろいろと残念なことがありました。仕事だけに楽しみを見出すことの危険性がよくわかりました。

2013年の目標

  • 楽しいと思えることを1つ以上見つけ、仕事以上にそれを大事にする

評価方法

2013年12月31日に「今年は人間らしく生きた?」と自分に問い、「肯定」の回答が得られること。