キッチンタイマー
Posted feedbacks - Flatten
Nested HiddenTkとWin32::Soundで。
Win32::Soundを使っているので、Windows環境限定です。
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 | use strict;
use warnings;
use Tk;
BEGIN {
if ( $^O !~ /Win32/ ) {
die q/ごめん、無理/;
}
eval q/use Win32::Sound/;
die $@ if $@;
}
my $mw = Tk::MainWindow->new(
-title => q/KitchenTimer/,
);
my $count = 0;
$mw->Entry(
-textvariable => \$count,
)->pack;
my $start = $mw->Button(
-text => q/start/,
-command => \&start_timer,
);
$start->pack;
my $stop = $mw->Button(
-text => q/stop/,
-command => \&stop_timer,
-state => q/disabled/,
);
$stop->pack;
$mw->MainLoop;
my $timer;
sub start_timer
{
return if $count <= 0;
$timer = $mw->repeat(1000, \&process_timer);
$start->configure(-state => q/disabled/);
$stop->configure(-state => q/normal/);
}
sub stop_timer
{
$timer->cancel if $timer;
$timer = undef;
$start->configure(-state => q/normal/);
$stop->configure(-state => q/disabled/);
}
sub process_timer
{
if ( --$count == 0 ) {
Win32::Sound::Play(q/ding.wav/);
stop_timer;
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/env python
import sys, time, math
def timeseq(limit):
now = time.time()
while now <= limit:
yield math.ceil(limit - now)
now = time.time()
if __name__ == '__main__':
sys.stdout = sys.stderr
if len(sys.argv) == 1:
print 'usage: %s MM:SS' % sys.argv[0]
else:
m, s = map(int, sys.argv[1].split(':'))
for t in timeseq(time.time() + m * 60 + s):
print '%s\r' % time.strftime('%M:%S', time.gmtime(t)),
time.sleep(.2)
print '\a'
|
Squeak Smalltalk で。
1 2 3 4 5 6 7 8 9 10 11 | | timer |
timer := [:limit |
| start remain |
start := DateAndTime now.
[(remain := DateAndTime now - start) <= limit] whileTrue: [
(limit - remain) printString displayAt: Display center.
(Delay forSeconds: 0.2) wait].
BaseSoundSystem beep].
timer value: 5 minutes + 10 seconds
|
台所に置いとくと便利かもしれません。
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 | using System;
using System.IO;
using System.Threading;
using System.Media;
static class P
{
static void Main()
{
// アラーム音は、カレントディレクトリの
// alarm.wav とする。ない場合は、ビープ音。
int limit;
Console.Write("何秒間?\n> ");
limit = int.Parse(Console.ReadLine());
Console.Clear();
Console.WriteLine("残り : " + limit + "秒");
Console.WriteLine("Enter で開始。");
TimerCallback countDown = (o) =>
{
Console.Clear();
if (limit >= 0)
Console.WriteLine("残り : " + limit-- + "秒");
};
while (Console.ReadKey(false).Key != ConsoleKey.Enter)
;
var tm = new Timer(countDown, null, 0, 1000);
Thread.Sleep(limit * 1000);
tm.Dispose();
Console.Clear();
Console.WriteLine("時間です。");
if (File.Exists("alarm.wav"))
new SoundPlayer("alarm.wav").Play();
else
Console.Beep();
}
}
|
僕が普段から実用しているものです。
PythonはPythonでもIronPythonです。
System.Windows.FromsのGUIを持ってます。
動かす際には
時間が来たときに鳴る:alarm1.wav
ボタンを押したときに鳴る:pi.wav
の2つの音声ファイルを用意して下さい。
PythonはPythonでもIronPythonです。
System.Windows.FromsのGUIを持ってます。
動かす際には
時間が来たときに鳴る:alarm1.wav
ボタンを押したときに鳴る:pi.wav
の2つの音声ファイルを用意して下さい。
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 180 181 182 183 184 185 186 187 | import sys
import clr
clr.AddReference("System")
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
from sys import argv
from System import DateTime, TimeSpan
from System.Drawing import Font, FontStyle, GraphicsUnit, Rectangle, Size
from System.Media import SoundPlayer
from System.Windows.Forms import Application, Button, CheckBox, Form, FormBorderStyle, Label, Timer
form = Form()
#コントロール、コンポーネント
label1 = Label()
button10m = Button()
button1m = Button()
button10s = Button()
button1s = Button()
buttonReset = Button()
buttonStart = Button()
checkBox1 = CheckBox()
timer1 = Timer()
#フィールド
pi = alarm1 = None
timeSpan = TimeSpan(0)
dateTime = DateTime.Now
def update():
if(timer1.Enabled):
timer1_Tick(None,None)
else:
label1.Text = timeSpan.ToString()
def soundInit():
global pi,alarm1
if(pi == None or alarm1 == None):
pi = SoundPlayer("pi.wav")
alarm1 = SoundPlayer("alarm1.wav")
def end():
soundInit()
timer1.Stop()
buttonReset_Click(None,None)
Application.DoEvents()
alarm1.PlayLooping()
#▼イベントプロシージャ
#ボタンクリック時にビープ音を鳴らす
def beepPi(sender,e):
soundInit()
alarm1.Stop()
pi.Play()
def button_Click(sender,e):
global timeSpan
timeSpan += TimeSpan(0,0,sender.Tag)
update()
def buttonReset_Click(sender,e):
global timeSpan
timeSpan = TimeSpan(0)
timer1.Stop()
update()
def buttonStart_Click(sender,e):
global dateTime
dateTime = DateTime.Now
if(timeSpan <= TimeSpan(0,0,10)):
timer1.Interval = 100
else:
timer1.Interval = 1000
timer1.Start()
timer1_Tick(None,None)
def checkBox1_CheckedChanged(sender,e):
form.TopMost = sender.Checked
def timer1_Tick(sender,e):
ts = timeSpan - (DateTime.Now - dateTime)
if(ts.Milliseconds > 0):
ts += TimeSpan(0,0,1)
if(ts <= TimeSpan(0,0,10)):
timer1.Interval = 100
label1.Text = ts.ToString().Substring(0,8)
if(ts <= TimeSpan()):
end()
def Form1_Load(sender,e):
if len(argv) >= 3:
global timeSpan
timeSpan = TimeSpan(0,int(argv[1]),int(argv[2]));
buttonStart_Click(None,None)
update()
#▲イベントプロシージャ
#フォームにコントロールを配置する
def initialize():
#▼label1
label1.Bounds = Rectangle(0,0,184,48)
label1.Text = "00:00:00"
label1.Font = Font("MS UI Gothic", 35, FontStyle.Regular, GraphicsUnit.Point, 128)
#▲label1
#▼button10m
button10m.Bounds = Rectangle(0,48,40,23)
button10m.Text = "10分"
button10m.Tag = 600
#▲button10m
#▼button1m
button1m.Bounds = Rectangle(40,48,40,23)
button1m.Text = "1分"
button1m.Tag = 60
#▲button1m
#▼button10s
button10s.Bounds = Rectangle(80,48,40,23)
button10s.Text = "10秒"
button10s.Tag = 10
#▲button10s
#▼button1s
button1s.Bounds = Rectangle(120,48,40,23)
button1s.Text = "1秒"
button1s.Tag = 1
#▲button1s
#▼buttonReset
buttonReset.Bounds = Rectangle(160,48,48,23)
buttonReset.Text = "リセット"
#▲buttonReset
#▼buttonStart
buttonStart.Bounds = Rectangle(212,48,53,23)
buttonStart.Text = "スタート"
#▲buttonStart
#▼checkBox1
checkBox1.Bounds = Rectangle(186,25,84,16)
checkBox1.Text = "TopMost"
#▲checkBox1
#▼Form1
form.Size = Size(272,93)
form.Text = "焼き弁タイマー2py"
form.FormBorderStyle = FormBorderStyle.FixedToolWindow
#▲Form1
#▼フォームへ追加
form.Controls.Add(checkBox1)
form.Controls.Add(label1)
form.Controls.Add(button10m)
form.Controls.Add(button1m)
form.Controls.Add(button10s)
form.Controls.Add(button1s)
form.Controls.Add(buttonReset)
form.Controls.Add(buttonStart)
#▲フォームへ追加
#▼イベントハンドラ登録
button10m.Click += button_Click
button1m.Click += button_Click
button10s.Click += button_Click
button1s.Click += button_Click
buttonReset.Click += buttonReset_Click
buttonStart.Click += buttonStart_Click
form.Load += Form1_Load
timer1.Tick += timer1_Tick
checkBox1.CheckedChanged += checkBox1_CheckedChanged
for ctrl in form.Controls: #フォームとラベル以外(操作対象)
if(ctrl is not form and ctrl is not label1): #のみクリックで音が出る様に
ctrl.Click += beepPi #イベント追加
#▲イベントハンドラ登録
form.SuspendLayout()
initialize()
form.ResumeLayout(False)
form.PerformLayout()
Application.Run(form)
|
特にnowとか使う必要無いと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/env python
import sys, time
def timeseq(limit):
for i in range(limit, 0, -1):
yield i
time.sleep(1)
if __name__ == '__main__':
sys.stdout = sys.stderr
if len(sys.argv) == 1:
print 'usage: %s MM:SS' % sys.argv[0]
else:
m, s = map(int, sys.argv[1].split(':'))
for t in timeseq(m * 60 + s):
print '%02d:%02d\r' % (t / 60, t % 60)
print '\a'
|
コメントありがとうございます。
sleep()のような関数は厳密に1秒寝てくれるとは限らないので、sleep()に頼ると誤差が集積していきますので、あのような書き方を致しました。
長くなってしまった……。
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 | #uselib "user32.dll"
#func MessageBeep "MessageBeep" int
#func EnableWindow "EnableWindow" int,int
#define true 1
#define false 0
goto *main
// グローバル定義
#deffunc ObjEnableAll int bEnable
EnableWindow infBtn, bEnable
foreach timer
EnableWindow infInput(0, cnt), bEnable
loop
return
#deffunc timetick int idx
timer(idx) --
if ( idx > 0 ) { // '時'ではない
if ( timer(idx) < 0 ) {
timer(idx) ++
timer(idx - 1) --
if ( timer(idx - 1) >= 0 ) {
timer(idx) = 59
} else {
timetick idx - 1
}
}
}
return
#defcfunc IsTimerLasting local bLast
bLast = false
foreach timer
if ( timer(cnt) != 0 ) { bLast = true : break }
loop
return bLast
*main
dim infInput, 2, 3
dim timer, 3 // 時、分、秒
gosub *LSetWindow
stop
*LTimerLoop
ObjEnableAll false
while ( IsTimerLasting() )
wait 100 // 1秒
timetick length(timer) - 1 // 刻む
// 内容を更新
foreach timer
objprm infInput(1, cnt), timer(cnt)
loop
wend
ObjEnableAll true
MessageBeep -1
return
*LSetWindow
width 180, 60 : title "台所時計"
objmode 2
timestr = "時", "分", "秒"
foreach timer
pos 5 + 55 * cnt, 5 : input timer(cnt), 30, 22
infInput(0, cnt) = objinfo(stat, 2), stat
pos 37 + 55 * cnt, 7 : mes timestr(cnt)
loop
pos 5, 30 : button gosub "開始", *LTimerLoop
infBtn = objinfo(stat, 2), stat
return
|
単にコマンドラインの次の行で、テキスト表示でカウントダウンするだけです。
キー操作:
- SPC: 一時停止/再開
- h、l: カーソルを左右(分・秒)に移動
- k、j: カーソル位置の値(分・秒)を1つ増減
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 | #!/bin/bash
function dsp_time() {
local t=$1
echo -ne '\r'
printf '%02.02d:%02d' $((t / 60)) $((t % 60))
echo -ne '\r'
[ "$cur_mode" = SEC ] && tput cuf 3
}
function timer_up() {
if [ "$cur_mode" = MIN ]; then
((t_end += 60))
else
((t_end += 1))
fi
}
function timer_down() {
if [ "$cur_mode" = MIN ]; then
(((t_end - SECONDS - offset >= 60) && (t_end -= 60)))
else
(((t_end - SECONDS - offset >= 1) && (t_end -= 1)))
fi
}
function key_command() {
case "$c" in
'h') cur_mode=MIN ;;
'l') cur_mode=SEC ;;
'k') timer_up ;;
'j') timer_down ;;
'') ((run_mode = run_mode == 1 ? 0 : 1)) ;;
esac
}
trap 'stty cbreak echo' EXIT
stty -cbreak -echo
tm=420 # 7 min
run_mode=1
cur_mode=MIN
offset=$SECONDS
t_end=$((offset + tm))
while ((tm > 0)); do
dsp_time $tm
read -n 1 -t 1 c && key_command "$c"
if [ $run_mode = 1 ]; then
((tm = t_end - SECONDS - offset))
else
((offset = t_end - tm - SECONDS))
fi
done
dsp_time 0
echo
echo -ne '\a'
|
1 2 | function timer { t=$1; while [ $t -gt 0 ]; do echo $t; t=`expr $t - 1`; sleep 1; clear; done; printf '\a'; }
timer 10
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import java.io.*;
public class KitchenTimer {
public static void main(String[] args) throws Exception{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String sec = buf.readLine();
long nowtime = System.currentTimeMillis();
long stoptime = nowtime + (Integer.parseInt(sec) * 1000);
while(stoptime > nowtime) {
System.out.println((stoptime - nowtime)/1000);
Thread.sleep(1000l);
nowtime = System.currentTimeMillis();
}
java.awt.Toolkit.getDefaultToolkit().beep();
}
}
|
locateで表示位置を指定。 myclsで画面をきれいに。 画面に出力させた後にこの二つの関数を呼び出してカーソルを元の位置に戻しまた出力させる。 これを繰り返して最初の入力値と現在の経過時間が等しくなったときビープ音を鳴らして終了。
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 | #include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*------------locate------------*/
int locate (int x, int y)
{
HANDLE handle;
COORD position;
handle = GetStdHandle(STD_OUTPUT_HANDLE);
position.X = (SHORT)x;
position.Y = (SHORT)y;
SetConsoleCursorPosition(handle,position);
return 0;
}
/*------------------------*/
/*------------mycls------------*/
int mycls (void)
{
int i=0;
while(i<=10)
{
printf(" ");
i++;
}
return 0;
}
/*------------------------*/
int main (void)
{
clock_t start;
int intime;
int sec;
char string[30];
locate(25,10);
printf("時間を秒単位で入力してください\n");
locate(35,11);
fgets(string,30,stdin);
locate(0,10);
mycls();
locate(0,11);
mycls();
intime=atoi(string);
start=clock();
while(1)
{
sec=clock()-start;
sec/=CLOCKS_PER_SEC;
locate(0,10);
mycls();
locate(35,10);
if (sec==intime)
{
printf("時間です.\a");
break;
}
else
{
printf("%3d",intime-sec);
}
Sleep(20);
}
return 0;
}
|
1 2 3 4 5 6 7 8 9 10 | (define (main args)
(let* ((m (string->number (cadr args)))
(s (if (null? (cddr args)) 0 (string->number (caddr args))))
(d (+ (* m 60) s))
(end (+ (sys-time) d)))
(do ((now (sys-time) (sys-time)))
((<= (- end now) 0) (display #\x07))
(receive (m s) (quotient&remainder (- end now) 60)
(format #t "~2,'0D:~2,'0D~%" m s)
(sys-sleep 1)))))
|
こんな感じでも書けますね。 あまり大きな数を指定されると 1秒を刻めなくなってしまいますが、 そのような場合は 8行目を削除してください。 なお、14行目の行末は BL(Ctrl + G) です。制御コードの一つです が、 コピー & ペーストで問題無く復元できると思います。 Windows XPで動作を確認しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @echo off
setlocal enabledelayedexpansion
if "%~1" == "" (echo usage: %~n0 SECOND) & exit /b 1
for /l %%i in (%~1,-1,1) do (
cls
set t=
for /l %%j in (1,1,%%i) do set t=!t!^|
echo !t! %%i
ping -n 2 127.0.0.1 > NUL
)
cls
echo
endlocal
|
Actorを使って書いてみました。
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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | import java.io.File
import javax.sound.sampled.{AudioFormat, AudioInputStream, AudioSystem, DataLine, SourceDataLine}
import scala.actors.{Actor, TIMEOUT}
import scala.actors.Actor.loop
import scala.swing.{Alignment, BorderPanel, Button, FlowPanel, Label, MainFrame, Menu, MenuBar, MenuItem, Panel, Separator, SimpleGUIApplication, TextField}
import scala.swing.event.{ActionEvent, ButtonClicked}
abstract class Request
case class Start(s:Actor, i:Long, r:Boolean) extends Request
case object Stop extends Request
abstract class Response
case object Timeout extends Response
class Timer extends Actor {
var a:Actor = null
var i:Long = 100
var r:Boolean = false
var e:Boolean = false
start
def reset:Unit = {
a = null
i = 100
r = false
e = false
}
def act:Unit = loop {
receiveWithin(i) {
case Start(a, i, r) => {
this.a = a
this.i = i
this.r = r
e = true
}
case Stop => reset
case TIMEOUT =>
if (e) {
a ! Timeout
if (!r) reset
}
}
}
}
class KitchenTimer extends Actor {
var s:Long = 0
var i:Long = 0
var u:(Long)=>Unit = null
var p:()=>Unit = null
var t:Timer = new Timer
var e:Boolean = false
start
def this(i:Long, u:(Long)=>Unit, p:()=>Unit) = {
this()
this.i = i
this.u = u
this.p = p
}
def reset:Unit = {
s = 0
e = false
}
def act:Unit = loop {
receive {
case Timeout =>
if (e) {
((System.currentTimeMillis - s) / 1000) match {
case l if (l < i) => u(i - l)
case _ => {
p()
reset
t ! Stop
}
}
}
case _ =>
}
}
def run:Unit = {
s = System.currentTimeMillis
e = true
t ! Start(this, 100, true)
}
def run(i:Long):Unit = {
this.i = i
run
}
def run(i:Long, u:(Long)=>Unit, p:()=>Unit):Unit = {
this.u = u
this.p = p
run(i)
}
def stop:Unit = {
reset
t ! Stop
}
}
object Beep {
val s:Int = 256000
val p:String = System.getenv("windir") + "\\Media\\Windows XP Error.wav"
def play:Unit =
try {
val a:AudioInputStream = AudioSystem.getAudioInputStream(new File(p))
val f:AudioFormat = a.getFormat
val l:SourceDataLine = AudioSystem.getLine(new DataLine.Info(classOf[SourceDataLine], f)).asInstanceOf[SourceDataLine]
var b:Array[Byte] = new Array[Byte](s)
def read:Unit = a.read(b, 0, s) match {
case r if (r >= 0) => {
l.write(b, 0, r)
read
}
case _ =>
}
l.open(f)
l.start
read
l.drain
l.close
} catch {
case e => e.printStackTrace
}
}
class KitchenTimerFrame extends MainFrame {
val t:KitchenTimer = new KitchenTimer
title = "Kitchen Timer"
menuBar = new MenuBar
val menu:Menu = new Menu("file")
val startMenu:MenuItem = new MenuItem("start")
val stopMenu:MenuItem = new MenuItem("stop")
val quitMenu:MenuItem = new MenuItem("quit")
menu.contents += startMenu
menu.contents += stopMenu
menu.contents += new Separator
menu.contents += quitMenu
menuBar.contents += menu
val time:TextField = new TextField("180")
val left:Label = new Label
val start:Button = new Button("start")
val stop:Button = new Button("stop")
contents = new BorderPanel {
import BorderPanel.Position._
layout(new FlowPanel(FlowPanel.Alignment.Left) {
val l:Label = new Label("time:")
l.preferredSize = (30, 20)
l.horizontalAlignment = Alignment.Left
time.preferredSize = (50, 20)
contents += l
contents += time
}
) = North
layout(new FlowPanel(FlowPanel.Alignment.Left) {
val l:Label = new Label("left:")
l.preferredSize = (30, 20)
l.horizontalAlignment = Alignment.Left
left.preferredSize = (50, 20)
left.horizontalAlignment = Alignment.Left
contents += l
contents += left
}
) = Center
layout(new FlowPanel(FlowPanel.Alignment.Right) {
contents += start
contents += stop
}
) = South
}
listenTo(startMenu, stopMenu, quitMenu, start, stop)
reactions += {
case ActionEvent(`startMenu`) | ButtonClicked(`start`) => startHandler
case ActionEvent(`stopMenu`) | ButtonClicked(`stop`) => stopHandler
case ActionEvent(`quitMenu`) => quitHandler
}
peer.setResizable(false)
pack
def resetInfo:Unit = left.text = time.text
def startHandler:Unit = {
resetInfo
t.run(time.text.toLong, updateHandler _, timeoutHandler _)
}
def stopHandler:Unit = {
resetInfo
t.stop
}
def updateHandler(l:Long):Unit = left.text = l.toString
def timeoutHandler:Unit = {
resetInfo
Beep.play
}
def quitHandler:Unit = System.exit(1)
}
object KitchenTimerApplication extends SimpleGUIApplication {
def top = new KitchenTimerFrame
}
|
sleepを使ったシンプルなものも。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | object KitchenTimer {
def main(args:Array[String]):Unit =
if (args.size != 1)
println("usage: KitchenTimer TIME")
else {
try {
val t:Long = args(0).toLong
val s:Long = System.currentTimeMillis
def loop:Unit = ((System.currentTimeMillis - s) / 1000) match {
case p if (p >= t) => java.awt.Toolkit.getDefaultToolkit.beep
case p => {
println((t - p).toString)
Thread.sleep(1000)
loop
}
}
loop
} catch {
case e:NumberFormatException => println("invlaid time format.")
case e => e.printStackTrace
}
}
}
|
GHC&Win32前提です…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | {-# OPTIONS_GHC -fglasgow-exts #-}
module Main where
import System (getArgs)
import System.Win32.Process (sleep)
import System.Win32.Types (DWORD)
foreign import stdcall "Beep" beep :: DWORD -> DWORD -> IO ()
doTimer :: Int -> IO ()
doTimer 0 = putStrLn "It's time!" >> beep 800 500
doTimer sec = do
putStrLn $ (show sec) ++ " seconds remaining"
sleep 1000 -- 1000 msec = 1 sec
doTimer (sec - 1)
main = getArgs >>= doTimer . read . head
|
GUIウィンドウ上に、測定時間の入力ボックス・残り時間の表示部・タイマーのスタートボタンを配置しています。
入力ボックスには「分:秒」または「秒」での指定が可能です。
測定可能範囲は0:01~59:59で、範囲外の時間や不正な値を入力をするとエラーアイコンが表示されます。
入力ボックスには「分:秒」または「秒」での指定が可能です。
測定可能範囲は0:01~59:59で、範囲外の時間や不正な値を入力をするとエラーアイコンが表示されます。
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 | #light
open System
open System.Windows.Forms
open System.Drawing
let label1 = new Label(Location = new Point(10, 12), AutoSize = true, Text = "測定時間")
let textBoxTime = new TextBox(Location = new Point(100, 10), Width = 50)
let label2 = new Label(Location = new Point(10, 40), AutoSize = true, Text = "残り時間")
let labelRest = new Label(Location = new Point(100, 40), AutoSize = true, Text = "")
let buttonStart = new Button(Location = new Point(10, 80), AutoSize = true, Text = "スタート")
let errorProvider = new ErrorProvider(BlinkStyle = ErrorBlinkStyle.BlinkIfDifferentError)
let timer = new Timer(Interval = 1000)
let rest = new TimeSpan() |> ref
let printRest (rest : TimeSpan) = labelRest.Text <- sprintf "%d:%02d" rest.Minutes rest.Seconds
buttonStart.Click.Add (fun _ ->
match Text.RegularExpressions.Regex.Match(textBoxTime.Text, @"^((\d+):)?(\d+)$") with
| m when not m.Success ->
errorProvider.SetError(textBoxTime, "秒 または 分:秒 で指定してください")
| m ->
let min = if m.Groups.[1].Success then int m.Groups.[2].Value else 0
match new TimeSpan(0, min, int m.Groups.[3].Value) with
| rest' when rest'.TotalSeconds = 0. ->
errorProvider.SetError(textBoxTime, "1秒以上を指定してください")
| rest' when rest'.TotalHours >= 1. ->
errorProvider.SetError(textBoxTime, "1時間未満を指定してください")
| rest' ->
errorProvider.SetError(textBoxTime, "")
printRest rest'
rest := rest'
timer.Start())
timer.Tick.Add (fun _ ->
rest := !rest - new TimeSpan(0, 0, 1)
printRest !rest
if (!rest).TotalSeconds = 0. then
timer.Stop()
Media.SystemSounds.Asterisk.Play())
let form = new Form(Text = "キッチンタイマー", Size = new Size(200, 160), AcceptButton = buttonStart)
[|(label1 :> Control); (textBoxTime :> Control); (label2 :> Control); (labelRest :> Control); (buttonStart :> Control)|]
|> form.Controls.AddRange
form.ShowDialog() |> ignore
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | (defun second->minutes (x)
(let ((minute (floor x 60)))
(list minute (- x (* minute 60)))))
(defun timer (x y)
(let ((seconder (+ (* x 60) y)))
(if (zerop seconder)
(princ (code-char 7))
(progn (format t "~A : ~A~%" (car (second->minutes seconder))
(cadr (second->minutes seconder)))
(princ (code-char 13))
(sleep 1)
(timer x (1- y))))))
|
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 | #include <iostream>
using namespace std;
class Timer
{
private:
int minute;
int second;
public:
Timer(int m,int s){
minute = m;
second = s;
}
void count_down() {
while(1) {
if (minute == 0 && second == 0) {
cout << "\a";
cout << "時間です!!" << endl;
break;
}
cout.width(2);
cout.fill('0');
cout << minute << ":";
cout.width(2);
cout.fill('0');
cout << second << endl;
if (second == 0) {
minute--;
second = 60;
}
second--;
sleep(1);
}
}
};
int main() {
int minute,second;
cout << "分を指定してください(0 ~ 60) :" ;
cin >> minute;
cout << "秒を指定してください(0 ~ 59) :" ;
cin >> second;
Timer timer(minute,second);
timer.count_down();
return 0;
}
|
cursesをつかってみました。
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 | require 'curses'
include Curses
init_screen
begin
w = Window.new(20, 100, 0, 0)
w.addstr("何秒間?\n> ")
sec = w.getstr.to_i
sec.times { |t|
w.clear
w.setpos(0, 0)
w.addstr("残り: #{sec - t} 秒")
w.refresh
sleep 1
}
beep
flash
w.clear
w.setpos(0, 0)
w.addstr("時間です (何かキーを押して終了)")
w.getch
w.close
ensure
close_screen
end
|
POSIX 系限定です。 カウントダウンは同じ行でやる様にしみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | module Kitchen where
import System.Environment (getArgs, getProgName)
import System.IO (hFlush, stdout)
import System.Posix.Unistd (sleep)
main = do args <- getArgs
pname <- getProgName
case args of
(s:_) -> timer $ read s
_ -> putStrLn ("usage: " ++ pname ++ " [sec]")
timer 0 = putStrLn "\CRremaining: 0\nFINISH!\BEL\BEL\BEL\BEL\BEL"
timer s = do putStr $ "\CRremaining: " ++ seikei s
hFlush stdout
sleep 1
timer (s-1)
seikei s = take (1+floor(logBase 10 (fromIntegral$s+1))) (show s ++ repeat ' ')
|
JavaScriptで。
タイマーが鳴るまでの時間はブラウザーのアドレスバーから以下の
ように指定します。
e.g.
file:///(パス文字列)/240.html?(秒数)
指定した時間が経過した後に鳴る音は、ダイアログがポップアップ
する時に鳴るもので勘弁してください。
Firefox 2.0.0.6, Google Chrome 1.0.154.48, Opera 9.23で動作
を確認しました。
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 | <html>
<body>
<script type="text/javascript">
Function.prototype.repeat =
function (t, o) {
var _ = this;
return setInterval(function () { _.apply(o); }, t);
};
var Timer =
function (t) {
this.id = 0;
this.time = t;
this.tick = function () {
if (!this.id) this.id = this.tick.repeat(1000, this);
document.body.innerHTML = this.time + ' second(s) remaining.';
if (this.time-- == 0) {
alert('!');
clearTimeout(this.id);
}
};
};
window.onload =
function () {
var t = parseInt(location.search.substring(1));
if (!isNaN(t)) new Timer(t).tick();
};
</script>
</body>
</html>
|
入力は秒で。 タイムアウトで味気ないbeepが出力されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #sec = val(input("input sec."));
insert str(#sec)+"\n";
#start = tickcount;
while (#sec) {
if ((#start + 1000) <= tickcount) {
#start = tickcount;
#sec = #sec - 1;
moveto 0,0;
beginsel;
golineend;
endsel;
insert str(#sec);
gofileend;
}
}
beep;
endmacro;
|
groovy 1.7で匿名内部クラス(およびその他内部クラス)がサポートされたぞ記念。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import java.util.Timer;
def now() { System.currentTimeMillis() }
def start = now()
def end = start + Integer.parseInt(args[0]) * 1000
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run(){
if (now() > end) {
println "\7"
System.exit(0)
}
println((end-now())/1000)
}
}, 0, 1000);
|
音はビープ音で
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 | #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h> /* Sleep用 */
int main(int argc, char *argv[]){
int sec, beep_cnt = 4;
clock_t old_time, new_time;
if (argc < 2) return 0;
sec = atoi(argv[1]);
old_time = clock();
while(1){
new_time = clock();
if ((new_time - old_time) / 1000 >= sec) {
printf("\r00\n時間です\n");
while(beep_cnt --) {
putchar('\a');
putchar('\r');
Sleep(1000);
}
break;
}
printf("\r%02d", sec - ((new_time - old_time) / 1000));
Sleep(100);
}
return 0;
}
|






ところてん
#8582()
Rating0/0=0.00
[ reply ]