[Tutor] Printing time without "if" statement

spir denis.spir at gmail.com
Mon Mar 8 10:50:21 CET 2010


On Mon, 8 Mar 2010 18:03:12 +1100
Steven D'Aprano <steve at pearwood.info> wrote:

> On Mon, 8 Mar 2010 03:38:49 pm Elisha Rosensweig wrote:
> > Hi,
> >
> > I have an event-based simulator written in Python (of course). It
> > takes a while to run, and I want to have messages printed every so
> > often to the screen, indicating the simulation time that has passed.
> > Currently, every event that occurs follows the following code
> > snippet:
> [...]
> > This seems stupid to me - why should I have to check each round if
> > the time has been passed? I was thinking that there might be a
> > simpler way, using threading, but I have zero experience with
> > threading, so need your help. The idea was to have a simple thread
> > that waited X time (CPU cycles, say) and then read the "current_time"
> > variable and printed it.
> >
> > Any simple (simpler?) solutions to this?
> 
> That's a brilliant idea. I think I will steal it for my own code :)
> 
> (Why didn't I think of it myself? Probably because I almost never use 
> threads...)
> 
> Anyway, here's something that should help:
> 
> 
> import time
> import threading
> 
> class Clock(threading.Thread):
>     def __init__(self, *args, **kwargs):
>         super(Clock, self).__init__(*args, **kwargs)
>         self.finished = False
>     def start(self):
>         print "Clock %s started at %s" % (self.getName(), time.ctime())
>         super(Clock, self).start()
>     def run(self):
>         while 1:
>             if self.finished:
>                 break
>             print "Clock %s still alive at %s" % (
>             self.getName(), time.ctime())
>             time.sleep(2)
>         print "Clock %s quit at %s" % (self.getName(), time.ctime())
>     def quit(self):
>         print "Clock %s asked to quit at %s" % (
>         self.getName(), time.ctime())
>         self.finished = True
> 
> def do_work():
>     clock = Clock(name="clock-1")
>     clock.start()
>     # Start processing something hard.
>     for i in xrange(8):
>         print "Processing %d..." % i
>         # Simulate real work with a sleep.
>         time.sleep(0.75)
>     clock.quit()
> 
> 
> 
> And in action:
> 
> >>> do_work()
> Clock clock-1 started at Mon Mar  8 17:40:42 2010
> Processing 0...
> Clock clock-1 still alive at Mon Mar  8 17:40:43 2010
> Processing 1...
> Processing 2...
> Clock clock-1 still alive at Mon Mar  8 17:40:45 2010
> Processing 3...
> Processing 4...
> Processing 5...
> Clock clock-1 still alive at Mon Mar  8 17:40:47 2010
> Processing 6...
> Processing 7...
> Clock clock-1 still alive at Mon Mar  8 17:40:49 2010
> Clock clock-1 asked to quit at Mon Mar  8 17:40:49 2010
> >>> Clock clock-1 quit at Mon Mar  8 17:40:51 2010
> 
> >>>
> 
> 
> There's a bit of a display artifact in the interactive interpreter, when 
> the final quit message is printed: the interpreter doesn't notice it 
> needs to redraw the prompt. But other than that, it should be fine.

Hello,

really interesting, indeed. I also have no idea about threading in python. But as timer is concerned, I would prefere something like:

import time
import whatever_to_ensure_run_in_separate_thread
class Timer(whatever_to_ensure_run_in_separate_thread):
	UNIT = 1/1000000	# µs
	def __init__(self, delay, action, cyclic=False):
		self.delay = delay
		self.action = action
		self.cyclic = cyclic
		self.goon = True
	def run(self):
		if self.cyclic:
			while self.goon:
				self.cycle()
		else:
			self.cycle
	def cycle(self):
		self.wait()
		self.action()
	def wait(self):
		delay.sleep(self.delay * self.UNIT)

Or even better, launch a signal in main thread -- which is supposed to be an event cycle. This is how things work in the field of automation:

class Timer(whatever_to_ensure_run_in_separate_thread):
	UNIT = 1/1000000	# µs
	def __init__(self, delay, signal, resetDelay=1, cyclic=False):
		self.delay = delay
		self.signal = signal
		self.resetDelay = resetDelay
		self.cyclic = cyclic
		self.goon = True
	def run(self):
		if self.cyclic:
			while self.goon:
				self.cycle()
		else:
			self.cycle
	def cycle(self):
		self.wait(self.delay)
		self.signal = True
		self.wait(self.resetDelay)
		self.signal = False
	def wait(self, delay):
		delay.sleep(delay * self.UNIT)

# main cycle:
t1 = Timer(.......)
.......
if t1_signal:
	do_t1_action

(Actually, in python, the signal may be the index of a Timer.signals boolean array, incremented with each new instance.)


Denis
-- 
________________________________

la vita e estrany

spir.wikidot.com



More information about the Tutor mailing list