Are we really this clueless about software costs?
Here's what Ohloh has to say about the cost of developing Marave
Really, Marave is maybe a month of part-time programming. How could that possible be U$S71355, or "1 Person Years"?
Is this garbage the best we have to estimate costs? If that's the case, then whenever you see something about "Open source program X would take Y years and cost Z dollars to write", cut it down by a factor of 10 or more.
Here's what Marave really costed to develop:
Ok, here's what it would have costed if I had charged for it:
I am guessing about 100 hours of my time. At my "I hope they pay me this much" rate of U$S 40/hour , that's U$S 4000, which means Ohloh is off by 1600%.
OTOH, for that much freelance work I would not charge you the full rate, I would probably end charging you more like U$S20/hour which would make Ohloh's guess over 3000% too high.
In conclusion: if you like my code (and hey, you can see it for yourself), hire me, I am incredibly cheap, or amazingly fast!
Marave 0.6 is out
Version 0.6 of Marave, my peaceful, fullscreen text editor is now available at the usual place: http://marave.googlecode.com
The aha! moment
I had a small task today in Marave. The goal was:
Fade in a widget
Set a variable
Fade in another one
It's important that things are done in that order and it's also important that the app remains interactive.
And here's the code to do that (simplified):
def fadein(thing, target=1., thendo=None): """ * thing is a QWidget * thing.proxy is a QGraphicsWidget * thendo is callable * target is the desired opacity """ thing.anim=QtCore.QPropertyAnimation(thing.proxy, "opacity") thing.anim.setDuration(200) thing.anim.setStartValue(thing.proxy.opacity()) thing.anim.setEndValue(target) thing.anim.start() thing.anim.finished.connect(thing.anim.deleteLater) if thendo: thing.anim.finished.connect(thendo)
And this is how you use it:
def later(): avar=avalue fadein(widget2) fadein(widget1, thendo=later)
Isn't that lovely? Having functions as first class objects means I can just take
later as a closure, along with
avar, which need only be defined in the local scope, and the call chain will work just as I wanted!
I think this kind of usage shows the real added value PyQt brings to the table, it's not just that python avoids the boring compiles, or that you have the awesome standard library to use, but that the language itself enables you to do things that are not practical in C++.
In C++ the only way I can think of is creating a slot that's the equivalent of later, then chaining the signals... which means that this throwaway
later becomes part of the interface of a class!
I would have to define
later somewhere else on the file, separate from its only usage (maybe even inlined in the header file).
Even then, that's not equivalent: avalue may be something that was only avalable before the first call to fadein, (for example, the time of the first fadein): I would have to create a place to store it, make it reachable by
later... and wht happens if you try to do this again while the first fadein is in progress?... it gets hairy.
Programming is like a slap in the face sometimes... you realize that things you use without even noticing are far from trivial.
So, remember young padawan: you can choose you tools. Choose wisely.