I'm new to python and i've become very interested in it's ability to produce fractal images. I've written a few simple ones myself, but I just discovered a script for Mandelbrot fractals... it produces beautiful, full color images at your desired resolution.... but the code is obfuscated to look like ASCII art of a Mandelbrot.... really cool, but silly if you want to read it easily. It contains functions I haven't learned yet in python, so if someone can indent the script to look like normal python script, that'd be great. The script:
_ = (
255,
lambda
V ,B,c
:c and Y(V*V+B,B, c
-1)if(abs(V)<6)else
( 2+c-4*abs(V)**-0.4)/i
) ;v, x=7200,4800;C=range(v*x
);import struct;P=struct.pack;M,\
j ='<QIIHHHH',open('M.bmp','wb').write
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
i ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9
*i-950*T **99,T*70-880*T**18+701*
T **9 ,T*i**(1-T**45*2)))(sum(
[ Y(0,(A%3/3.+X%v+(X/v+
A/3/3.-x/2)/1j)*2.5
/x -2.7,i)**2 for \
A in C
[:9]])
/9)
) )
As I said, the art is cool, but too hard to read! If someone can do this, I'd be greatly thankful.
Note: This is not meant as a definitive answer, but as an effort for a step-by-step de-obfuscation. If you can provide an additional step to make things clearer, it would be great if you could add it to this answer.
Okay, let's start by giving the code proper newlines and indentation:
_ = (255,
lambda V, B, c: c and Y(V*V + B, B, c-1) if(abs(V) < 6) else (2 + c - 4 * abs(V)**-0.4)/i)
v, x = 7200, 4800
C = range(v*x)
import struct
P=struct.pack
M, j = '<QIIHHHH', open('M.bmp','wb').write
for X in j('BM' + P(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
i, Y = _
j(
P('BBB',
*(lambda T: (T * 80 + T**9 * i - 950 * T**99, T*70 - 880* T**18 + 701* T**9, T* i**(1-T**45*2)))(
sum([Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2 for A in C[:9]]) / 9
)
)
)
A bit better, but still confusing. For example, defining P
as an alias for struct.pack
, and all those two-declarations-in-one lines. If we get rid of them, and move the lambda definition outside the loop, we get this:
import struct
i = 255
Y = lambda V, B, c: c and Y(V*V + B, B, c-1) if(abs(V) < 6) else (2 + c - 4 * abs(V)**-0.4)/i
v = 7200
x = 4800
C = range(v*x)
M = '<QIIHHHH'
color = lambda T: (T * 80 + T**9 * i - 950 * T**99, T*70 - 880* T**18 + 701 * T**9, T * i**(1-T**45*2))
f = open('M.bmp','wb')
for X in f.write('BM' + struct.pack(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
f.write(
struct.pack('BBB',
*color(sum([Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2 for A in C[:9]]) / 9))
)
Things are starting to get a bit clearer now. The loop is writing color values for each pixel, and the lambda returns a 3-tuple, representing the blue, green and red values of each pixel.
import struct
i = 255
Y = lambda V, B, c: c and Y(V*V + B, B, c-1) if abs(V) < 6 else (
(2 + c - 4 * abs(V)**-0.4)/i)
v = 7200
x = 4800
C = range(v*x)
M = '<QIIHHHH'
color = lambda T: (T * 80 + T**9 * i - 950 * T**99,
T*70 - 880* T**18 + 701 * T**9,
T * i**(1-T**45*2))
f = open('M.bmp', 'wb')
for X in f.write('BM' + struct.pack(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
f.write(struct.pack('BBB',
*color(sum(
[Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2
for A in C[:9]]) / 9))
)
As per your comment, the asterisk (the star, *) unpacks a list into an argument list.
After many hours, here's the nearly 100 MB image produced of the Mandelbrot set: