コロナで始めたランニング

テレワークになりすっかり体重が増えてしまった(74kg→77kg)。このぐらい普通じゃんと思うかもしれない。ただ、180cmの標準体重は71kg程度で健康診断で「美しい体ですね」と割と美人先生から言われた意味深体重も70.8kgだったので私の中のベストは71kg付近なのかなと。

 

こりゃまずいと8月中旬から動き始め今現在(9月末)に74.5kgまで無理なく落とせた。やはり谷ランニング5kmを毎日無理なく走破しているのが大きいと思う。(横浜だから坂ラニングというか谷ランニング)。なぜ無理なく続けられたのか振り返ってみようと思う。

 

まず初めの1週間は歩くところから始めた。20分程度ぶらぶらと夜散歩するだけである。蝉の声やら鈴虫の声、暴走族のバイクの音、突然聞こえるおばあちゃんの爆笑の声と耳を傾けると面白い気持ちになり自然と毎日続けられた。

 

だんだんと歩くことに慣れてきて、歩きの後半は走ってみた。走るといっても8分/1kmで1.5km走破と結構なスロースピードである。これでも夏の夜だからか結構な汗をかいていて、俺の汗クサ!っと一人で悲しんでいたことを非常によく覚えている。

 

だんだんと慣れてきて(初めて2週間程度だったかな)、初めは歩き→ランニング。だったのがランキング→ランニング。となり、3kmを走れるようになった。スピードは7分/1km程度とおっさん成長してんじゃん。と無駄に感動したことを覚えている。(汗クサのほうがよく覚えているが。。)また、恐る恐る体重計に乗ってみるとなんと-1kg達成している。目標面談でA+ぐらい取れそうな気分である。最近仕事でA+なんてとってないけど。。

 

このころになると、だんだんと足が痛くなってくる。まあ、10年ぐらい動いてないから仕方ない。なので痛いときは無理しないで、腹筋(20×3)、腕立て(15×3)とストレッチとビールとポテチを食べた。

 

だんだんと慣れてきて、走ることが楽しくなってきたころ、ふと当初の目的を思い出すと「痩せること」と思い出す。手っ取り早く痩せるには食事制限が効果的らしいが、食べたいものは我慢したくないし、痩せて不健康になるもの本末転倒な気がして避けた。なので、グリコ パワープロテイン的なドーピング?をして走ることにした。効果あるんだかないんだかわからないけど、プロテインのむ→走る→風呂入る→PCの前で作業をすると、このPCで作業しているときもなぜか汗が吹き出しまだまだ体が燃えている感が継続していた(ただ部屋の温度が高いだけかもですが。。)おかげで朝起きてまたシャワーを浴びたい気分になるというなんだかなー生活を送った。。

 

で、走り始めて3週間目になって5kmを走れるようになった。6分/1kmなのでやはり当初より成長している。もう自己評価的にS+ぐらいだ。昇格レベルですね。このころになると大会で走れんじゃね?となりタイムを見ると5kmは25分程度が標準らしいことがわかる。つまり5分/1km。谷を走っているとはいえまだまだなレベル。自己評価はS+だけど、会社の評価はCか努力したね。の恩情評価でB-的なレベルでした。。

 

とはいえ、秋のこの時期は走っていて本当に気持ちいいし、体重も落ちたけどテレワークで感じた頭痛や肩こりは一切感じなくなっている。タイムや距離がこのままどこまで伸びるかわからないけど続けてみようかなと。

 

下記は続けるにあたって、個人的にヒットしたアイテム。

 

まずはApple Watch。これは必須かと。走った距離がわかるのと、ランニングのペースがわかるため、1週間前は1.5kmしか走れなかったけど、今週は3kmも走れた。とかってに数値化してくれるためモチベーションが保ちやすい。消費カロリーもわかるため今日ビール飲んでもいいジャン的な気分にもなれるw(と同時に5km走っても350kカロリー程度しか消費しないんだね。。とがっくり来たんですが。。)

