2012年11月11日日曜日

開発環境

『初めてのC# 第2版』(Jesse Liberty+Brian MacDonald著、日向俊二訳、オライリー・ジャパン、2006年、ISBN978-487311-294-7)の 第16章(デリゲートとイベント)17.6(練習問題)問題17-3を解いてみる。

その他参考書籍

問題17-3.

コード

using System;
using System.Threading;

class TimeInfoEventArgs : EventArgs
{
    public TimeInfoEventArgs(string msg)
    {
        this.msg = msg;
    }
    public readonly string msg;
}

class Clock
{
    private string msg;
    private DateTime start;
    private DateTime stop;
    public Clock(string msg, int hours, int minutes, int seconds)
    {
        this.msg = msg;
        start = DateTime.Now;
        TimeSpan duration = new TimeSpan(hours, minutes, seconds);
        stop = start + duration;
    }

    public delegate void SecondChangedHandler(object clock, TimeInfoEventArgs ti);
    public event SecondChangedHandler SecondChanged;
    public void Run()
    {
        for (int i = 0; ; i++)
        {
            Console.WriteLine("{0}秒経過", i);
            DateTime now = DateTime.Now;
            if (now >= this.stop)
            {
                TimeInfoEventArgs ti =
                    new TimeInfoEventArgs(msg);
                if (SecondChanged != null)
                {
                    SecondChanged(this, ti);
                    break;
                }
            }
            Thread.Sleep(1000);
        }
    }
}

class DisplayClock
{
    public void Subscribe(Clock clock)
    {
        clock.SecondChanged +=
            new Clock.SecondChangedHandler(TimeHasChanged);
    }
    public void TimeHasChanged(object clock, TimeInfoEventArgs ti)
    {
        Console.WriteLine("{0}", ti.msg);
    }
}

class Tester
{
    public void Run()
    {
        Console.WriteLine("通知してほしい経過時間を入力");
        Console.Write("時間: ");
        int hours = Convert.ToInt16(Console.ReadLine());
        Console.Write("分: ");
        int minutes = Convert.ToInt16(Console.ReadLine());
        Console.Write("秒: ");
        int seconds = Convert.ToInt16(Console.ReadLine());
        Console.Write("経過したときのメッセージ: ");
        string msg = Console.ReadLine();

        Clock clock = new Clock(msg, hours, minutes, seconds);
        DisplayClock dc = new DisplayClock();
        dc.Subscribe(clock);
        clock.Run();
    }
    static void Main()
    {
        Tester t = new Tester();
        t.Run();
    }
}

入出力結果(Console Window)

通知してほしい経過時間を入力
時間: 0
分: 3
秒: 0
経過したときのメッセージ: カップラーメン出来上がり!
0秒経過
1秒経過
2秒経過
3秒経過
4秒経過
5秒経過
6秒経過
7秒経過
8秒経過
9秒経過
10秒経過
11秒経過
12秒経過
13秒経過
14秒経過
15秒経過
16秒経過
17秒経過
18秒経過
19秒経過
20秒経過
21秒経過
22秒経過
23秒経過
24秒経過
25秒経過
26秒経過
27秒経過
28秒経過
29秒経過
30秒経過
31秒経過
32秒経過
33秒経過
34秒経過
35秒経過
36秒経過
37秒経過
38秒経過
39秒経過
40秒経過
41秒経過
42秒経過
43秒経過
44秒経過
45秒経過
46秒経過
47秒経過
48秒経過
49秒経過
50秒経過
51秒経過
52秒経過
53秒経過
54秒経過
55秒経過
56秒経過
57秒経過
58秒経過
59秒経過
60秒経過
61秒経過
62秒経過
63秒経過
64秒経過
65秒経過
66秒経過
67秒経過
68秒経過
69秒経過
70秒経過
71秒経過
72秒経過
73秒経過
74秒経過
75秒経過
76秒経過
77秒経過
78秒経過
79秒経過
80秒経過
81秒経過
82秒経過
83秒経過
84秒経過
85秒経過
86秒経過
87秒経過
88秒経過
89秒経過
90秒経過
91秒経過
92秒経過
93秒経過
94秒経過
95秒経過
96秒経過
97秒経過
98秒経過
99秒経過
100秒経過
101秒経過
102秒経過
103秒経過
104秒経過
105秒経過
106秒経過
107秒経過
108秒経過
109秒経過
110秒経過
111秒経過
112秒経過
113秒経過
114秒経過
115秒経過
116秒経過
117秒経過
118秒経過
119秒経過
120秒経過
121秒経過
122秒経過
123秒経過
124秒経過
125秒経過
126秒経過
127秒経過
128秒経過
129秒経過
130秒経過
131秒経過
132秒経過
133秒経過
134秒経過
135秒経過
136秒経過
137秒経過
138秒経過
139秒経過
140秒経過
141秒経過
142秒経過
143秒経過
144秒経過
145秒経過
146秒経過
147秒経過
148秒経過
149秒経過
150秒経過
151秒経過
152秒経過
153秒経過
154秒経過
155秒経過
156秒経過
157秒経過
158秒経過
159秒経過
160秒経過
161秒経過
162秒経過
163秒経過
164秒経過
165秒経過
166秒経過
167秒経過
168秒経過
169秒経過
170秒経過
171秒経過
172秒経過
173秒経過
174秒経過
175秒経過
176秒経過
177秒経過
178秒経過
カップラーメン出来上がり!
続行するには何かキーを押してください . . .

