CamPUG Dojo Challenge #1

3 views
Skip to first unread message

Robin Newton

unread,
Nov 26, 2009, 6:58:49 PM11/26/09
to Cambridge and East Anglian Python Users Group
I've uploaded files for Tuesday's meeting.

In keeping with the apparent tradition of doing two-player board games
in Python Dojos, we'll be doing Nine Men's Morris. The zip file I've
uploaded includes a description of the challenge, a rather skimpy set
of tests, and an even skimpier implementation. (The tests currently
pass, but only because they're rigged.)

There are variants of Nine Men's Morris. Depending on how we get on,
we may want to address this. However, the description I've uploaded
does include rules that - for the purpose of the challenge - we will
treat as being the canonical ones.

Apart from looking at the rules of Nine Men's Morris itself, I'm
guessing that it would be best to avoid thinking about the problem too
much prior to the meeting.

See you Tuesday.

Robin

mChicago

unread,
Dec 2, 2009, 6:38:21 AM12/2/09
to Cambridge and East Anglian Python Users Group
Hello everyone,

> In keeping with the apparent tradition of doing two-player board games
> in Python Dojos, we'll be doing Nine Men's Morris. The zip file I've
> uploaded includes a description of the challenge, a rather skimpy set
> of tests, and an even skimpier implementation. (The tests currently
> pass, but only because they're rigged.)

So last night was the first time I attended campug and the code dojo
was a really good experience - I work in quite a small company (I'm
actually just swapping jobs and will be writing Python full time come
the new year) and you can kind of get used to writing code and only
getting input and experience from a smallish group of people, so it
was really interesting to see both the different styles of tackling
the problem.

I think perhaps Nine Mens Morris might have been a little too big and
difficult for the timescale - some things, like the board layout etc
just meant that certain tasks where difficult to fit into the
timescale, and maybe something simpler like Tic Tac Toe might have
been faster to get "useful meaningful method" written in your time
slot.

As for the timeslot themselves, a five minute one was great if you,
(like me) arn't really proud of their python abilities, but it was a
little short for people actually writing a method, and debugging any
daft bugs in it.

I kind of feel that if perhaps more methods had been defined (but not
coded) at the start, and had simpler test cases for each one of them,
then a less experienced programmer could come up, and not have to
debug someone elses code but just start on filling out one of the easy
ones - __str__ for example. I would have been really interested to see
the __repr__ method filled out (I hadn't even heard of it before last
night!)

I can only apologize for all my noob questions, and thank you all for
being patient and giving me answers - there are a lot of things that
seem to be "quite wrong" when you compare whats "ok" in python to
whats "ok" in other languages (just simple stuff like, is it ok to
throw an exception in a constructor - C++ Noooo, python (and most
other modern languages) yea!)

It was *great* fun and a real learning experience. I don't think
there was a single 5 min slot that I didn't learn something different
about Python, coding styles, debugging and testing techniques (and not
to mention differences in views of programming in general). There was
a fantastic little discussion at the back over the pros and con's of
returning values vrs exceptions for error / 'unusual' cases which
certainly leaves food for thought.

Best Regards, and hope to see you in future
James

Ben Hutchings

unread,
Dec 2, 2009, 8:27:31 AM12/2/09
to cam...@googlegroups.com
On Wed, 2009-12-02 at 03:38 -0800, mChicago wrote:
[...]

> I can only apologize for all my noob questions, and thank you all for
> being patient and giving me answers - there are a lot of things that
> seem to be "quite wrong" when you compare whats "ok" in python to
> whats "ok" in other languages (just simple stuff like, is it ok to
> throw an exception in a constructor - C++ Noooo, python (and most
> other modern languages) yea!)
[...]

There's nothing wrong with throwing an exception from a C++ constructor;
in fact it's the proper thing to do if it cannot satisfy the type
invariant. Two-phase construction is a workaround for compilers with
missing or broken exception support; any coding standards that recommend
it today (except perhaps for hard real-time systems) should be treated
with suspicion.

Ben.

--
Ben Hutchings
It is a miracle that curiosity survives formal education. - Albert Einstein

signature.asc

Tom Lynn

unread,
Dec 2, 2009, 1:11:34 PM12/2/09
to Cambridge and East Anglian Python Users Group
Glad you enjoyed it. I have the code we produced but unfortunately
not the Bazaar history. Joe, perhaps you could tar up that directory
and upload it to the group? Otherwise I'll upload my copy tomorrow (I
have to rush off in a minute).

I think I now understand the role of the co-pilot -- it doesn't work
that way. The co-pilot's seat is just to give them a bit of
preparation time before they jump in. If they are helpful beforehand,
that's good too, but the pair programming thing doesn't really come
into its own much on the 5m timescale (I agree that 10m worked
better).

I also felt like it was "cheating" to talk about design issues/bugs if
you weren't in the hot seats, but I think I'll be more vocal next
time, since while debugging is a useful exercise it does slow things
down, and I was a willing recipient of several such observations
myself. I think with a relatively small audience there's potential
for more of that kind of discussion, and perhaps we stuck to the
script a bit too much in that regard.

At the recent PyConUK Unconference there was a similar activity where
people were working on toy problems in pairs over a slightly longer
timeframe; I'd like to give that a go at some point too.

And for the record, always use exceptions in Python unless you know
better :-)

