update from Atlas

This commit is contained in:
Luciano Ramalho
2015-02-27 20:34:12 -03:00
parent 304d628066
commit 39e87de5cd
25 changed files with 2097 additions and 46 deletions

107
control/coroaverager3.py Normal file
View File

@@ -0,0 +1,107 @@
"""
A coroutine to compute a running average.
Testing ``averager`` by itself::
>>> coro_avg = averager()
>>> next(coro_avg)
>>> coro_avg.send(10)
>>> coro_avg.send(30)
>>> coro_avg.send(6.5)
>>> coro_avg.send(None)
Traceback (most recent call last):
...
StopIteration: Result(count=3, average=15.5)
Driving it with ``yield from``::
>>> def summarize(results):
... while True:
... result = yield from averager()
... results.append(result)
...
>>> results = []
>>> summary = summarize(results)
>>> next(summary)
>>> for height in data['girls;m']:
... summary.send(height)
...
>>> summary.send(None)
>>> for height in data['boys;m']:
... summary.send(height)
...
>>> summary.send(None)
>>> results == [
... Result(count=10, average=1.4279999999999997),
... Result(count=9, average=1.3888888888888888)
... ]
True
"""
# BEGIN YIELD_FROM_AVERAGER
from collections import namedtuple
Result = namedtuple('Result', 'count average')
# the subgenerator
def averager(): # <1>
total = 0.0
count = 0
average = None
while True:
term = yield # <2>
if term is None: # <3>
break
total += term
count += 1
average = total/count
return Result(count, average) # <4>
# the delegating generator
def grouper(results, key): # <5>
while True: # <6>
results[key] = yield from averager() # <7>
# the client code, a.k.a. the caller
def main(data): # <8>
results = {}
for key, values in data.items():
group = grouper(results, key) # <9>
next(group) # <10>
for value in values:
group.send(value) # <11>
group.send(None) # <12>
# print(results) # uncomment to debug
report(results)
# output report
def report(results):
for key, result in sorted(results.items()):
group, unit = key.split(';')
print('{:2} {:5} averaging {:.2f}{}'.format(
result.count, group, result.average, unit))
data = {
'girls;kg':
[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
'girls;m':
[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
'boys;kg':
[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
'boys;m':
[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}
if __name__ == '__main__':
main(data)
# END YIELD_FROM_AVERAGER

5
control/kwcombos.py Normal file
View File

@@ -0,0 +1,5 @@
from keyword import kwlist
from itertools import combinations
for combo in combinations(kwlist, 2):
print(*combo)

View File

@@ -2,25 +2,25 @@
"""
Taxi simulator
Sample run with two cars, random seed = 4. This is a valid doctest.
Sample run with two cars, random seed 10. This is a valid doctest.
>>> main(num_taxis=2, seed=10)
taxi: 0 Event(time=0, proc=0, action='leave garage')
taxi: 0 Event(time=4, proc=0, action='pick up passenger')
taxi: 1 Event(time=5, proc=1, action='leave garage')
taxi: 1 Event(time=9, proc=1, action='pick up passenger')
taxi: 0 Event(time=10, proc=0, action='drop off passenger')
taxi: 1 Event(time=10, proc=1, action='leave garage')
taxi: 1 Event(time=11, proc=1, action='pick up passenger')
taxi: 0 Event(time=14, proc=0, action='pick up passenger')
taxi: 1 Event(time=12, proc=1, action='drop off passenger')
taxi: 0 Event(time=17, proc=0, action='pick up passenger')
taxi: 1 Event(time=19, proc=1, action='pick up passenger')
taxi: 1 Event(time=21, proc=1, action='drop off passenger')
taxi: 1 Event(time=24, proc=1, action='pick up passenger')
taxi: 0 Event(time=28, proc=0, action='drop off passenger')
taxi: 1 Event(time=28, proc=1, action='drop off passenger')
taxi: 0 Event(time=32, proc=0, action='drop off passenger')
taxi: 0 Event(time=33, proc=0, action='going home')
taxi: 1 Event(time=33, proc=1, action='pick up passenger')
taxi: 1 Event(time=35, proc=1, action='drop off passenger')
taxi: 1 Event(time=38, proc=1, action='pick up passenger')
taxi: 1 Event(time=42, proc=1, action='drop off passenger')
taxi: 1 Event(time=44, proc=1, action='pick up passenger')
taxi: 1 Event(time=75, proc=1, action='drop off passenger')
taxi: 1 Event(time=76, proc=1, action='going home')
taxi: 0 Event(time=29, proc=0, action='going home')
taxi: 1 Event(time=30, proc=1, action='pick up passenger')
taxi: 1 Event(time=61, proc=1, action='drop off passenger')
taxi: 1 Event(time=62, proc=1, action='going home')
*** end of events ***
See explanation and longer sample run at the end of this module.
@@ -35,8 +35,9 @@ import argparse
DEFAULT_NUMBER_OF_TAXIS = 3
DEFAULT_END_TIME = 80
SEARCH_INTERVAL = 4
SEARCH_DURATION = 4
TRIP_DURATION = 10
DEPARTURE_INTERVAL = 5
Event = collections.namedtuple('Event', 'time proc action')
@@ -50,7 +51,7 @@ def taxi_process(ident, trips, start_time=0): # <1>
"""Yield to simulator issuing event at each state change"""
time = yield Event(start_time, ident, 'leave garage') # <2>
for i in range(trips): # <3>
prowling_ends = time + compute_delay(SEARCH_INTERVAL) # <4>
prowling_ends = time + compute_delay(SEARCH_DURATION) # <4>
time = yield Event(prowling_ends, ident, 'pick up passenger') # <5>
trip_ends = time + compute_delay(TRIP_DURATION) # <6>
@@ -107,7 +108,7 @@ def main(end_time=DEFAULT_END_TIME, num_taxis=DEFAULT_NUMBER_OF_TAXIS,
if seed is not None:
random.seed(seed) # get reproducible results
taxis = {i: taxi_process(i, (i+1)*2, i*10)
taxis = {i: taxi_process(i, (i+1)*2, i*DEPARTURE_INTERVAL)
for i in range(num_taxis)}
sim = Simulator(taxis)
sim.run(end_time)
@@ -216,40 +217,40 @@ Notes for the ``Simulator.run`` method::
sometimes).
Sample run from the command line::
Sample run from the command line, seed=24, total elapsed time=160::
# BEGIN TAXI_SAMPLE_RUN
$ clear; python3 taxi_sim.py -t 3 -s 19
$ python3 taxi_sim.py -s 24 -e 160
taxi: 0 Event(time=0, proc=0, action='leave garage')
taxi: 0 Event(time=5, proc=0, action='pick up passenger')
taxi: 1 Event(time=10, proc=1, action='leave garage')
taxi: 1 Event(time=13, proc=1, action='pick up passenger')
taxi: 2 Event(time=20, proc=2, action='leave garage')
taxi: 0 Event(time=21, proc=0, action='drop off passenger')
taxi: 1 Event(time=21, proc=1, action='drop off passenger')
taxi: 1 Event(time=23, proc=1, action='pick up passenger')
taxi: 2 Event(time=23, proc=2, action='pick up passenger')
taxi: 1 Event(time=25, proc=1, action='drop off passenger')
taxi: 1 Event(time=27, proc=1, action='pick up passenger')
taxi: 2 Event(time=27, proc=2, action='drop off passenger')
taxi: 2 Event(time=29, proc=2, action='pick up passenger')
taxi: 1 Event(time=31, proc=1, action='drop off passenger')
taxi: 2 Event(time=31, proc=2, action='drop off passenger')
taxi: 1 Event(time=33, proc=1, action='pick up passenger')
taxi: 2 Event(time=33, proc=2, action='pick up passenger')
taxi: 2 Event(time=36, proc=2, action='drop off passenger')
taxi: 2 Event(time=37, proc=2, action='pick up passenger')
taxi: 2 Event(time=40, proc=2, action='drop off passenger')
taxi: 1 Event(time=42, proc=1, action='drop off passenger')
taxi: 1 Event(time=43, proc=1, action='going home')
taxi: 0 Event(time=44, proc=0, action='pick up passenger')
taxi: 2 Event(time=44, proc=2, action='pick up passenger')
taxi: 0 Event(time=49, proc=0, action='drop off passenger')
taxi: 0 Event(time=50, proc=0, action='going home')
taxi: 2 Event(time=58, proc=2, action='drop off passenger')
taxi: 2 Event(time=65, proc=2, action='pick up passenger')
taxi: 2 Event(time=71, proc=2, action='drop off passenger')
taxi: 2 Event(time=72, proc=2, action='going home')
taxi: 1 Event(time=5, proc=1, action='leave garage')
taxi: 1 Event(time=6, proc=1, action='pick up passenger')
taxi: 2 Event(time=10, proc=2, action='leave garage')
taxi: 2 Event(time=11, proc=2, action='pick up passenger')
taxi: 2 Event(time=23, proc=2, action='drop off passenger')
taxi: 0 Event(time=24, proc=0, action='drop off passenger')
taxi: 2 Event(time=24, proc=2, action='pick up passenger')
taxi: 2 Event(time=26, proc=2, action='drop off passenger')
taxi: 0 Event(time=30, proc=0, action='pick up passenger')
taxi: 2 Event(time=31, proc=2, action='pick up passenger')
taxi: 0 Event(time=43, proc=0, action='drop off passenger')
taxi: 0 Event(time=44, proc=0, action='going home')
taxi: 2 Event(time=46, proc=2, action='drop off passenger')
taxi: 2 Event(time=49, proc=2, action='pick up passenger')
taxi: 1 Event(time=70, proc=1, action='drop off passenger')
taxi: 2 Event(time=70, proc=2, action='drop off passenger')
taxi: 2 Event(time=71, proc=2, action='pick up passenger')
taxi: 2 Event(time=79, proc=2, action='drop off passenger')
taxi: 1 Event(time=88, proc=1, action='pick up passenger')
taxi: 2 Event(time=92, proc=2, action='pick up passenger')
taxi: 2 Event(time=98, proc=2, action='drop off passenger')
taxi: 2 Event(time=99, proc=2, action='going home')
taxi: 1 Event(time=102, proc=1, action='drop off passenger')
taxi: 1 Event(time=104, proc=1, action='pick up passenger')
taxi: 1 Event(time=135, proc=1, action='drop off passenger')
taxi: 1 Event(time=136, proc=1, action='pick up passenger')
taxi: 1 Event(time=151, proc=1, action='drop off passenger')
taxi: 1 Event(time=152, proc=1, action='going home')
*** end of events ***
# END TAXI_SAMPLE_RUN

View File

@@ -0,0 +1,52 @@
# Code below is the expansion of the statement:
#
# RESULT = yield from EXPR
#
# Copied verbatim from the Formal Semantics section of
# PEP 380 -- Syntax for Delegating to a Subgenerator
#
# https://www.python.org/dev/peps/pep-0380/#formal-semantics
# BEGIN YIELD_FROM_EXPANSION
_i = iter(EXPR) # <1>
try:
_y = next(_i) # <2>
except StopIteration as _e:
_r = _e.value # <3>
else:
while 1: # <4>
try:
_s = yield _y # <5>
except GeneratorExit as _e: # <6>
try:
_m = _i.close
except AttributeError:
pass
else:
_m()
raise _e
except BaseException as _e: # <7>
_x = sys.exc_info()
try:
_m = _i.throw
except AttributeError:
raise _e
else: # <8>
try:
_y = _m(*_x)
except StopIteration as _e:
_r = _e.value
break
else: # <9>
try: # <10>
if _s is None: # <11>
_y = next(_i)
else:
_y = _i.send(_s)
except StopIteration as _e: # <12>
_r = _e.value
break
RESULT = _r # <13>
# END YIELD_FROM_EXPANSION