時間を長めに設定すると、表示される経過秒に誤差がでるなぁ。。

ちなみにJavaScriptの場合。

通知して欲しい経過時間




コード(TextWrangler)

var msg = $('#t0').val();
var hours = parseInt($('#t1').val());
var minutes = parseInt($('#t2').val());
var seconds = parseInt($('#t3').val());

var start = new Date();
var stop = new Date();
stop.setHours(start.getHours() + hours);
stop.setMinutes(start.getMinutes() + minutes);
stop.setSeconds(start.getSeconds() + seconds);
var i = 0;
var timer = setInterval(function(){
  $('#pre0').append(i + "秒経過\n");
  if(start >= stop){
    $('#pre0').append(msg);
    clearInterval(timer);
  } else {
    i++;
    start.setSeconds(start.getSeconds() + 1);
  }
}, 1000);


pythonの場合。

sample.py

コード(TextWrangler)

#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-

import datetime
import time

print("通知して欲しい経過時間を入力")
print("時: ", end="")
hours = int(input())
print("分: ", end="")
minutes= int(input())
print("秒: ", end="")
seconds = int(input())
print("経過したときのメッセージ: ", end="")
msg = input()

start = datetime.datetime.today()
stop = datetime.datetime(start.year, start.month, start.day, start.hour + hours, start.minute + minutes, start.second + seconds)
i = 0
while True:
  print("{0}秒経過".format(i))
  i += 1
  now = datetime.datetime.today()
  if now >= stop:
    print(msg)
    break
  time.sleep(1)

入出力結果(Terminal)

$ ./sample.py
通知して欲しい経過時間を入力
時: 0
分: 3
秒: 0
経過したときのメッセージ: カップラーメン出来上がり!
0秒経過
1秒経過
2秒経過
3秒経過
4秒経過
5秒経過
6秒経過
7秒経過
8秒経過
9秒経過
10秒経過
11秒経過
12秒経過
13秒経過
14秒経過
15秒経過
16秒経過
17秒経過
18秒経過
19秒経過
20秒経過
21秒経過
22秒経過
23秒経過
24秒経過
25秒経過
26秒経過
27秒経過
28秒経過
29秒経過
30秒経過
31秒経過
32秒経過
33秒経過
34秒経過
35秒経過
36秒経過
37秒経過
38秒経過
39秒経過
40秒経過
41秒経過
42秒経過
43秒経過
44秒経過
45秒経過
46秒経過
47秒経過
48秒経過
49秒経過
50秒経過
51秒経過
52秒経過
53秒経過
54秒経過
55秒経過
56秒経過
57秒経過
58秒経過
59秒経過
60秒経過
61秒経過
62秒経過
63秒経過
64秒経過
65秒経過
66秒経過
67秒経過
68秒経過
69秒経過
70秒経過
71秒経過
72秒経過
73秒経過
74秒経過
75秒経過
76秒経過
77秒経過
78秒経過
79秒経過
80秒経過
81秒経過
82秒経過
83秒経過
84秒経過
85秒経過
86秒経過
87秒経過
88秒経過
89秒経過
90秒経過
91秒経過
92秒経過
93秒経過
94秒経過
95秒経過
96秒経過
97秒経過
98秒経過
99秒経過
100秒経過
101秒経過
102秒経過
103秒経過
104秒経過
105秒経過
106秒経過
107秒経過
108秒経過
109秒経過
110秒経過
111秒経過
112秒経過
113秒経過
114秒経過
115秒経過
116秒経過
117秒経過
118秒経過
119秒経過
120秒経過
121秒経過
122秒経過
123秒経過
124秒経過
125秒経過
126秒経過
127秒経過
128秒経過
129秒経過
130秒経過
131秒経過
132秒経過
133秒経過
134秒経過
135秒経過
136秒経過
137秒経過
138秒経過
139秒経過
140秒経過
141秒経過
142秒経過
143秒経過
144秒経過
145秒経過
146秒経過
147秒経過
148秒経過
149秒経過
150秒経過
151秒経過
152秒経過
153秒経過
154秒経過
155秒経過
156秒経過
157秒経過
158秒経過
159秒経過
160秒経過
161秒経過
162秒経過
163秒経過
164秒経過
165秒経過
166秒経過
167秒経過
168秒経過
169秒経過
170秒経過
171秒経過
172秒経過
173秒経過
174秒経過
175秒経過
176秒経過
177秒経過
178秒経過
179秒経過
カップラーメン出来上がり!

メモ: PythonでもC#と同様に誤差が出た。。JavaScriptだけが唯一誤差が出なかったし、C#もPythonもコードの書き方に問題がありそう。どちらにもJavaScriptのsetInteervalみあたいな関数、メソッドが用意されてそうだし、それを見つければ誤差がでないように上手く書けるかも。とりあえず今回はこれでよしとして、次に挑戦するときには探してみることに。

0 コメント:

コメントを投稿