Tom

Joe

unread,
Dec 2, 2009, 4:40:59 PM12/2/09
to Cambridge and East Anglian Python Users Group
I've uploaded a tar of the whole directory (I hope).

I thought the evening was a success and I thought the progress was
pretty good for a dojo. Most of the people there were involved and the
discussions were interesting. I thought the number of people was about
right though the 5 minute slot could have been longer. If there was
some better visibility (data projector, more than one large screen or
even putting the laptop at the far end of the table to the screen)
that would be good. There was also an interesting and vigorous
discussion in the pub afterwards about the merits (or otherwise) of
test driven development.

I look forward to the next one.

Joe

mChicago

unread,
Dec 3, 2009, 4:34:19 AM12/3/09
to Cambridge and East Anglian Python Users Group
> [...]> I can only apologize for all my noob questions, and thank you all for
> > being patient and giving me answers - there are a lot of things that
> > seem to be "quite wrong" when you compare whats "ok" in python to
> > whats "ok" in other languages (just simple stuff like, is it ok to
> > throw an exception in a constructor - C++ Noooo, python (and most
> > other modern languages) yea!)
> [...]
>
> There's nothing wrong with throwing an exception from a C++ constructor;
> in fact it's the proper thing to do if it cannot satisfy the type
> invariant. Two-phase construction is a workaround for compilers with
> missing or broken exception support; any coding standards that recommend
> it today (except perhaps for hard real-time systems) should be treated
> with suspicion.


Let me rephrase and check that its ok in Python then:

Constructors can't return any value, so if something does go wrong
then they should instead throw exceptions.
The problem in C++ / other low level programming is that in the
constructor, you allocate some memory, throw the exception, the system
won't call the deconstructor and boom, memory leaking. So as long as
you clean up *before* throwing exception, then everythings cool. (And
of course there are further problems in various languages where
extending a class means that your new class's constructor should also
throw the same exception and not where some languages try, to catch
and ignore). I think a lot of people say you shouldn't throw
exceptions in constructors (and I think thats the advice in Code
Complete) and to use a initaliser instead because it just means
minion^W junior programmers who arn't as good programers cant cause
too many problems.

But Python seems ok in that regards, because I dont use malloc or
anything daft I dont need to worry about memory leaking in [in this
instance].

On a slightly different aspect:

The main thing that is going to catch me out is the move from a
strongly typed language to a weakly typed language and method
declarations: i.e. when I declare a method that has an integer being
passed, I am very used to knowing that its always an integer being
passed, but in Python it could be anything - so when writing methods.

Is it usual to check the value types are the right thing (i.e. like int
(val)) or is it usually a case of just write it and it will throw its
own exceptions and trust in the person calling your method having read
your docstring where you said it was an int to figure it out? Are
there quick shortcuts to checking input vars? [obviously there are
cases where you would definitely want to check if the particular
function was doing something mission critical]

James

David Reynolds