ビール飲みたい日はコンビニよってQuickPayで支払ってビール頼んでます(GPSモデルだから携帯も必要なんだけど。。) 

 

 ランニング際は何も持ちたくないかつかぎ落すの怖いなーと思っている人なので(1,000札と名前と住所かいてある紙は小銭入れに入れて走ってますが)、家の開施錠はApple Watchのセサミアプリからやってます。今のところ一度もあかない。といったことは起きてないためあまり心配してませんが、万が一あかない。といった事態が起きた場合は妻をたたき起こすしかないとあきらめてますw(一人暮らしだと鍵を持つしかないか。とあきらめて走ると思います)

 

 初心者×道路のコンクリを走る×なるべく毎日走りたいとなるとクッション性があって足を守ってくれるシューズのほうがいいと思い、スポーツ店で探していたところこちらを勧められました。ミズノやナイキの同様のシューズも試し履きしてどちらも歩いた感じのクッション性はこのシューズよりあったのですが、一番足にフィットしたのがこちらだったので、アシックスにしました。初心者はぜひ一度スポーツ店で試し履きをしたほうがいいと思います。実際走ってみるとクッション性が効いていることがわかり、またこのシューズ前(10年前に買ったウォーキングシューズ)で走っていたころは足首に痛みが残りましたが、このシューズにしたところすっかりなくなりました。1世代前。おそらくもう少ししたら新しいのが出ると思うので2世代前になりますが安く手に入るため、もし足に合うなら個人的にはおすすめです。(わかりやすいようにAmazonのリンクを設けてますが、スポーツ店で試し履きをお勧めします)

 

 

 個人的に効いているかどうかわからないやつ。飲んでいるときと飲んでないときの体重の変異を比べようもないから仕方ないけど、飲んで走って痩せてるから、飲まなくなるとどうなるのか怖いため飲み続けるという。。

 

 

 

 

 1週間に一度Netflixを鑑賞しながら楽しんでます。これやめれば金銭的にも健康的にも体重的にもいいことはわかってますが、これやめた瞬間にストレスたまりそうなので絶対やめません。太ってでも。。。。

 

 

ぺったり取っ手

無印で8キロぐらいの棚をレジに持って行った。
店員さんが「とって付けますねー」といった。
ああ、青プラスチック?のあれね。。。と思っていたら、
ペラペラの取っ手付きシール2枚を段ボールの両脇に「ぺった」とはった。



はい????
いやいや、絶対取れる or 破けるでしょ!!!
無印から500mぐらい離れた家まで持って帰るし。
だけど、店員さんの自信満々の笑みに心砕かれ取っ手に手をかけ
レジを後にした。(途中で破けても抱きかかえてもって帰ればいいしー)



結果。
無事に自宅まで持って帰れましたとさ。。。。
とってシールすげー!!

modelmapperを触ってみた

modelmapperは、開発でよく出くわす「〜層へのオブジェクト伝搬。(Bean Mapping)」これをさくっと出来るライブラリらしいです。最近infoqで取り上げられていました。「en」「jp

例えば、T1#name1をT2#name1に値コピーとT2のBean生成.

class T1 {
     private String name1;
     //getter setter name1;
}
class T2 {
     private String name1;
     private String name2;
     private String name3 = "hello";
     //getter setter name1,name2;
}

main(String... args) {
     T1 t1 = new T1();
     t1.setName1("hello");
     ModelMapper mapper = new ModelMapper();
     T2 t2 = mapper.map(t1,T2.class);
     System.out.println(t2.getName1());
}
//console:>hello

次に、T1#name1をT2#name2に値コピーとT2のBean生成.

main(String... args) {
     T1 t1 = new T1();
     t1.setName1("hello2");
     PropertyMap<T1,T2> pmap = new PropertyMap<T1, T2>() {
          @Override
	  protected void configure() {
	          map().setName2(source.getName1());
	   }
      };
     ModelMapper mapper = new ModelMapper();
     mapper.addMappings(pmap);
     T2 t2 = mapper.map(t1,T2.class);
     System.out.println(t2.getName2());
}
//console:>hello2

次に、T1#name1をT2#name3に値コピー(上書き)とT2のBean生成.
ただし、T1#name1がnullの場合、値は上書きしない。

main(String... args) {
     T1 t1 = new T1();
     t1.setName1("hello3");
     PropertyMap<T1,T2> pmap = new PropertyMap<T1, T2>() {
         @Override
	 protected void configure() {
		when(new Condition<T1,T2>() {
		     @Override
		     public boolean applies(MappingContext<T1, T2> context) {
				return context.getSource() != null;
		      }
                  }).map().setName3(source.getName1());
           }
	};
       ModelMapper mapper = new ModelMapper();
       mapper.addMappings(pmap);
       T2 t2 = mapper.map(t1,T2.class);
       System.out.println(t2.getName3());
       t1.setName1(null);
       t2 = mapper.map(t1,T2.class);
       System.out.println(t2.getName3());
}
//console:>hello3
//console:>hello

その他、値のconverter等が出来るらしい。(まだ1時間程度しか触っていないため、機能の詳細はつかめず)

こういったBean Mappingライブラリは、単純なものだとBean Utils等で済ませられるが、単純すぎて使えないシーンが多い。また、Dozer等はXMLが面倒で私の気性にあわなくてだめ。また、文字列でBean同士のMappingをするライブラリ(ognl?)もIDEの支援が受けられなくて、Propertieの名称が変わると面倒。

