Dec 29, 2010

Star and double star operators

I bet not every Python programmer knows what unary operators * and ** do.

Here's the thing: applying * to a list or a tuple extracts all the items of it and forms a function arguments sequence.

That is,
def sum3(a, b, c):
    return a + b + c

threesome = (1, 2, 3)
print "sum of", threesome, "is", sum3(*threesome)
outputs
sum of (1, 2, 3) is 6.

While ** is used for unpacking a dictionary of named function arguments:
args = { "jumper": "fox", "jumpee": "dog" }

print "quick {jumper} jumped over the lazy {jumpee}".\
    format(**args)
naturally produces
quick fox jumped over the lazy dog.

It's easy to remember, you can think of these operators as the ones literally removing parentheses of a tuple, brackets of a list or curly braces of a dictionary.

Dec 27, 2010

Version 0.1 released!

On this great winter day, pyfuscator 0.1 has been released. For now, it will be available only in two flavours: the source code and the Windows x86 executable (built with py2exe for python 2.6). 

What's next? According to our roadmap, version 0.2 will mainly be a bugfix release with some minor improvements. It's hard to say now when it will be available (it really depends on the feedback), but we'll try to roll it out anyway somewhere in Spring 2011. 

In parallel with stabilization, we're starting on the version 0.3 which is going to deliver python 2.7 and 3.x support as well as capability of handling multifile projects.

Now go check us out on the downloads page and, yes, enjoy your holidays!

Dec 19, 2010

We ARE close to the 0.1 release

Now that all internal tests are passing successfully, we anicipate releasing pyfuscator 0.1 in one week term, right at Christmas. Stay tuned!

Nov 6, 2010

Tests stats

We have 52 unit-tests now which cover as much as 89% of the code (not counting the tests themselves). The test-to-production code ratio is 1.121 KLOC / 1.533 KLOC = 73% or a share of 42%.

I made the script for counting LOCs available here: link, enjoy!

Oct 30, 2010

boost.python

Today I have tried boost.python and was impressed with its power and simplicity. Using it, I was able to marry an utility-level C++ library with Python 2.6 in just three hours, wasting at least half of the time purily because of my Saturday's stupidity.

The only thing that worries me if I think about providing Python scripting for large-scale application is compilation time of the bindings provided by boost.python -- these templates could eat my PC alive.

Oct 25, 2010

Weird in

Just discoverd that "" in "abc" evaluates as True, which is on my opinion counter-intuitive. It's quite strange that I can't find it listed as a common Python newbies' error. Does everybody read manual then? :)

Oct 24, 2010

Development mode: relaxed

Sorry folks, due to technical complications, release 0.1 isn't gonna happen in October. More realistically, it would be November or December, definitely this year.

Sep 14, 2010

Deep copy of a list in 4 bytes

In Python, when you do assign one list variable to another, it actually assigns an extra reference to the same list object, thus making any modification to one of variables be effectively reflected by another. This is what called "a shallow copy".

Sometimes, it's not the intent and you really want to obtain two independent copies of the list object, that's what called "a deep copy". Omitting trivial iterative by-element copy, there is at least three proper ways to create a deep copy of the list object.


  1. Invoking a builtin function named copy.deepcopy() which is designed to do deep copies of anything and - duh - applicable to lists;
  2. Calling list constructor on the source object: a = list(b), which is nice, because it's clear and costs only six bytes of code;
  3. And finally, making full slice of the source object: a = b[::], which might be not as fast as approach №2, but it's only four bytes of code!

Sep 13, 2010

Multi-line strings

I've just realized that multi-line spanning string literals which give me so much pain could be collapsed to single-line literals for the sake of obfusation! Yes, replacing carriage returns with \n's will result in adding one extra  byte per line but, honestly, who cares about this novadays?

"""I hate you 
multi-line string literal guys.
Prepare to die."""

Mercurial branching guide

I have found a pretty good Mercurial branching guide, with comparison to git on Steve Losh's blog: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/.

Sep 12, 2010

A little on ternary operator

Well, what I don't like about Python, it's the ternary operator. Comparing to simplicity and elegance of C's ?:, statements like expr1 if condition else expr2 make me sick. 

There are two alternatives to it, but both of them have their drawbacks.

The first one, is so called and-or trick: condition and expr1 or expr2. It behaves exactly the same as if-else, in 99%. In remaining 1% it will drive you mad finding the bug: if expr1 evaluates to false, the result will always be expr2!

And another one is: (expr2, expr1)[condition], however it's usage implies two things: 
a) condition must be a pure boolean or an int with the value of zero or one;
b) expr2 and expr1 are evaluated always, in contrary with two previous approaches.

So far, I'll stick to standard ternary operator anyway. Maybe in the end, I'll like it.

One-liner: multiple assignment

Suppose, you have variables a, b and c and you want to apply fnuction func to each of them:
a = func(a)
b = func(b)
c = func(c)

In python, it easily can be done with this:
map(func, [a, b, c])

Sep 6, 2010

Disclaimer

Welcome to the official blog of the pyfuscator project! Here will be posted new releases announcements, yummy technical information and fresh pythonian jokes. Stay tuned.