unread,
Dec 3, 2009, 4:57:44 AM12/3/09
to cam...@googlegroups.com
Thanks for that Joe. I have added the files to github (with the bzr history intact) in case anyone would like to get them from there:

http://github.com/dreynolds/campug-dojo

Like James, this was also the first time I attended and I very much enjoyed the code dojo format. While we could have had longer than 5 minute slots or had predefined tasks per slot, I think there was some merit in the organisational choices that were made, in as much as we were all able to have a go at both roles and work with a bunch of different people. I certainly found it interesting seeing how other people attacked a problem and the conversations that went on around the room were also valuable. I believe a certain amount of help from the rest of the group who aren't in the "hot seats" is great as it keeps more of the room focused on the task at hand, and means that if the pilot/co-pilot are stuck, they can be helped along to achieve something in their slot.

I look forward to similar upcoming events.

David

PS. Tom: did you go to Anglia Polytechnic University (1999-2002) by any chance?

--
David Reynolds
da...@reynoldsfamily.org.uk





Tom Lynn

unread,
Dec 3, 2009, 3:52:45 PM12/3/09
to Cambridge and East Anglian Python Users Group
On Dec 3, 9:34 am, mChicago <jmon.mons...@googlemail.com> wrote:
> Let me rephrase and check that its ok in Python then:
>
> Constructors can't return any value, so if something does go wrong
> then they should instead throw exceptions.
> The problem in C++ / other low level programming is that in the
> constructor, you allocate some memory, throw the exception, the system
> won't call the deconstructor and boom, memory leaking. So as long as
> you clean up *before* throwing exception, then everythings cool. (And
> of course there are further problems in various languages where
> extending a class means that your new class's constructor should also
> throw the same exception and not where some languages try, to catch
> and ignore). I think a lot of people say you shouldn't throw
> exceptions in constructors (and I think thats the advice in Code
> Complete) and to use a initaliser instead because it just means
> minion^W junior programmers who arn't as good programers cant cause
> too many problems.

Python deals with the memory. There are no attempts to save memory by
having "value types", all objects behave basically the same way (there
are a few primitive types, but you never seem to hit the corners of
the model in practice). C++ is a world of pain in comparison. It may
seem very elegant when it's working well, but it's not as elegant as
not having to care.

> But Python seems ok in that regards, because I dont use malloc or
> anything daft I dont need to worry about memory leaking in [in this
> instance].

True. The downside of course is that when you exhaust your n GB of
memory, your program might well die horribly when the interpreter
falls over. But you can just ignore that fact and it will never happen
in practice. The same is probably true of JVMs.

You can get memory leaks in Python. Having said that, I've never had
one that I've noticed in my five to ten years of coding Python, but I
usually write short-lived scripts and web apps.

> On a slightly different aspect:
>
> The main thing that is going to catch me out is the move from a
> strongly typed language to a weakly typed language and method
> declarations: i.e. when I declare a method that has an integer being
> passed, I am very used to knowing that its always an integer being
> passed, but in Python it could be anything - so when writing methods.

It catches you out less than you'd think.

def square(n):
return n * n

You could pass in a string, but it would fail pretty quickly. On the
other hand, wow, it works for complex numbers too, and I did no extra
work...

> Is it usual to check the value types are the right thing (i.e. like int
> (val)) or is it usually a case of just write it and it will throw its
> own exceptions and trust in the person calling your method having read
> your docstring where you said it was an int to figure it out? Are
> there quick shortcuts to checking input vars? [obviously there are
> cases where you would definitely want to check if the particular
> function was doing something mission critical]

Just let it be untyped (strictly, polymorphic) until it starts causing
problems. You could scatter type checks around willy nilly, but hardly
any of them would ever be used and they would hide the intention of
your code, make it harder to maintain. Basically, it's very difficult
to get an object of the wrong type any distance into most code before
the code tries to make it do something it can't, which usually causes
either a TypeError or an "AttributeError: 'Cat' object has no
attribute 'quack'".

This can occasionally cause problems, most commonly with string/list
confusion (keeping strings iterable in Python 3 was a bit
contentious), but they are quite rare and the productivity gain makes
it easily worth it. Google "Duck typing" if you're still interested.

In answer to your question, you check a type like this when you have
to::

if not isinstance(x, (int, basestring)):
raise TypeError("Expected int or string, got %r" % type(x))

If you want to know your types inside out, you can often compile your
code to C++ with Shedskin, which will annotate your Python source with
the types used, but treat that as an off-the-wall suggestion rather
than something anyone actually does.

Tom

Tom Lynn

unread,
Dec 3, 2009, 4:12:41 PM12/3/09
to Cambridge and East Anglian Python Users Group
On Dec 3, 9:57 am, David Reynolds <da...@reynoldsfamily.org.uk> wrote:
> On 2 Dec 2009, at 21:40, Joe wrote:
>
> > [...] If there was some better visibility (data projector, more than
> > one large screen or even putting the laptop at the far end of the
> > table to the screen) that would be good. [...]

Yes, I'll try to get a projector set up next time.

> Thanks for that Joe.  I have added the files to github (with the bzr history intact) in case anyone would like to get them from there:
>
> http://github.com/dreynolds/campug-dojo

Nice. What tool did you use?

For complete interoperability silliness, I just checked it out with
Mercurial using hg-git, which was trivially easy -- follow "The easy
way" at http://hg-git.github.com/ and add "hg clone
git://github.com/dreynolds/campug-dojo.git" once you've got it
installed.

[snip]
> I look forward to similar upcoming events.

There was suggestion in the pub afterwards of continuing where we left
off at the next non-pub meeting (February 2nd, Jan 5th will be a pub
meet). Any views?

> PS.  Tom: did you go to Anglia Polytechnic University (1999-2002) by any chance?

'fraid not.

Tom

Robin Newton

unread,
Dec 3, 2009, 5:25:52 PM12/3/09
to Cambridge and East Anglian Python Users Group
On Dec 3, 9:34 am, mChicago <jmon.mons...@googlemail.com> wrote:
> The main thing that is going to catch me out is the move from a
> strongly typed language to a weakly typed language

[Pedantic]

The correct terms for the difference between Python and C++ in this
respect is that Python is dynamically typed, and that C++ is
statically typed. The weak/strong distinction is conceptually separate
from the dynamic/static one (but they are often confused). C, and
hence C++, is weakly typed. (Pointer casting, varargs.)

> Is it usual to check the value types are the right thing (i.e. like int
> (val)) or is it usually a case of just write it and it will throw its
> own exceptions and trust in the person calling your method having read
> your docstring where you said it was an int to figure it out?

[Hopefully more helpful]

Michael Feathers did a talk (http://scna.softwarecraftsmanship.org/
media/michaelfeathers) where he discussed the notion of a type as a
set of permissible values, which need not map exactly to the type
system provided by a programming language. For example, in C++ you
might have a method which takes a float representing a probability, or
a string representing a host name - and have the expectation that the
float would be in the range 0-1, or that the string would only contain
characters valid for a host name. It would be possible to have a type
system that enforced these restrictions, but the the chances are this
won't what you are using.

That being so, I would say that it is a design decision for your
program as a whole as to what kind of data validation is makes sense
to do, and where. The issue may arise more prominently in a
dynamically typed language, but it isn't really a different kind of
problem.

Also, in your example, int(val) isn't checking that val is an integer,
it is constructing an integer instance from val. (So if val were a
string then this would be like calling atoi in C.)


Robin

David Reynolds

unread,
Dec 3, 2009, 5:46:06 PM12/3/09
to cam...@googlegroups.com

On 3 Dec 2009, at 21:12, Tom Lynn wrote:

>> Thanks for that Joe. I have added the files to github (with the bzr history intact) in case anyone would like to get them from there:
>>
>> http://github.com/dreynolds/campug-dojo
>
> Nice. What tool did you use?

Something called tailor (which I'd never heard of until I searched for it this morning, but seems quite useful). I basically just followed this:
http://somethingsimilar.com/2008/05/01/moving-from-bzr-to-git-or-tailor-is-so-awesome-i-cream-my-pants/

> For complete interoperability silliness, I just checked it out with
> Mercurial using hg-git, which was trivially easy -- follow "The easy
> way" at http://hg-git.github.com/ and add "hg clone
> git://github.com/dreynolds/campug-dojo.git" once you've got it
> installed.

Heh, anyone care to import into SVN? ;)

