読者です 読者をやめる 読者になる 読者になる

イヤホン修理。

いつもはソフトウェアエンジニア(プログラマ)として働いたり、
趣味でコーディングしたりしていますが、
今回は断線してしまったイヤホンのプラグ交換。
ネットにいくつか交換方法が載ってたので、結構参考になりました。

段ボールに刺して固定するのはナイスアイディアだと思いました。
d.hatena.ne.jp

ページング多すぎてうざかったですけど一番わかりやすかった。
monostudio.jp


f:id:ckoshien:20170202155110j:plain
上から
・半田付け後にボンドで固めたところ
・根本を熱収縮チューブで固定
・付属のカバーをつける
・完成
半田ごてを使うのは中学の技術の授業と
折れた傘の骨を無謀にも半田で接着しようとしたころですかね。
もう15年ぐらい半田ごて触ってなかったです。

広告を非表示にする

S2Chronos始めました(今更)

趣味で開発している野球リーグスコア管理システム
バッチ処理を新たに2つほど追加しました。

  • 30日間天気予報取得バッチ(6時間ごと)
  • 決め太郎スケジュール変更監視バッチ(4時間ごと)

使っているFWがSAStruts(Seasar2)なのでバッチはS2Chronos
少し設定ファイル書いてやればそのままデプロイできるので割と便利。

@Task
@CronTrigger(expression = "0 0 */6 * * ?")//6時間ごと
public class GetWeatherTask {
	@Resource
	public WeatherService weatherService;
	public List<Weather> weatherList;
	public HashMap<String,WeatherDto> response;

	private static Logger logger = Logger.getLogger("rootLogger");
	// タスク処理
	public void doExecute() {
		weatherList=weatherService.findAllOrderByRegTime();
		response=new HashMap<String,WeatherDto>();
		//テーブル全データ削除
		long t3=System.currentTimeMillis();
		for(int i=0;i<weatherList.size();i++){
			weatherService.delete(weatherList.get(i));
		}
		long t4=System.currentTimeMillis();
		WeatherAction weatherAction =new WeatherAction();
		response=weatherAction.get();
		long t5=System.currentTimeMillis();
		String date="";
		WeatherDto weatherDto= new WeatherDto();
		for(Map.Entry<String, WeatherDto> e : response.entrySet()) {
			date=e.getKey();
			weatherDto=e.getValue();
			Weather weatherBean= new Weather();
			BeanUtil.copyProperties(weatherDto, weatherBean);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
			java.util.Date formatDate = null;
			String todayStr= new SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date()).replaceAll("-", "/");
			int year=Calendar.getInstance().get(Calendar.YEAR);
			java.util.Date today=null;
			try {
				formatDate = sdf.parse(year+"/"+date);
				today=sdf.parse(todayStr);
			} catch (ParseException e1) {
				e1.printStackTrace();
			}
			if(today.compareTo(formatDate)>0){
				weatherBean.date=Date.valueOf(String.valueOf(year+1)+"-"+date.replaceAll("/", "-"));
			}else{
				weatherBean.date=Date.valueOf(String.valueOf(year)+"-"+date.replaceAll("/", "-"));
			}
			weatherService.insert(weatherBean);
		}
		long t6=System.currentTimeMillis();
		logger.info("天気テーブル全削除:"+(t4-t3));
		logger.info("天気データ取得:"+(t5-t4));
		logger.info("天気データinsert:"+(t6-t5));
		logger.info("タスク終了");
	}
}

Java7のソートにバグがあるの初めて知った。
Listのソートをする際にComparator使うやり方で、

Collections.sort(rbiTop10, new RbiComparator());
Collections.reverse(rbiTop10);

Collections.sortを使うと
Comparison method violates its general contract!
というエラーが返される。
調べてみたら既知のバグらしいが...。
http://blog.satotaichi.info/timsort-was-broken/
回避方法はいくつか試したけどJDKを6に落とせばバージョンが古いと怒られ...。
Collections.sortでも必ずエラーとなるわけではなく、
上記コードの前に要素数が同じソートをやっているが何も起こらずじまい。
とりあえず怖いので使わないことに越したことはないかと。
最悪自前でインデックスソートとかなら書けるはず...ずいぶん使ってないけど。
SQLでorder byすることもできなくはないけど1ページで同じ結果を複数用意するのに
何本もSQLを流していいものか...。