というわけで、「modelmapper」はBean Mapping の操作はごりごりとgetter/setterでやっていた派としては割と好感触。ただ、安定性はいまいちつかめない。少なくとも、propertiesのスキップ条件とマッピング条件の整理と、Conditional Mappingを使わないで定義できる条件のバリエーションをそろえた方が使い勝手はよいと思う。とりあえず、この3連休forkして見てみようと。

http://modelmapper.org

strtus2のデフォルトValidationであるConnvertionパッケージ以下を使用した場合、SkipValidationアノテーションが使える。
が、ovalでは使用できない。(使用できるかも知れませんが、ちょっと調べただけでは分からずじまい)
これに不便を感じ、SkipOvalValidationなるものを作成し使用した。

@SkipOvalValidation

package org.framework.ext.oval.validation;

import static java.lang.annotation.ElementType.METHOD;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(METHOD)
public @interface SkipOvalValidation {
}

OvalAnnotationValidationInterceptor

package org.framework.ext.oval.validation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;

import org.apache.struts2.oval.interceptor.OValValidationInterceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.AnnotationUtils;

public class OvalAnnValidationInterceptor extends OValValidationInterceptor{

	protected String doIntercept(ActionInvocation invocation) throws Exception {
		if (checkSkipValidation(invocation))
			return invocation.invoke();
		return super.doIntercept(invocation);
	}

	protected boolean checkSkipValidation(ActionInvocation invocation) throws Exception {
		Object action = invocation.getAction();
		if (action != null) {
            Method method = getActionMethod(action.getClass(), invocation.getProxy().getMethod());
            Collection<Method> annotatedMethods = AnnotationUtils.getAnnotatedMethods(action.getClass(), SkipOvalValidation.class);
            if (annotatedMethods.contains(method))
                return true;
            //check if method overwites an annotated method
            Class clazz = action.getClass().getSuperclass();
            while (clazz != null) {
                annotatedMethods = AnnotationUtils.getAnnotatedMethods(clazz,  SkipOvalValidation.class);
                if (annotatedMethods != null) {
                    for (Method annotatedMethod : annotatedMethods) {
                        if (annotatedMethod.getName().equals(method.getName())
                                && Arrays.equals(annotatedMethod.getParameterTypes(), method.getParameterTypes())
                                && Arrays.equals(annotatedMethod.getExceptionTypes(), method.getExceptionTypes()))
                            return true;
                    }
                }
                clazz =  clazz.getSuperclass();
            }
        }
		return false;
	}
	 protected Method getActionMethod(Class actionClass, String methodName) throws NoSuchMethodException {
	        Method method;
	        try {
	            method = actionClass.getMethod(methodName, new Class[0]);
	        } catch (NoSuchMethodException e) {
	            try {
	                String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
	                method = actionClass.getMethod(altMethodName, new Class[0]);
	            } catch (NoSuchMethodException e1) {
	                // throw the original one
	                throw e;
	            }
	        }
	        return method;
	    }
}

strtus.xml

<package name="ann-oval-default" extends="struts-default">
           <interceptors>
               <interceptor name="annOvalValidation" class="org.framework.ext.oval.validation.OvalAnnValidationInterceptor" />
               <interceptor-stack name="ovalAnnotaionStack">
               	   <interceptor-ref name="autowiring" />
                   <interceptor-ref name="exception"/>
                   <interceptor-ref name="alias"/>
                   <interceptor-ref name="servletConfig"/>
                   <interceptor-ref name="i18n"/>
                   <interceptor-ref name="prepare"/>
                   <interceptor-ref name="chain"/>
                   <interceptor-ref name="debugging"/>
                   <interceptor-ref name="profiling"/>
                   <interceptor-ref name="scopedModelDriven"/>
                   <interceptor-ref name="modelDriven"/>
                   <interceptor-ref name="fileUpload"/>
                   <interceptor-ref name="checkbox"/>
                   <interceptor-ref name="staticParams"/>
                   <interceptor-ref name="actionMappingParams"/>
                   <interceptor-ref name="params">
                       <param name="excludeParams">dojo\..*,^struts\..*</param>
                   </interceptor-ref>
                   <interceptor-ref name="conversionError"/>
                   <interceptor-ref name="annOvalValidation">
                       <param name="excludeMethods">input,back,cancel,browse</param>
                   </interceptor-ref>
                   <interceptor-ref name="workflow">
                       <param name="excludeMethods">input,back,cancel,browse</param>
                   </interceptor-ref>
               </interceptor-stack>
           </interceptors>
    </package>

TestAction

@Namespace("/")
@ParentPackage("ann-oval-default")
@InterceptorRefs({
	@InterceptorRef(value="ovalAnnotaionStack")
})
@Results({
	@Result(name="success" ,  type="dispatcher" , location="success.jsp")
})
public class TestAction extends ActionSupport {
        @NotEmpty
	private String name;
	
	@SkipOvalValidation
	public String sayName() {
		return "success";
	}
	