> [snip]
>> I look forward to similar upcoming events.
>
> There was suggestion in the pub afterwards of continuing where we left
> off at the next non-pub meeting (February 2nd, Jan 5th will be a pub
> meet). Any views?

Sounds like a plan. We might get a better start, since we'll all be a bit more familiar with the rules of NMM by then!


>> PS. Tom: did you go to Anglia Polytechnic University (1999-2002) by any chance?
>
> 'fraid not.

Damn. You are the spitting image of a guy who was on my course!

--
David Reynolds
da...@reynoldsfamily.org.uk





Robin Newton

unread,
Dec 3, 2009, 6:26:25 PM12/3/09
to Cambridge and East Anglian Python Users Group
The dojo was a learning thing at a number of different levels. I think
we're going to have to experiment a bit and see how things pan out.
Here are my thoughts so far.

1. I wrote some starting point code with tests that all passed, but
dishonestly so. With hindsight, this was a bad idea - it would have
been better to have honestly failing tests. I think starting with a
larger number of smaller, failing tests would address the comments
about providing a focus for each person's go.

2. I never figured out what the co-pilot was supposed to do, partly
because role was, I think, being usurped by the entire audience. Also,
if we could find someone with real pair programming experience then
maybe they would be able to explain the dynamic.

3. I agree the the time limit for pilots made it very difficult to get
anything done. A possible alternative to simply making it longer would
be to change the way the rotation worked: have distinct pairs, and
each pair getting a continuous slot of 20 minutes (with the pilot and
co-pilot exchanging every 5 minutes). Given that the pair is supposed
to be working together anyway, this should give them a chance to build
up some momentum.

4. Disagreeing with James, I don't think the problem was too hard.
Certainly, at the level of textual board display and move adjudication
(which was as far as we got) I doubt it was significantly more
difficult than noughts and crosses would have been. I suspect that but
for the problem with the time slots we would have made considerably
more progress.

5. Tom suggested that we might start completely from scratch, rather
than rely on the problem setter writing an initial cut. I think having
an initial set of tests has its advantages, but I'd also like to see
how the other way works out. If all the code was written in the dojo
itself, then this should save on people having to spend part of their
go reading the existing code.

6. Echoing comments made on the evening, having a sign-up page worked
very well.

7. I'm possibly biased here, but I also think that having one person
to set the problem worked out well. I know Tom has an idea of the
challenge he'd like to set after we're done with Nine Man's Morris,
and after that maybe other people could take on that role so that we
get a real variety. (There ought to be a name for person who sets the
dojo challenge. Master of Ceremonies? Dungeon Master? OK, I'll shut up
now.)


Robin

Zeth

unread,
Dec 4, 2009, 6:41:56 AM12/4/09
to cam...@googlegroups.com
2009/12/3 Robin Newton <rne...@fastmail.fm>:
>> Is it usual to check the value types are the right thing (i.e. like int
>> (val)) or is it usually a case of just write it and it will throw its
>> own exceptions and trust in the person calling your method having read
>> your docstring where you said it was an int to figure it out?

Unless it is some program that will have real technical effects (i.e.
a pacemaker or space rocket) then just write it and allow 'consulting
adults' to do what they want with it. The problem of type checking is
that somewhat might have an int-like object that is not an 'int' but
would work fine as long as you don't stop them.

Best Wishes,
Zeth

Tony Ibbs

unread,
Dec 8, 2009, 3:06:13 PM12/8/09
to cam...@googlegroups.com
Belated thanks to Robin (and Tom) for organising the code dojo - I
enjoyed it a lot - the meeting seemed to be over very quickly.

I'm happy to go with any changes that seem sensible - I think the
first meeting had sensible choices, especially given it was a first
time.


On 3 Dec 2009, at 21:12, Tom Lynn wrote:

> There was suggestion in the pub afterwards of continuing where we left
> off at the next non-pub meeting (February 2nd, Jan 5th will be a pub
> meet). Any views?

Well, I'd come!

Tibs
Reply all
Reply to author
Forward
0 new messages