Skip to content

Commit 916dd63

Browse files
committed
Commit Paul Ross's training examples to github
1 parent d163f9f commit 916dd63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+7349
-0
lines changed

Advanced/CoRoutine/CoRoutine.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
"""Write a co-routine that is sent words and maintains a sorted list of them.
3+
4+
This generator can be used in the following way:
5+
6+
g = keep_sorted()
7+
# Start the generator
8+
g.next()
9+
# Send stuff
10+
g.send('zzz')
11+
g.send('Hi there')
12+
# Use next to retrieve the list
13+
print 'Sorted list is {0:s}'.format(g.next())
14+
g.close()
15+
16+
Created on Sep 12, 2011
17+
18+
@author: paulross
19+
"""
20+
21+
__author__ = 'Paul Ross'
22+
__date__ = '2011-09-12'
23+
__version__ = '0.1.0'
24+
__rights__ = 'Copyright (c) 2011 Paul Ross. Copyright (c) 2015 AHL.'
25+
26+
def keep_sorted():
27+
"""A co-routine that receives words and maintains a sorted list of them.
28+
"""
29+
l = []
30+
while True:
31+
v = yield l
32+
if v is not None:
33+
# This is a simple but not very efficient way of maintaining the
34+
# sort. A more efficient way would be to use bisect to insert the
35+
# word in the place that maintains the sort
36+
l.append(v)
37+
l.sort()
38+
39+
40+
if __name__ == '__main__':
41+
g = keep_sorted()
42+
# Start the generator
43+
g.next()
44+
# Send stuff
45+
print g.send('zzz')
46+
print g.send('Hi there')
47+
print 'Sorted list is {0:s}'.format(g.next())
48+
g.close()

Advanced/CoRoutine/__init__.py

Whitespace-only changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
"""Write a co-routine that is sent words and maintains a sorted list of them.
3+
4+
This generator can be used in the following way:
5+
6+
g = keep_sorted()
7+
# Start the generator
8+
g.next()
9+
# Send stuff
10+
g.send('zzz')
11+
g.send('Hi there')
12+
# Use next to retrieve the list
13+
print 'Sorted list is {0:s}'.format(g.next())
14+
g.close()
15+
16+
Created on Sep 12, 2011
17+
18+
@author: paulross
19+
"""
20+
21+
__author__ = 'Paul Ross'
22+
__date__ = '2011-09-12'
23+
__version__ = '0.1.0'
24+
__rights__ = 'Copyright (c) 2011 Paul Ross. Copyright (c) 2015 AHL.'
25+
26+
def keep_sorted():
27+
"""A co-routine that receives words and maintains a sorted list of them.
28+
"""
29+
l = []
30+
while True:
31+
v = yield l
32+
if v is not None:
33+
# This is a simple but not very efficient way of maintaining the
34+
# sort. A more efficient way would be to use bisect to insert the
35+
# word in the place that maintains the sort
36+
l.append(v)
37+
l.sort()
38+
39+
40+
if __name__ == '__main__':
41+
g = keep_sorted()
42+
# Start the generator
43+
g.next()
44+
# Send stuff
45+
print g.send('zzz')
46+
print g.send('Hi there')
47+
print 'Sorted list is {0:s}'.format(g.next())
48+
g.close()

Advanced/CoRoutine/solution/__init__.py

Whitespace-only changes.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python
2+
"""Write a decorator that makes sure that only a particular type of exception is
3+
raised by the function.
4+
The trick here is to catch all exceptions then if any exception is raised
5+
convert it to the type of exception that we want to raise.
6+
7+
Complete the decorator raises() below.
8+
9+
Created on Sep 21, 2011
10+
11+
@author: paulross
12+
"""
13+
14+
__author__ = 'Paul Ross'
15+
__date__ = '2011-08-03'
16+
__version__ = '0.1.0'
17+
__rights__ = 'Copyright (c) 2011 Paul Ross. Copyright (c) 2015 AHL.'
18+
19+
import functools
20+
21+
def raises(exception_cls):
22+
"""Wraps a function ensuring only one type of exception is raises."""
23+
def wrap(fnIN, *args,**kwargs):
24+
@functools.wraps(fnIN)
25+
def wrap_func(*args, **kwargs):
26+
"""Wrapping function with exception translation."""
27+
# Save and delete the following line and use it in your own code
28+
fnIN(*args,**kwargs)
29+
return wrap_func
30+
return wrap
31+
32+
# Right and wrong exceptions
33+
class RightException(Exception): pass
34+
class WrongException(Exception): pass
35+
36+
37+
@raises(RightException)
38+
def functionOne():
39+
"""Documentation for functionOne, this may raise an WrongException."""
40+
raise WrongException('Raising an WrongException (originally)')
41+
42+
43+
def main():
44+
try:
45+
functionOne()
46+
except RightException as err:
47+
print('Success! caught an RightException exception: "{0:s}"'.format(str(err)))
48+
except WrongException as err:
49+
print('FAILURE! caught an WrongException exception: "{0:s}"'.format(str(err)))
50+
51+
if __name__ == '__main__':
52+
main()