	public String checkName(){
		return "success";
	}
	
	public String execute() {
		return "success";
	}
}

success.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="windows-31j"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
	<s:form>
	<s:fielderror></s:fielderror>
          name:<s:input name="name" />
          <s:submit action="input" method="sayname" value="sayname(skip)"></s:submit>
          <s:submit action="input" method="check" value="check"></s:submit>
          </form>
</body>
</html>

見てわかるように、org.apache.struts2.interceptor.validationの中身を少しアレンジしただけ。
struts-ovalプラグイン担当に提案した方がいいのかなぁ。。。

 システムアーキテクトの午後問題(I)は得べし

次週のシステムアーキテクトの為に昨日からシャカリキに勉強しているが、いま非常に後悔している。


今から来週まで参考書の問題全てを解答出来いからだ。
なぜなら、午後問題(I)に様々な業種のシステムが単純化され、開発の問題として提示されており、各場面(企画、開発、運用、等々)に触れる事が出来るからだ。
これは、ソフトウェアアーキテクトは、改修・新規構築システムを適切にモデリングし、関係者に対しそのモデルに対する回答責任がある。と思っている私のような輩には非常に痛い。*1


そして、もうひとつは、「論文」が思ったより書けないからだ。。。。


*1.試験が終わっても、参考書とけばいいじゃん!って思うかも知れませんが、教科書が嫌いな人にとって問1..Nを解答するのは、リリース日が必要なのです(はははぁ〜。。。)


ソフトウェアアーキテクトが知るべき97のこと

ソフトウェアアーキテクトが知るべき97のこと

Mysql Access denied for userにはまった

RedMineCentOS(Vm)にインストールしようと、Mysql5.5をセットアップ。
RedMindMineのテーブルを作成しようとすると「 Access denied for user 」が出てしまう。。。。
てか、mysql -u user_redmine -p を打ち込んでも「 Access denied for user」が。。。
仕方ないから、/var/lib/mysql以下を全て消して、Mysqlクリーンインストール + サボってた「mysql_secure_installation」を実行。
すると、無事解決!!。Mysqlをインストールしたら、とりあえず、
1.my.cnfにutf8を追加
2.mysql_secure_installation
をしておけばいいのか?てか「mysql_secure_installation」はrootユーザのコントロールと匿名ユーザのブロックしか設定しないと思っていただけに、
原因が分からず気持ち悪い。
本当は調べたいけど、忙しいからまあいいや。

Eclipse64bitはいい感じ

最近、Androidのソフトを作るのにはまっています。GPSを使ったアプリ開発とか、モーションセンサーとか面白すぎです。
ただ、画面をプレビュー&開発できるGraphical Layoutのところでメモリーが足りなくてよく落ちてしまう。。。Eclipse 32bitなので、ヒープを1024Mしか確保できるのですが、それではまったく歯がたたないらしい。
なので、win7 64bit力を借り、メモリーいっぱい確保しましょう。という魂胆。

以下のようにしたら、一応何も問題なく動いたので、一応展開します。
*試すのは、自己責任で。

1.以下のサイトからjdk ver6,64bitを落とし、インストール。
http://www.oracle.com/technetwork/java/javase/downloads/index.html
2.以下のサイトからEclipse3.7を落とし、解凍。
 (私は、Eclipse IDE for Java EE Developers)を選択
http://www.eclipse.org/downloads/
3.Pleiadesから、JREなしのEclipseを落とし、解凍。
 (私は、Javaを選択)
http://mergedoc.sourceforge.jp/index.html#/pleiades.html
4. 2.で解凍したEclipseが起動するか確認し、起動したら閉じる。
5. 3.で解凍したEclipseにある「dropins」フォルダを2.で解凍したフォルダに上書きする。
6. 起動できるか確認。
7. 2.で解凍したフォルダにあるeclipse.iniの末尾に「-javaagent:dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar」を入れる。
ちなみに、今回の目的であるメモリー拡大大作戦のため、以下のようにeclipse.iniを編集した。

-startup
plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.100.v20110502
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
512M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
512m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms1024m
-Xmx2048m
-javaagent:dropins/MergeDoc/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar

8.Eclipseを起動する。
9.今まで使用していたEclipseプラグインをインストールするため、ファイル->インポート->インストール->既存インストールからを選ぶ。
10.インポートダイアログの「元のアプリケーション・インストール」に今まで使用してたEclipseのインストール(展開)フォルダを指定する。
11.一覧が表示されたら、いるものをチェックし、インストールする。
 (ちなみに私は、Androiodの開発系とPython系の開発、javaのテストをインストール。Google Apps Engineはインストールできなかったため、別途インストールした。)
12.終了。

以上です。画像なしでわかりづらいですね。。面倒なんです。。。ごめんなさい。