コーディングのリハビリ始めました。
seasar2とかしばらく使ってなかったのであちこちでエラー出して行き詰まるw
バリデータ関係もようやく少しずつ思い出してきたけど、
こういうやり方できるんだね。input="***.jsp"しか教わらなかったから新鮮。
#バリデートに引っかかったらメソッドを再度実行
@Execute(validator = true,input="(メソッド名)?redirect=true")
(参考)http://yakinikunotare.boo.jp/orebase2/sastruts/input_check
DBにアクセスするメソッドだとjspだけ呼ぶと入力値が空だったりするので。

SourceForgeへのコミットができなくなってた件。
秘密鍵はOpenSSH方式に変換しないと使えないのね。
コミット誤操作+未コミットのソース消えたw

いったんロケーション廃棄して再接続するとよい。

seasar2フレームワークが3ケ月ぐらいブランクあってjspとかもなかなか思い出せなかった。
次はたぶん別のフレームワークだけどコーディングの勘ぐらいは取り戻しておきたい。
本日のネタはナップザック問題。動的計画法で解けるアレです。
他言語のソースをjavaに直して何とかしたものですw

public class knapsack {
	public static void main(String[] args) {
		int capacity = 143;
		int[]price={
				10788,10721,10513,10236,9478,
				9478,9111,8831,8831,7693,
				7535,7181,7068,6918,6874,
				6859,6737,6591,6496,6212,
				6017,5912,5786,5708,5574,
				5513,5144,5110,4954,4827,
				4560,4559,4466,4428,4081,
				3886,3247,3217,3064,3016,
				2898,2826,2780,2642,2580,
				2485,2245,2203,1742,2063,
				2058,2013,1996

			};
		int[]weight={
				11,9,12,9,14,
				14,8,9,14,12,
				10,8,13,11,8,
				12,9,12,12,11,
				12,11,11,9,5,
				5,11,6,10,7,
				7,8,8,11,8,
				8,9,9,5,6,
				8,6,11,6,13,
				13,11,12,11,8,
				11,12,11
				};
		System.out.println(computeKnapsack(capacity,price,weight));
	}

	public static int computeKnapsack(int capacity, int[] price, int[] weight) {
		int numItem = price.length;
		int[][] dp = new int[numItem + 1][capacity + 1];
		int[][] g = new int[numItem + 1][capacity + 1];
		for (int c=0;c<=capacity;c++){
			dp[0][c]=0;
			g[0][c]=1;
		}
		for(int i=1;i<=numItem;i++){dp[i][0]=0;}
		for (int c = 1; c <= capacity; c++) {
			dp[1][c] = c < weight[0] ? 0 : price[0];
//			g[0][c]=0;
		}
		for (int i = 2; i <= numItem; i++) {
			for (int c = 1; c <= capacity; c++) {
				if (c < weight[i - 1]) {
					dp[i][c] = dp[i - 1][c];
					g[i][c] = 0;
				} else {
					dp[i][c] = Math.max(dp[i - 1][c], dp[i - 1][c - weight[i - 1]]
							+ price[i - 1]);
					g[i][c] = 0;
					if (dp[i][c]==dp[i - 1][c - weight[i - 1]]
					                        + price[i - 1]){
							g[i][c]=1;
						}
				}
			}
		}
		for(int i=1;i<numItem+1;i++){
			for(int j=1;j<capacity+1;j++){
//				System.out.println("d["+i+"]["+j+"]="+dp[i][j]);
				if(j<=capacity+1){
					System.out.printf("|%5d(%1d,%2d)",dp[i][j],g[i][j],i);
				}
				if(j==capacity){System.out.println("");}
			}
		}

		int c=capacity;
		for (int i=numItem;i>0;i--){
			if(g[i][c]==1){
				System.out.print(price[i-1]+" ");
				c=c-weight[i-1];
			}
		}
		return dp[numItem][capacity];
	}
}

用途?GF(仮)のセンバツ編成を考えるためw
最後に何を選択したかの表示にまだ少しバグがあるけども。
さすがにDB使うまでのものでもないかなぁ....。
これも2,3ケ月前に作った(翻訳した)ものなのでアルゴリズムが思い出せないw