Advanced/ExceptionDecorator/__init__.py

Whitespace-only changes.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python
2+
"""Write a decorator that makes sure that only a particular type of exception is
3+
raised by the function.
4+
The trick here is to catch all exceptions then if any exception is raised
5+
convert it to the type of exception that we want to raise.
6+
7+
Complete the decorator raises() below.
8+
9+
Created on Sep 21, 2011
10+
11+
@author: paulross
12+
"""
13+
14+
__author__ = 'Paul Ross'
15+
__date__ = '2011-08-03'
16+
__version__ = '0.1.0'
17+
__rights__ = 'Copyright (c) 2011 Paul Ross. Copyright (c) 2015 AHL.'
18+
19+
import functools
20+
21+
def raises(exception_cls):
22+
"""Wraps a function ensuring only one type of exception is raises."""
23+
def wrap(fnIN, *args,**kwargs):
24+
@functools.wraps(fnIN)
25+
def wrap_func(*args, **kwargs):
26+
"""Wrapping function with exception translation."""
27+
# Save and delete the following line and use it in your own code
28+
# fnIN(*args,**kwargs)
29+
try:
30+
return fnIN(*args,**kwargs)
31+
except Exception as err:
32+
raise exception_cls(str(err))
33+
return wrap_func
34+
return wrap
35+
36+
# Right and wrong exceptions
37+
class RightException(Exception): pass
38+
class WrongException(Exception): pass
39+
40+
41+
@raises(RightException)
42+
def functionOne():
43+
"""Documentation for functionOne, this may raise an WrongException."""
44+
raise WrongException('Raising an WrongException (originally)')
45+
46+
47+
def main():
48+
try:
49+
functionOne()
50+
except RightException as err:
51+
print('Success! caught an RightException exception: "{0:s}"'.format(str(err)))
52+
except WrongException as err:
53+
print('FAILURE! caught an WrongException exception: "{0:s}"'.format(str(err)))
54+
55+
if __name__ == '__main__':
56+
main()

Advanced/ExceptionDecorator/solution/__init__.py

Whitespace-only changes.

Advanced/RomeoAndJuliet/__init__.py

