||[Jan. 9th, 2009|05:12 pm]
Well, yesterday Seamus conform threw down and did another one of these problems, so I decided to give it a shot as well (without looking at his solution). I was just getting started when Alex oniugnip looked over my shoulder.
"What are you going to use to represent cards and decks?"
"I think those want to be classes."
Famous last words. A day later, I finally finished my ridiculously object-oriented solution. (And it works, too!) Seriously, you guys: I'm getting excited about Python. I started digging in hard because I'm trying to prepare for an interview, but I'm finding that I actually really, really like it. For example, the
for ... in ... construct: give it a list, and it knows you want to iterate over elements. Give it a string, and it knows you want characters. A dictionary? It knows you want keys! A frickin' filehandle? It knows you want lines in the file! See what I mean? It's smart enough to understand you! Or actually, maybe what I'm trying to say that it's smart enough to be exactly dumb enough to understand you, because anything that implements the iteration interface is fine. See? See? Isn't it cool? If this had been how I had learned about polymorphism when I was in school, it wouldn't have made me want to drive nails into my head!
It doesn't look particularly ridiculous to me.
Well, only ridiculous in that it's probably about three times as long as what was strictly needed to solve the problem (see the solutions that Seamus and Peter did). (But now I have infrastructure for doing more card-game problems, if I want to (like this one
or this one
Hmm. Now I want to go through a number of these in F#, which is my new toy. (It's a functional language being promoted by a major and practical company! It interops very smoothly with the entire .NET world! I can write NUnit tests and get useful feedback!)
Who's the major and practical company promoting Scala?
okay, maybe not. also, who calls microsoft "practical" ?
Also, Alex posits that Google Atlanta is at least giving "moral support" to Scala by employing Lex
Oh noes, throwdowns!
Now I should do this one (and/or the factors/factorials one) in Logo and Haskell‽
Logo forthcoming, now that I know what dumb mistake not to make :)
Wow. Google Code totally does not know how to highlight Haskell. (You should clearly call Ben to complain.)
Aaaand Logo version
Logo, kind of cute! Although it feels like functions aren't first-class objects in the way we expect. When you want to pass a function to (say, to filter), you pass a "template
" instead. It's some quoted code which is going to get its parameters filled in before it's eval'd. Not sure that this is beautiful. But it's probably easier to implement.
for offset in ( 3, 1 ):
Oh, that's nice! I just stole the idea for mine. Is there any particular reason why it's a tuple instead of a list?
play_step()) return a truth value is nice, too. I have to ask: can you write code this concisely the first time, or do you write a first draft and then refine it?
The tuple vs. list thing is a slight efficiency hack. (Granted, overall, my program goes for conciseness over efficiency, but still -- preferring tuples to list for things like this is habit.) Tuples in Python are immutable. With a list, Python has to assume that the list might get modified and so rebuilds it each time through the outer loop:
3 25 SETUP_LOOP 148 (to 176)
28 LOAD_CONST 1 (3)
31 LOAD_CONST 2 (1)
34 BUILD_LIST 2
Whereas, with a tuple it can just build it once and reuse it:
3 25 SETUP_LOOP 142 (to 170)
28 LOAD_CONST 5 ((3, 1))
(To view a dissassembly of the byte code for something, you can use the dis module
: e.g., import accordian
and then dis.dis( accordian )
As for writing this concisely the first time? Almost never. I'm constantly reviewing and rewriting whatever I've just written until it "feels" right. Sometimes that means refining the logic when it feels clumsier than it should. Other times its renaming variables, functions, or classes repeatedly till I find a taxonomy that I'm truly satisfied with. Left to my own devices, I'm a perfectionist.
I should also mention that I don't typically go for quite this degree of terseness for real code. For any code that I expect to be around for a while, I'll extensively comment all interfaces and I'll prioritize clarity over terseness or clever tricks.
Whereas, with a tuple it can just build it once and reuse it
Ah! Yeah, that makes sense. I was just about to ask whether it would give me an efficiency boost to do
tuple(range(a, b)) intead of just
range(a, b) if I were going to be iterating over that range. But it seems to me that ranges are already effectively immutable, because there would be no way to grab on to things to modify them, right?
To view a dissassembly of the byte code for something...
That is so awesome! Thank you!
of squished python
And if I steal your swell set intersection and pop+append idioms and use lambda a,b:a+b instead of the add operator I get 13 lines
Although really I think they should be 16 and 14 respectively because I should be importing reduce from functools but I've got 2.5 installed on my home machine for some reason
The neatest thing about for ... in ... has nothing to do with for ... in ... . It is the wisdom of range().
Also: how had I not read that entire article on classes before?
Has anyone here had any positive experiences with stack based/concatenative languages on Windows? The Forth world is sort of scattershot and Factor is taking minutes on my machine to load dependencies when I run through the tutorial...
2009-01-10 05:03 pm (UTC)
That feeling of finally having a language that isn't constantly fighting you (we still fight, but not constantly) is why I like Python.
somehow, the constant fight is what makes Haskell interesting.