Home > Software engineering >  How does this discouraging Python one-liner works?
How does this discouraging Python one-liner works?

Time:06-28

Could you please explain how it works. In particular: where do a,c,n,s,z come from? And how to convert this to regular functions and their calls?

x=10
y=5
abs( (lambda a: lambda z, c, n: a(a, z, c, n)) (lambda s, z, c, n: z if n == 0 else s(s, z*z c, c, n-1)) (0, 0.02*x 0.05j*y, 10) )

It was even longer, but I figured out the rest of it.

print('\n'.join([''.join(['*'if abs((lambda a: lambda z, c, n: a(a, z, c, n))(lambda s, z, c, n: z if n == 0 else s(s, z*z c, c, n-1))(0, 0.02*x 0.05j*y, 40)) < 2 else ' ' for x in range(-80, 20)]) for y in range(-20, 20)]))

This monster expression outputs a pseudo-graphic Mandelbrot fractal to the console.

CodePudding user response:

This function (lambda a: lambda z, c, n: a(a, z, c, n)) can be rewritten as

def apply_function_to_itself(funk):
    def inner(arg1, arg2, arg3):
        funk(funk, arg1, arg2, arg3)
        
    return inner

This is a functional thing that calls a function with itself as the first argument. This is necessary for recursion in functional languages but in python there is usually a better way.

This function (lambda s, z, c, n: z if n == 0 else s(s, z*z c, c, n-1)) can be rewritten as this:

def transform_n_times(funk, value, c, n):
    if n==0:
        return arg1
    else:
        return funk(funk, value * value   constant, constant, n-1)

We know from the previous function that funk === call_if_n_is_not_0, so this is a recursive function that will apply a operation n times before stopping.

So basically combined we can rewrite it like this:

def transform_n_times(value, constant, n):
    for i in range(n):
        value arg1 * arg1   arg2
    return value

Much simpler.

Understanding the entire program

The entire code could be written like this:


def apply_function_to_itself(funk):
    def inner(arg1, arg2, arg3):
        funk(funk, arg1, arg2, arg3)
        
    return inner

def transform_n_times(funk, value, constant, n):
    if n==0:
        return arg1
    else:
        return funk(funk, value * value   constant, constant, n-1)

abs(apply_function_to_itself(call_if_n_is_not_0)(0, 0.02*x 0.05j*y, 10))

Or like this. We can get rid of the apply_function_to_itself entirely but keep the recursion like this:

def transform_n_times(value, constant, n):
    if n==0:
        return arg1
    else:
        return transform_n_times(funk, value * value   constant, constant, n-1)

abs(transform_n_times(0, 0.02*x 0.05j*y, 10))

Or we can delete the recursion entirely and just use a loop:

constant = 0.02*x 0.05j*y
value = 0
n = 10
for i in range(n):
    a1 = value * value   constant
abs(value)

The basic equation behind the mandlebrot set is f(x) = x^2 c which matches this.

  • Related