Whitespace-only changes.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
"""Given the text for Romeo and Juliet can you predict which actor is next to speak?
2+
3+
There is a fair amount of code here that I have prepared for you:
4+
play.py is the play text itself.
5+
result.py keeps track of how well your strategy works.
6+
parser.py reads this into Python data structures.
7+
romeo_and_juliet.py (this file) that you can modify.
8+
9+
Creating a strategy:
10+
---------------------
11+
main() will pass you a Play() object that contains the play contents. Your job
12+
is to create a result.Result() object then iterate throught the acts and scenes.
13+
For each scene, given the information that you have available pass your best
14+
guess to the result.Result() object by calling guess(actor).
15+
That will check and record whether your guess was a good one and returns the
16+
actual actor who will speak next at this stage of the scene (None at the end
17+
of the scene). You are free to use this information, but remember the scene
18+
has moved on!
19+
20+
At the end of the play return your result and it will be printed out to see
21+
how accurate you were:
22+
23+
Here is an example where we always guess 'ROMEO':
24+
25+
def strat_empty(play):
26+
ret_val = result.Result()
27+
for act in play.gen_acts():
28+
for scene in act.gen_scenes():
29+
ret_val.set_act_scene(act, scene)
30+
while True:
31+
#--------- Your code starts here ------
32+
# What are you going to choose?
33+
my_choice = 'ROMEO'
34+
#--------- Your code ends here ------
35+
actual_actor = ret_val.guess(my_choice)
36+
if actual_actor is None:
37+
break
38+
return ret_val
39+
40+
This produces the following score:
41+
42+
Empty strategy (always ROMEO):
43+
Act Scene Good Bad Accuracy
44+
1 1 16.0 79.0 16.8%
45+
1 2 11.0 18.0 37.9%
46+
1 3 0.0 29.0 0.0%
47+
1 4 13.0 15.0 46.4%
48+
1 5 10.0 44.0 18.5%
49+
2 1 1.0 9.0 10.0%
50+
2 2 26.0 29.0 47.3%
51+
2 3 9.0 10.0 47.4%
52+
2 4 27.0 65.0 29.3%
53+
2 5 0.0 19.0 0.0%
54+
2 6 2.0 7.0 22.2%
55+
3 1 11.0 49.0 18.3%
56+
3 2 0.0 23.0 0.0%
57+
3 3 16.0 22.0 42.1%
58+
3 4 0.0 8.0 0.0%
59+
3 5 7.0 61.0 10.3%
60+
4 1 0.0 33.0 0.0%
61+
4 2 0.0 18.0 0.0%
62+
4 3 0.0 5.0 0.0%
63+
4 4 0.0 11.0 0.0%
64+
4 5 0.0 48.0 0.0%
65+
5 1 8.0 7.0 53.3%
66+
5 2 0.0 8.0 0.0%
67+
5 3 6.0 59.0 9.2%
68+
163.0 676.0 19.4%
69+
70+
Hmmm 19.4 %, can you do better?
71+
72+
There is one other example here which just guesses at random with predictably
73+
poor results.
74+
75+
Maybe a strategy that guesses the last but one actor betting that the scene is
76+
ROMEO/JULIET/ROMEO/JULIET/ROMEO/JULIET/ etc. Code it up!
77+
78+
Create your strategy by copying strat_empty(), rename it and add the call from
79+
main(). Then add your strategy code where you see fit but don't alter the flow
80+
of act/scene/actor or alter the lines that create result, initialise the result
81+
for a new scene and passes your guess to the result.
82+
83+
Created on 18 Mar 2015
84+
85+
@author: paulross
86+
"""
87+
import random
88+
89+
from Exercises.RomeoAndJuliet.util import parser
90+
from Exercises.RomeoAndJuliet.util import result
91+
92+
93+
#----------------- Strategies ----------------
94+
95+
def strat_empty(play):
96+
"""You can copy and modify this strategy."""
97+
ret_val = result.Result()
98+
for act in play.gen_acts():
99+
for scene in act.gen_scenes():
100+
ret_val.set_act_scene(act, scene)
101+
while True:
102+
#--------- Your code starts here ------
103+
# What are you going to choose?
104+
my_choice = 'ROMEO'
105+
#--------- Your code ends here ------
106+
actual_actor = ret_val.guess(my_choice)
107+
if actual_actor is None:
108+
break
109+
return ret_val
110+
111+
112+
def strat_random_all(play):
113+
"""Just guess a random actor."""
114+
ret_val = result.Result()
115+
# Get all the actors, we are going to guess one randomly
116+
all_actors = play.dramatis_personae.keys()
117+
# Iterate through the acts
118+
for act in play.gen_acts():
119+
# Iterate through the scenes
120+
for scene in act.gen_scenes():
121+
# Prepare the results object for this act/scene
122+
ret_val.set_act_scene(act, scene)
123+
# Iterate through the actors in the scene
124+
while True:
125+
my_choice = random.choice(all_actors)
126+
actual_actor = ret_val.guess(my_choice)
127+
# If the actual actor is None it is the end of the scene
128+
if actual_actor is None:
129+
break
130+
return ret_val
131+
132+
133+
def main():
134+
play = parser.get_play()
135+
print 'Empty strategy (always ROMEO):'
136+
result = strat_empty(play)
137+
print result
138+
print
139+
print 'Random in play:'
140+
result = strat_random_all(play)
141+
print result
142+
print
143+
144+
if __name__ == '__main__':
145+
main()
146+
print 'Bye, bye!'

0 commit comments

Comments
 (0)