Showing posts with label python. Show all posts
Showing posts with label python. Show all posts
Friday, June 05, 2009
JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine
Wednesday, May 20, 2009
JavaOne Talk: Python Reversible Numbers
class PyReversible(object):
__slots__ = ['max','numReversible']
def __init__(self, max):
self.max = max
self.numReversible = self.countReversible()
def countReversible(self):
return len([i for i in xrange(11,self.max+1) if self.reversible(i)])
def allOdd(self,n):
for ch in str(n):
if int(ch) % 2 != 1:
return False
return True
def reverse(self,n):
return n + int(str(n)[::-1])
def reversible(self,n):
return self.allOdd(self.reverse(n))
JavaOne Talk: Python Word Sort
class PyWordSort(object):
def __init__(self, fileName):
print "init " + fileName
self.dataFile = open(fileName)
self.words = []
def sortedWords(self):
if len(self.words) == 0:
for line in self.dataFile:
for word in line.split():
self.words.append(word)
self.words.sort(lambda w,w1: cmp(w.lower(), w1.lower()))
return self.words
Saturday, May 09, 2009
JavaOne Talk: Python Prime Sieve
from math import log
import sys
class PyPrimes(object):
__slots__ = ['cnt','primes','size']
def __init__(self,n):
self.primes = n*[0]
self.cnt = 0
self.size = n
i = 2
max = self.calcSize()
nums = max*[True]
while i < max and self.cnt < self.size:
p = i
if nums[i]:
self.primes[self.cnt] = p
self.cnt += 1
for j in xrange(p, max/p):
nums[p*j] = False
i+= 1
def calcSize(self):
max = 2
while max/log(max) < self.size:
max = max *2 # this makes the sieve too big, but fast
return max
def last(self):
return self.primes[self.cnt - 1]
Tuesday, December 16, 2008
Is Scala too hard or are you just stupid?
Since I am going to make a statement of fact based entirely on my own experiences, maybe a little background would be relevant. I started programming 27 years ago when I was 7 years old. I programmed in BASIC, first on an Apple II at school and then on my very own Commodore 64. My first "real programming" was in Pascal when taking Advanced Placement Computer Science in high school. I probably still think in Pascal and translate everything into it first. I also learned FORTRAN and C while in high school.
In college, I learned a lot more C. For awhile I double-majored in math and computer science. Then I took the CS 10, the weed-out course for CS majors. For all of our programs in that class, we started with a predicate calculus definition of the problem, and then we had to logically derive the solution. We had a tool (I think the prof or somebody else in the department wrote) that we transform the problem statement to a computer program. But not just any program, a Lisp program. I hated everything about this, including Lisp. That class successfully weeded me out, and stuck to math.
In college I also learned Perl (for an economics class) and C++ (for a summer math research project.) After college, I programmed mostly in Java, with some C++, Perl, Ruby, and C# sprinkled in along the way. So in summary, I've programmed in a lot of language, but most of them are from the imperative cum OOP tree with C based syntax. I had one major experience with a functional language, and hated it so much that I change my major. So now on to my observations and emotions about Scala.
1.) Type inference sucks, but you (Java developers) gotta love it. I love having a statically typed language. I am definitely in that camp. However, I love not having to declare types very often. How often do you get to have your cake and eat it too? But this is, in my experience, the major source of pain in Scala. You are at the mercy of the cleverness of the compiler. In Java you are often at the mercy of the cleverness of the JVM, but it requires some esoteric Java (the kind that you only see in job interview problems or in books by Josh Bloch and Neal Gafter) to produce code that looks like it should compile, but will not. This is all too common in Scala. Here is an example.
// this compiles
object ItemMetaData extends Item with KeyedMetaMapper[Long, Item]{
override def dbTableName = "items"
// here is the problem line
override def fieldOrder = List(name, description, reserve, expiration)
}
class Item extends KeyedMapper[Long, Item]{
def getSingleton = ItemMetaData
def primaryKeyField = id
object id extends MappedLongIndex(this)
object reserve extends MappedInt(this)
object name extends MappedString(this, 100)
object description extends MappedText(this)
object expiration extends MappedDateTime(this)
}
// but this does not
object ItemMetaData extends Item with KeyedMetaMapper[Long, Item]{
override def dbTableName = "items"
// here is the problem line
override def fieldOrder = name :: description :: reserve :: expiration :: Nil
}
class Item extends KeyedMapper[Long, Item]{
def getSingleton = ItemMetaData
def primaryKeyField = id
object id extends MappedLongIndex(this)
object reserve extends MappedInt(this)
object name extends MappedString(this, 100)
object description extends MappedText(this)
object expiration extends MappedDateTime(this)
}
The two list expressions are equivalent, and yet one compiles and the other does not. Why? Is it a flaw in the compiler? Is it bad syntax? Is it a flaw in the language implementation (i.e. the List code and the :: code) ?
2.) Having no operators means that operators are everywhere! You can make the case that Scala's syntax is simpler than Java, C++, Ruby, or C++ for that matter. Why? Because it has no operators. There is no operator overloading, because there are no operators. The flip side of this is that it is easy to simulate operators and that everybody can do it. This is great for the wanna-be language designers in all of us, but can really suck. Why? It's like you are constantly encountering new operators. It can make Scala's syntax feel infinite is size, even though it is actually quite small and simple.
3.) Golf is built in and is known as _. Scala uses the underscore all over the place to allow for shorthand. Once you have become reasonably competent at Scala, you begin to like this. Until then, you hate it. In other words, it steepens the learning curve. It is a feature for power users, but it is prevalent. Thus you either become a power user, or you quit (insert snide comment about Guido or Cedric here.)
4.) Expressive is as expressive does. A lot of folks have thrown the term "readability" around. There are two aspects of readability. When you read code, do you know what it does? When you read code, do you know how it does it? The more expressive a language is, the easier it is for it to satisfy the first question. However, it may be harder for it to satisfy the second question. One could argue that if a language is better at both of these things than an alternative language, then you would probably rather program in that language. It is certainly easier to tell what idiomatic Scala will do than Java, for example. However, it is often harder to understand how it does it. You can substitute Python for Scala in the above two sentences and it is still true. But could you substitute Python for Java in those sentences? Probably not.
5.) Scala is not for creationists. Ok maybe that's a bad joke by an atheistic evolutionist. What I mean is that object creation can be confusing in Scala. Constructors are not obvious at first. Case classes add confusion, and then you throw in companion objects and you might start screaming "Make it stop!" Oh do I complain too much? Well in most of the other "mainstream" languages you need to learn exactly one thing to figure out object construction. Sure there may be other patterns (factories, singletons, builders, etc.) for augmenting this, but there is only "natural" way instantiate a class. In Scala you see standard stuff like val foo = new Foo("2ez") but also val foo = Foo("wtf"). The latter could be a case class, in which case the former won't compile. Or it could be a companion object, in which case both things compile.
So what is the conclusion? Well for all of my struggles, I have managed to find my way around Scala. So there, it must not be too hard. I am no smarter than any other programmer out there, so if I can learn it, they can too. Plus, my job did not even depend on it. Usually when a programmer has to learn a language, their job depends on it. A motivated programmer can definitely learn Scala is no time!
Labels:
functional programming,
java,
programming,
python,
scala
Thursday, July 31, 2008
Jython, It ain't no JRuby
Maybe that was the first problem, unrealistic expectations. Let's not jump into the shortcomings, just yet. First off, Jython installation is nice. Well nice as in "there is a gui." The installer only seemed to copy files into the installation directory, nothing more. That is fine, but makes me wonder I bothered with an installer at all. I at least expected into put the jython executable on my path, but it did not. No big deal.
Running a script is painless. It was odd to see a lot of activity the first time I ran a script, but the messaging (or should I say logging) was good enough to give me a good idea about what was going on and it only happens once. It also seemed like Jython was going out of its way to help performance, and JRuby had caused me to expect a nice performance boost from Jython.
So I tried out a script I wrote to solve a Project Euler problem, in particular Problem #43. The performance on Python is not that great, as it takes about 58 seconds to solve on my Macbook. Here is the code. It has been slightly optimized by Gilly.
def combinations(items, n):
if n == 0:
yield []
else:
i = 0
l = len(items)
while i < l:
for combo in combinations(items[:i] + items[i+1:], n-1):
yield [items[i]] + combo
i += 1
def permutations(items):
return combinations(items, len(items))
def to_int(seq):
return reduce(lambda x,y: 10*x + y, seq, 0)
def main():
primes = [2, 3, 5, 7, 11, 13, 17]
digits = range(0, 10)
sum = 0
for p in permutations(digits):
if p[5] == 5 and p[0] != 0:
j = 0
trait = True
while trait:
if j == 7:
y = to_int(p)
sum += y
print y
break
x = 100*p[j+1] + 10*p[j+2] + p[j+3]
trait = not x % primes[j]
j += 1
print "sum = " + str(sum)
if __name__ == '__main__':
main()
Lots of brute force, with a little bit of clever use of Python features. I was ready to crank this up with Jython, but when I tried to run it, I got this error message:
Traceback (innermost last):
(no code object) at line 0
File "euler43.py", line 5
yield []
^
SyntaxError: invalid syntax
Ouch. This actually made me feel stupid. I should have noticed that the current version of Jython is numbered 2.2.1 and that this obviously corresponds to Python 2.2.1 (that is obvious, right?) I had used a Python feature that did not exist in 2.2.1. Luckily there is an alpha version of Jython that is numbered 2.5. What about 2.3 or 2.4, you say? Uhh...
Anyways, with the alpha version of Jython 2.5 used instead everything worked. However, the performance was not what I expected. The same script ran in 171 seconds! It took three times longer than CPython. Wow.
I wrote a similar algorithm in Ruby and it was horribly slow. Perhaps this is why JRuby is faster than CRuby, CRuby is just so slow. Perhaps not. The nice thing about this is that it forced me to optimize the code more. Here is the optimized Ruby code.
def calc(seq)
seq.inject(0) {|x,y| x = 10*x + y}
end
def test(seq)
primes = [2,3,5,7,11,13,17]
j = 1
trait = true
while j < 8 && trait
num = calc(seq[j,3])
trait = (num % primes[j-1] == 0)
j += 1
end
trait
end
sum = 0
digits = (0..4).to_a + (6..9).to_a
for p in digits.permutation
if p[0] != 0
x = p[0,5] + [5] + p[5,4]
trait = test(x)
if trait
y = calc(x)
sum += y
puts "found one " + y.to_s
end
end
end
print "sum= " + sum.to_s
A couple of things to note. This uses Array#permutation, a new feature of Ruby 1.8.7. This is written in C, so you would think it would be super fast. You would be wrong. The latest JRuby is 1.1.3 and does not implement all of the 1.8.7 features, including Array#permutation. So this code will not run in JRuby. It winds up being much faster than the Python code, but only because the algorithm is so much better. It only deals with 9! numbers instead of 10!. Without the modification, Ruby was so slow that I did not have the patience to let it finsh. We're talking 10+ minutes for something that only took 1 minute in Python. With the improved algorithm it took about 40s to solve the problem in Ruby. When I ported the change over to Python, it dropped Python down to around 9s. When I tried the ported code in Jython, it would not run at all... I haven't tracked down that problem yet.
Wednesday, July 30, 2008
Python Threads
Wednesday, July 23, 2008
I ♥ Slots
Sunday, July 13, 2008
Google App Engine, Python, and The Gator
First, GAE. From a developer standpoint, it is excellent. The SDK works well. It is easy to get develop, test, and deploy. I used Eclipse and PyDev, and I was very impressed with it. PyDev does a good job of providing code assist and syntax checking, something greatly appreciated by a statically typed language guy like myself.
Now once you get beyond the development phase, GAE has had some notable problems. I have been subscribed to the mailing list, and it is very active with people having problems. Personally, I had problems with urlfetch returning HTTP 503's when I could go to the same URL and get a nice little 200. This didi give me the pleasure of using GAE's logging feature to identify these errors, but there was nothing to be done about them. The 503's have since gone away, but I was just glad that this wasn't a "real" app that my job depended on.
A big part of the fun of using GAE can accredited to Python. It is a nice language. It is definitely not as elegant as Ruby or Scala. It does read nicely and has a lot of very practical sugar to it. I think it was a good choice by Google to use for GAE. I don't think they use it much for their high profile applications (I think Google Code is written in Python, but not certain.) Python is known to have better performance than Ruby, but I don't think it has nearly the popular as the other common P in LAMP (PHP.)
Labels:
aggrogator,
gae,
google app engine,
programming,
python
Tuesday, July 08, 2008
Functional Programming
Labels:
functional programming,
java,
programming,
python,
scala
Saturday, June 28, 2008
To pickle or not to pickle
Thursday, June 19, 2008
Blogging about Books
Wednesday, June 11, 2008
New Books!
Me : "I need to leave work early"
Yep, new books arrived today. Here is the new reading list:
Java Concurrency in Practice by Brian Goetz. I know, I know, I should have already read this. The S3 bulk uploader really convinced me of this.
Refactoring by Martin Fowler. I know, I know, I should have read this many years ago...
core Python. Good to have while hacking on GAE.
Don't Make Me Think by Steve Krug. Wouldn't it be great if designers understood programmers? I can't help with that, but maybe I can understand design? Probably not, but worth a try.
Friday, February 08, 2008
99 Bottles of Beer
Ok, now I am assuming that you just spent the last hour or so at that website, but you are back. If you are into Java, one of the most interesting solutions is one that eschews typical control structures (for/while/do loops) and instead uses Java's exception system to sing the song. Actually the way that I came across the site was from an email sent by one of my colleagues. He was amused by the exception based solution. I was amused, too. Obviously such code will perform exceptionally bad (pun intended.)
One of my friends was inspired to do a Python variant that used the same technique:
#! /usr/bin/env python
class BottleException(Exception):
def __init__(self, i, c):
self.cause = c
self.cnt = i
try:
a = 1/(99-i)
raise BottleException(i+1, self)
except ZeroDivisionError:
pass
def getCause(self):
return self.cause
def printStackTrace(self):
print("%d Bottle(s) of beer on the wall, %d Bottle(s) of beer" % (self.cnt, self.cnt))
print("Take one down and pass it around,")
print("%d Bottle(s) of beer on the wall" % (self.cnt - 1))
try:
self.getCause().printStackTrace()
except AttributeError:
pass
try:
raise BottleException(1, None)
except Exception, e:
e.printStackTrace()
He and I are both pure hackers when it comes to Python, so there are probably numerous improvements that can be done to that code.
Update: I submitted the Python code to the 99 Bottles of Beer site and they accepted it. You can view it here.
Friday, February 09, 2007
Python
Python includes it's own IDE, IDLE. It seems pretty nice. I'm not sure how well it would work on a large project with many Python scripts/classes. I've been using Eclipse for Java and Ruby, and using Visual Studio for C# and C++. For easy things like these assignments, Eclipse is definitely the biggest pain to use...
Thursday, February 08, 2007
Code Fest
Plus it's fun. I figured out that what would be even more fun would be to write the programs in different languages. So I picked three: C#, C++, and Ruby. I'm doing each assignment myself in those three languages, plus Java, of course. I picked these languages because I know each, but don't use them on a regular basis and they are all "relevant." I know Fortran (or I did in high school,) but what would be the point in that? I also know Perl, but I would rather do most Perl things in Ruby, and I don't know Ruby as well as I know Perl. I am still considering adding Python, a language I don't know at all.
Anyways, here's the first assignment. I am giving each assignment it's own web page, but I will link a blog entry to each. And here's the second assignment.
Subscribe to:
Posts (Atom)