#esoteric-python

1 messages ยท Page 83 of 1

gilded orchid
#

is ast stuff on-topic for this channel?

distant wave
#

on topic enough imo

crystal mica
#

Aha!py [*map(a.__rshift__, range(len(bin(a)) - 2))]

#

Making it more exotic

#

and shorter

#

is it shorter lol

zealous widget
#

you can initialize prev with a dummy loop

gilded orchid
#

how do I execute an ast tree after I've modified it?

bitter iris
#

compile() it and then exec()/eval() it

gilded orchid
#

is it possible to use ast to replace print@"Hello" with print("Hello")?

#

my current attempt is:

import ast
tree = ast.parse(input())

class test(ast.NodeTransformer):
 def visit_BinOp(self,node):
  if node==ast.MatMult:
   return ast.call(func=node.left, args=[node.right])

exec(compile(ast.fix_missing_locations(test().visit(tree)), filename="<ast>", mode="exec"))
bitter iris
#

yes

proper vault
#

In [46]: curse(type(print), '__matmul__', lambda s,e: s(e))

In [47]: print@"Hello"
Hello
``` you can use forbiddenfruit.curse (though you have to do the same for `type(lambda:0)`
sick hound
#

that's different, you're messing with the objects at runtime

#

not a nerd is using the ast

gilded orchid
#

yeah I was trying to use ast

#

I changed it to if type(node.op)==ast.MatMult: and it still didn't work

#

nvm I got it working

#
import ast
tree = ast.parse(input())

class test(ast.NodeTransformer):
 def visit_BinOp(self,node):
  if type(node.op)==ast.MatMult:
   return ast.Call(func=node.left, args=[node.right], keywords=[])

exec(compile(ast.fix_missing_locations(test().visit(tree)), filename="<ast>", mode="exec"))
#

is it possible to make a@b@c equivelent to a(b,c) using ast?

proper vault
#

maybe you could do partial on function if it takes more args than one, until it only takes one. Then you run into trouble with variadic functions though

gilded orchid
#

actually it'd probably be better to turn it into a(b(c))

earnest wing
#

Is it possible to make a class that when called given N, returns either an instance of the class or a tuple with N distinct instances of the class?
What I mean is:

a = Thing(1) # a is an instance of Thing
a, b = Thing(2) # a and b are distinct instances of Thing
bitter iris
#

I think you can mess with __new__ and metaclasses to do that but a better way would be using classmethods. Like Thing.from_multiple(3) etc. and then initializing 3 different copies of Thing

crystal mica
#

Alternatively you can do that via __mul__

#

!e ```py
class Thing:
def mul(self, multiplier):
return tuple(Thing() for _ in range(multiplier))

a = Thing()
print(a)
b, c = Thing() * 2
print(b, c)

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

001 | <__main__.Thing object at 0x7f8832e729d0>
002 | <__main__.Thing object at 0x7f8832e09610> <__main__.Thing object at 0x7f8832e11e50>
crystal mica
#

I second isidential's idea of having a classmethods

earnest wing
#

I went with a classmethod, except I overwrote __class_getitem__() for maximum jank.
Ergo,

a = Thing[1]
a, b = Thing[2]
#

Since this is not a very serious use case, I can afford to mess with syntax a little.

#

And that's about it! My project is complete:

#

And here's this as text:

#
>>> from no_strings import BFInterpreter
>>> _,__,___ = BFInterpreter[3]
>>> _.interpret(+_[+__[___<<___<+___>>___>>___]+__<-__<-__<<__<+__<++__]<<_._<++_._<++_._._+++_._<<++_._<---_._>>_._>_._+++_._------_._>-_._>>--_._)

Source code: +[+[<<<+>>>>]+<-<-<<<+<++]<<.<++.<++..+++.<<++.<---.>>.>.+++.------.>-.>>--.
Output: Hello, World! 
formal sandal
#

I think I made a thing like that in the past ๐Ÿค”

#

But mine uses << and >> instead of < and >, so yours is superior.

#

Why are you using 3 different objects, though?

low acorn
#
l1, indices = [a >> i for i in range(len(bin(a)) - 2)], [i for i, s in enumerate(bin(a)[2:]) if s == '1']```

@crystal mica i know its yesterday's topic but the indices list u built is wrong, may be rather something like this python from math import ceil, log a = 7 print([a >> i for i in range(ceil(log(a, 2)))], [i for i in range(ceil(log(a, 2))) if (a >> i) % 2 == 0])

#

out : [7, 3, 1] []

#

your code would out : ([7, 3, 1], [0, 1, 2])

earnest wing
#

@formal sandal There's a cornercase where _>_>_[_>_] is parsed as >[>>] due to the method I used to fix comparison chains breaking things

#

The fix for the cornercase is to have a separate object for each layer of loops

cursive plover
#

And here's this as text:
@earnest wing
could you explain how that worked? Like how did those symbols even output smth, and why did they output Hello, World!

earnest wing
#

It's a brainfuck interpreter, but instead of taking source code as a string ("+-<>[],."), it takes source code as valid python expressions.

cursive plover
#

well how does that expression translate to Hello World

earnest wing
#

+_[+__[___<<___<+___>>___>>___]+__<-__<-__<<__<+__<++__]<<_._<++_._<++_._._+++_._<<++_._<---_._>>_._>_._+++_._------_._>-_._>>--_._

=>

"+[+[<<<+>>>>]+<-<-<<<+<++]<<.<++.<++..+++.<<++.<---.>>.>.+++.------.>-.>>--."

cursive plover
#

umm

snow beacon
#

It's brainfuck code.

earnest wing
#

^

cursive plover
#

i know @snow beacon but I'd like to understand it

#

But how do those symbols translate to letters

snow beacon
#

AFAIK the first parts in the brackets set up a bunch of cells to a certain amount close to the alphabet, then the rest offsets and outputs the values.

#

Every . is outputting one character.

cursive plover
#

Is there some reference for that? like how'd one even discover that?

#

I'm guessing by readig about the BFInterpreter?

snow beacon
#

Probably not.

#

There are lots of brainfuck implementations.

earnest wing
cursive plover
#

I'm like curious, the guy who wrote that code originally, how did he actually do it

snow beacon
#

It might be on Rosettacode or something.

cursive plover
#

ah

#

Rosettacode?

#

oh it's a website I just checked

#

ah that's a very good article

snow beacon
cursive plover
#

explains the Hello World code too

earnest wing
#

Since all commands for BF are valid characters in Python source code, it's possible to make an implementation like this by using a class that overrides many of the builtin methods (x.__add__(y) for x + y, etc.)

cursive plover
#

well you'll be overriding print()?

#

what else

crystal mica
#

@low acorn aha, that's a good catch!

marsh void
#

Why are you all doing this brainfuck! # coding trick exists!

cursive plover
#

@marsh void # coding tricks?

snow beacon
#

When you change the encoding of a file to a custom python decoder so that you can use whatever syntax you want.

#

You know how you can do #coding=utf8?

#

Or something similar, I don't know exactly.

#

You can define your own encoding.

marsh void
#
# coding: omg_braces
def main() {
    print('What a twist!');
}
main();``` you can make this work
distant wave
#

screaming

analog rock
#

what's the best shorthand for if x: y()

#

so far I've found x and y()

gilded orchid
#

depends on what y is I guess

analog rock
#

print(...)

gilded orchid
#

do you want to print something if a condition is true?

analog rock
#

yes

#

and nothing otherwise

gilded orchid
#

print(a*x,end='') (if x is a boolean, and a is the thing you want to print)

analog rock
#

I swear that's longer

gilded orchid
#

wait no that doesn't work

#

also yeah it's longer

analog rock
#

๐Ÿ˜„

gilded orchid
#

it's longer by 1 char I'm, pretty sure

#

x and print(a) is probably the best solution

analog rock
#

yeah

gilded orchid
#

although there might be a better one in specific edge cases

analog rock
#

e.g.?

gilded orchid
#

if you were already printing without a newline so you already has ,end=''

#

for an example

analog rock
#

ah

strong hollow
#

probably been done before but still:

class PrintDict(dict):
    def __getitem__(self, item):
        print(f"get {repr(item)}")
        return super().__getitem__(item)
    
    def __setitem__(self, item, value):
        print(f"set {repr(item)} = {repr(value)}")
        return super().__setitem__(item, value)

class PrintMeta(type):
    @classmethod
    def __prepare__(cls, name, bases, **kwds):
        return PrintDict()

class SomeClass(metaclass = PrintMeta):
    foo = "bar" # yup, this prints
    my_locals = locals() # this is actually a live copy of the namespace, observe:
    my_locals["foo"] = "baz"
    assert foo == "baz" # runs just fine
#

prints

get '__name__'
set '__module__' = '__main__'
set '__qualname__' = 'SomeClass'
set 'foo' = 'bar'
get 'locals'
set 'my_locals' = {'__module__': '__main__', '__qualname__': 'SomeClass', 'foo': 'bar'}
get 'my_locals'
set 'foo' = 'baz'
get 'foo'

for those too lazy to copy / paste

thin trout
#

That's pretty cool

analog rock
#

how about a shorthand for if not x: print(y)

#

other than x or print(y)

gilded orchid
#

actually for the previous one you could do print(*[a]*x)

#

i think

analog rock
#

prints a blank line tho

gilded orchid
#

oh yeah nvm

analog rock
#

also my x is actually a set

#

not a bool

#

is there any shorthand for x.lower()?

#

cause it's longg

thin trout
#

Nope

gilded orchid
#

not really

analog rock
#

ooof

thin trout
#

I've seen worst tbh

gilded orchid
#

although if you use it multiple times you could put it in a variable (str.lower)

analog rock
#

nope

#

only once

#

but it's a substantial chunk of my 78 chars

#

import sys is quite a few actually

gilded orchid
#

could you send your code?

analog rock
#
import sys
for i in sys.argv:{*map(chr,range(97,123))}-{*i.lower()}or print(i)
#

prints each arg if it contains every letter in the alphabet

gilded orchid
#

could you just use regular input() instead?

analog rock
#

nope

#

I don't think

#

nope I can't

gilded orchid
#
import sys
[print(i)for i in sys.argv if {*map(chr,range(97,123))}-{*i.lower()}]
#

nvm that's longer

analog rock
#

u can save 1 char with no whitespace after if

gilded orchid
#

oh yeah

#

it's still slightly longer though

analog rock
#

1 char

#

yeah

#

without the [] it would be shorter

#

but python doesn't like that

grizzled cloak
#
for i in sys.argv:{*string.ascii_letters}-{*i}or print(i)```
#

is this shorter?

analog rock
#

possibly

#

but it wouldn't work anyways

#

cause it doesn't have to contain a and A

gilded orchid
#

isn't string.ascii_letters in both cases?

analog rock
#

yes

#

he did that to get rid of the .lower()

#

but in fact that wouldn't work

gilded orchid
#

doesn't your current thing always print it

#

because of the .lower()

analog rock
#

?

gilded orchid
#

the set will always have uppercase letters in it

#

so it'll either never print or always print

analog rock
#

no cause ASCII 97-122 is just lowercase

gilded orchid
#

oh yeah nvm

#

couldn't you change it to map(chr,range(65,91)) then use .upper() instead?

#

1 char shorter

analog rock
#

aha

#

very big brain

#

thx

grizzled cloak
#

you could try the inverse:
not 2847-sum(map(ord,{*i.lower()})) will only be true if it uses all letters

analog rock
#

sadly that won't work if it has any characters like . or

#

which it does

#

it works if you filter with isalpha

#

but that's substantially longer

#

anyways I think I'd rather try to shorten it by myself now

#

thanks for the help though!

analog rock
#

shortest way to reverse digits of an int?

sick hound
#

str(i)[::-1] is pretty short

analog rock
#

trouble is I need it back as an int

sick hound
#

hmm

analog rock
#

which is longg

sick hound
#

int(str(i)[::-1])?

analog rock
#

slightly long tho

sick hound
#

i can't really think of any way to do it shorter

gilded orchid
#

yeah that's pretty optimal

#

unless you want to use python 2 with int(`i`[::-1])

zealous widget
#
from math import ceil,log

def reverse(n):
    return sum(n//10**j%10 * 10**k for j,k in enumerate(range(ceil(log(n, 10)) - 1, -1, -1)))
#

who needs strings

edgy kelp
#

people who want it short

zealous widget
#

didn't need the dummy first loop

#

now it's short

#

even shorter

#

can't do better than that

#
reverse=lambda n:sum(n//10**(d-1-j)%10*10**j for j in range(d))if(d:=ceil(log(n,10)))else 0
gilded orchid
#

challenge: golf a sorting algorithm (without using the builtin)

#

(function/program that takes an array of numbers and sorts it)

#
def g(l):
 p=0
 while p<len(l):
  if p==0 or l[p]>=l[p-1]:
   p+=1
  else:
   l[p],l[p-1]=l[p-1],l[p]
   p-=1
 return l

here's a terrible and very golfable gnome sort for example

sick hound
#

wh

#

why

#

i can do oneliner algorithm

#

wanna see

#

?

gilded orchid
#

sure

sick hound
#

wait a little bit

#
f=lambda a:(lambda b:f(a)if b!=sorted(b)else b)(__import__("random").sample(a,len(a)))
#

this is it

#

bogosort

gilded orchid
#

that uses the builtin though

#

'(without using the builtin)'

#

also bogosort isn't allowed because it's kinda cheating

#

how about: your algorithm has to be able to work with an array of 20 elements in under 10 seconds

sick hound
#

its a little bit relative

#

10 seconds

gilded orchid
#

your solution still uses sorted(b) so it's invalid

edgy kelp
#
from random import shuffle
sort = lambda array: [array.insert(i,array.pop(array.index(min(array[i:]))))for i in range(len(array))]
arr = [*range(100)]
shuffle(arr)
sort(arr)
print(arr)

Don't like all the methods but fairly short

proper vault
#
def srt(a):
 o=[]
 while a:o+=[min(a)];a.remove(min(a))
 return o
```by no means the shortest, but quite short
sick hound
#

why didnt you do it oneliner

proper vault
#

Because it would be longer

sudden osprey
#

You might be able to shorten it using .pop()

sick hound
#

yup

#

its

#

mcuh better

#
def srt(a):
 o=[]
 while a:o+=a.pop(a.index(min(a)))
 return o
proper vault
#

Need [], otherwise the += will not work

sick hound
#

correct

#

using pop makes it more pythonic and 1 byte effiecent

proper vault
#
srt = lambda a:[a.pop(a.index(min(a)))for _ in a[:]]
```turns out, oneline was the way
sudden osprey
#

Ah, clever

zealous widget
#

unfortunately remove is too many letters:

srt = lambda a:[b for _ in a[:]if a.remove(b:=min(a))or 1]
proper vault
#
srt = lambda a:[a.remove(b:=min(a))or b for _ in a[:]]
```still longer, but not as much
analog rock
#

is there any way to write numbers more concisely?

edgy kelp
#

compared to?

analog rock
#

writing them like 1800

edgy kelp
#

so you want 1800 in a more concise way?

analog rock
#

at least for relatively large numbers it would be shorter to write them as mathematical things

#

maybe not as small as 1800

edgy kelp
#

you have the mathematical notation for floats

analog rock
#

which is?

edgy kelp
#
>>> 1.8e3
1800.0
gilded orchid
#

you can write numbers greater than 999999 in hex

analog rock
#

I mean that works

edgy kelp
#

could go hex or octal for something shorter

analog rock
#

ta

vestal solstice
#

j has the coolest syntax I've seen

#

420blazeit -> 274765352357189

#

base in decimal, "b", the digits 0-9a-z

#

should be asymptotically short af

gilded orchid
#

you can do int(string,b) to convert a string from base b to decimal

vestal solstice
#

oh yeah, same thing doesn't go past 36 though

gilded orchid
#

also implementing that J base thing in ast could be cool

edgy kelp
#

you got me very confused with the j thought you meant python complex at first

gilded orchid
#

haha

edgy kelp
#

wondering how on earth that works

gilded orchid
#

I didn't even know python had complex numbers until I bruteforced all valid syntax 3 char strings

#

is there any golfing use for complex numbers?

edgy kelp
#

makes sense to include it considering python's use with data analysis

gilded orchid
#

yeah

#

do they have any use for golfing?

zealous widget
#

if you ever have a challenge that needs 2-d vectors

#

using complex numbers is often easier

gilded orchid
#

why does -1j print as (-0-1j)?

#

(it's the -0 that confuses me)

proper vault
#

It probably does -(0+1j) -> (-0-1j)

gilded orchid
#

yeah probably

#

0j prints as 0j, but -0j prints as (-0-0j)

zealous widget
#
In [64]: -0j.real
Out[64]: -0.0

In [65]: -0-0j.real
Out[65]: 0.0
gilded orchid
#

oh wow

#

I didn't realise -0.0 was a thing

#

makes sense now

edgy kelp
#

the floating point standard brings that in

#

this line looks mildly esoteric

>>> -0.*-0.
0.0
earnest wing
#

The floating point standard peaked at Float3. It allows for:

NaN
-NaN
Inf
-Inf
0.0
-0.0
1.0
-1.0

!

snow beacon
#

I presume you've seen NaN Gates and Flip-FLOPS?

#

I've got to be honest, I hate floats.

#

I was pretty interested in posits for representing numbers a while back; the standard allows a 2-bit posit that can represent {0, 1, -1, complex infinity}.

#

To be honest I can't think of any other numbers anyone could want.

earnest wing
#

@marsh void #coding is not very modular for the (very common) scenario in which one wishes to interpret stringless bf in the middle of an otherwise normal script

cursive plover
#
n = int(input())
wave = list(map(int, input().split()))
up = True
down = False

for i in range(n - 1):
    if up and wave[i] > wave[i+1]:
        wave[i], wave[i+1] = wave[i+1], wave[i]
    elif down and wave[i] < wave[i+1]:
        wave[i], wave[i+1] = wave[i+1], wave[i]
    up, down = down, up

print(wave)

How would you reduce the code to baar? I know it's essentially
(lambda n, wave, up, down : Code here) (int(input()), list(map(int, input().split())), True, False)
But like how do I get the whole for loop with the 2 conditions in baar

sick hound
#

you can remove the variables up and down and use i%2 instead

#
n = int(input())
wave = list(map(int, input().split()))

for i in range(n - 1):
    if i%2==0 and wave[i] > wave[i+1]:
        wave[i], wave[i+1] = wave[i+1], wave[i]
    elif i%2==1 and wave[i] < wave[i+1]:
        wave[i], wave[i+1] = wave[i+1], wave[i]

print(wave)```
#

since wave[i], wave[i+1] = wave[i+1], wave[i] and wave[i], wave[i+1] = wave[i+1], wave[i] are the same you can turn that if/elif into just one condition

#
n = int(input())
wave = list(map(int, input().split()))

for i in range(n - 1):
    if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1]):
        wave[i], wave[i+1] = wave[i+1], wave[i]

print(wave)```
#

now to 1-line it...

#

actually let's 1-line wave[i], wave[i+1] = wave[i+1], wave[i] first since that's the hard part

cursive plover
#

oh wow, yeah

sick hound
#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i])

#

and now...

#
(lambda n,wave:[(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])])``` i think this should work
#

wait no whoops

#
(lambda n,wave:[(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])])(int(input()),list(map(int,input().split())))```
cursive plover
#

wait can you explain how that setitem thing worked please?

sick hound
#

a[b]=c is the same as a.__setitem__(b,c)

#

__setitem__ is the dunder method that gets called when you assign an item in a list

#

technically it's not the same if you override __getattribute__ but most sane classes, including list, don't do that so yeah

#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i])

cursive plover
#

so then, (lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) translates to
((lambda x,y: (wave[i] = x, wave[i+1] = y))(wave[i+1], wave[i]) yes?

sick hound
#

yes

#

which is (wave[i] = wave[i+1], wave[i+1] = wave[i])

#

well except for the fact that both of the arguments are evaluated first so it does a proper swap instead of setting wave[i] = wave[i+1] and then wave[i+1] = wave[i+1]

cursive plover
#

well why wouldn't it work if we just did it like

#

(lambda n,wave: wave[i], wave[i+1] = wave[i], wave[i+1] for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1]))(int(input()),list(map(int,input().split())))

#

is there a reason we had to use __setitem__ or was that just for illustration?

sick hound
#

wave[i], wave[i+1] = wave[i+1], wave[i] is a statement, not an expression

#

you can't put it in a lambda

#

it's invalid syntax

#

we had to use __setitem__ because function calls are an expression, which means you can put them in a lambda

#

it's the same reason that you use the (lambda x: ...)(input()) trick instead of just (x = input(), ...)

#

the second one is invalid syntax

cursive plover
#

oh right, I didn't know that

#

also, we're not printing wave at the end though are we

sick hound
#

oh good point

#
(lambda n,wave:([(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])],print(wave)))(int(input()),list(map(int,input().split())))```
cursive plover
#

oh we're allowed to put commas like that

sick hound
#

not exactly

#

i made it a tuple

cursive plover
#

oh nice, that's a cool trick

#

so we used nested lambdas to do this

sick hound
#

i used a tuple for the __setitem__ stuff too

cursive plover
#

uhm, one sec

#

[(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])]
Why's the whole thing a list

#

like, wouldn't it be just valid to have it without the enclosing [ ] as well?
Like (lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])

sick hound
#

no

#

it's a list comprehension

cursive plover
#

uhm, yeah but well why do we need a list comprehension here

sick hound
#

to emulate the for loop

#

we can't put a normal for loop inside a lambda but we can put a list comprehension in and a list comprehension can be used as a for loop

#
>>> [print(x) for x in range(5)]
0
1
2
3
4
[None, None, None, None, None]```
#

this is the same as py for x in range(5): print(x) but it's an expression so you can put it in a lambda

#

if you remove the [ ] around it then it's not a list comprehension anymore, it's just invalid and python won't like it

cursive plover
#

oh, that makes it very clear, but one more thing, the placement of the brackets

#

lemme break the inner lambda down

sick hound
#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y))) this one?

cursive plover
#

yeah

#

the for loop is in the second part, yet we placed the brackets around the whole thing and not just the second part, what I mean is

sick hound
#
(lambda x,y:
    (
        wave.__setitem__(i,x),
        wave.__setitem__(i+1,y)
    )
)```
cursive plover
#

hm yeah

#

so the second part

#

where the loop is

#

(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])

#

shouldn't just that part be inside the list comprehension

#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))[(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])]

sick hound
#

what??

cursive plover
#

um, sorry

sick hound
#

why wouldn't (lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y))) be inside the list comprehension?

cursive plover
#

I mean, it's just the second part that has the for loop

sick hound
#

?!

#

look at the original code

#
for i in range(n - 1):
    if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1]):
        wave[i], wave[i+1] = wave[i+1], wave[i]```
#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y))) is basically wave[i], wave[i+1] =

#

which is in the for loop

cursive plover
#

it's essentially two parts right, one is

(lambda x,y:
    (
        wave.__setitem__(i,x),
        wave.__setitem__(i+1,y)
    )
)

and the second

(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])
sick hound
#

no

#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) is one thing

#

you can't separate (lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y))) from (wave[i+1],wave[i]) and have it still make sense

#

imagine if you went back to the original code and did this py wave[i], wave[i+1] = for i in range(n - 1): if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1]): wave[i+1], wave[i]

cursive plover
#

erm but isn't the general structure like so:
(lambda name_of_variables: code)(variables)

#

so here, the code is (wave.__setitem__(i,x),wave.__setitem__(i+1,y))

#

right?

sick hound
#

wait hang on a second

cursive plover
#

and the variables are x,y

#

alright

sick hound
#

ok so, yes, that proves that i'm right ._.

#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i])

#

x,y is the name_of_variables

#

(wave.__setitem__(i,x),wave.__setitem__(i+1,y)) is the code

#

wave[i+1],wave[i] is the variables

#

the general structure is (lambda name_of_variables: code)(variables), not (lambda name_of_variables: code)[(variables) for i in range(n-1)]

cursive plover
#

AH yes, so after the whole lambda expression do you have the for loop, which is why the whole thing becomes a list comprehension

sick hound
#

yes

#

(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) is wave[i], wave[i+1] = wave[i+1], wave[i]

cursive plover
#

Ah, damn, yes

sick hound
#

which is inside the for loop (which became a list comprehension)

cursive plover
#

right, now all of it makes sense

#

so the structure will always be

#

[(lambda name_of_variables: code)(variables) for i in range(n-1)]

#

right?

cloud fossil
#

i've actually used this once in my code because hey it was a lot shorter than make a function and do so

cursive plover
#

and hence, that whole thing breaks down like so:

(
lambda n,wave:( #this bracket is so we get a tuple, to fit in print()
[(lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y)))(wave[i+1],wave[i]) for i in range(n-1) if (i%2==0 and wave[i] > wave[i+1]) or (i%2==1 and wave[i] < wave[i+1])] #The inner lambda expression
,print(wave)) #the tuple ends here
) #the lambda thing ends here
(int(input()),list(map(int,input().split()))) #and these are the variables
sick hound
#

range(n-1) is only because that's what it was in the original code

#

and you're not required to have a lambda call in the list comprehension

cursive plover
#

yeah, I just copy pasted your sentence from above and didn't change it but yeah I get the idea

sick hound
#

the general structure for a list comprehension is [thing for thing in thing], and you can also have an if thing in there ([thing for thing in thing if thing])

#

and they don't all have to be the same i just couldn't be bothered to come up with more interesting placeholders

cursive plover
#

what do you mean I don't need to have the lambda call inside the comprehension? Didn't we just discuss why we needed that inside?

#

why wouldn't (lambda x,y:(wave.__setitem__(i,x),wave.__setitem__(i+1,y))) be inside the list comprehension?
here

sick hound
#

in this specific case you do need it

#

but in general, it is possible to have a list comprehension which doesn't have a lambda inside it

#

i showed you an example earlier

#
[print(x) for x in range(5)]```
#

this list comprehension isn't particularly useful because what it does is so ridiculously simple

#

but yeah, not all list comprehensions have lambdas

cursive plover
#

oh right, I read it the other way round

#

you meant that not all list comprehensions require a lambda, which is, well yeah

#

what I misread it as there could be lambda expressions which had their code inside a list comprehension but weren't called inside it

#

which well, is yes again true if I look at the outer lambda expression in the solution you wrote to my original question

sick hound
#

well technically you can do this py [(lambda x: x) for i in range(5)]

#

it's just silly

cursive plover
#

because that is basically (lambda n, wave: [code])(variables)

#

hm yeah

#

Right, I learnt a lot of things from that talk. Thanks a lot for breaking everything down into such a simple manner, that was beautiful. โค๏ธ

marsh void
#

Meanwhile if I manage to do my bytecode modifying thing, we might be able to write actually nice multi line lambdas

cursive plover
#

bytecode? you mean from advent of code?

marsh void
#

I mean bytecode

#

python source code compiles to bytecode

#

@cursive plover

sick hound
#

yep

#

the interpreter doesn't directly run the source code, it turns it into bytecode and then executes that

analog rock
#

How could this be optimized:

#
for i in range(1800,2401,4):not i%50and i%16or print(i)
#

in terms of chars, I mean

#

not speed

cursive plover
#

oh, like Java

#

Also, aoc had opcode thing not bytecode mb ๐Ÿ˜“

burnt pasture
#

yes, Python is executed just like Java, though people call Java compiled and Python interpreted

cursive plover
#
for i in range(1800,2401,4):not i%50and i%16or print(i)

how's the interpreter able to interpret it right when there's no space before and and or

analog rock
#

cause it knows an identifier can't start with a digit

burnt pasture
#

the lexical analyzer sees "5" and starts building an int. It stops when it gets to "a" because that can't be part of an int.

cursive plover
#

oh wow, that's very clever

analog rock
#

yeet

cursive plover
#

@burnt pasture also, java has this jvm that makes it portable, python doesn't have that sort of thing yeah?

analog rock
#

got it down a bit

#
for i in range(1800,2401,4):i%16>i%50<1or print(i)
burnt pasture
#

@cursive plover Python has a VM also. It's not named something like "JVM", but it's the same idea

cursive plover
#

Ah, okay

#

@analog rock what's this part doing i%16>i%50<1 ?

analog rock
#

it's a short way of saying

#
i%16!=0 and i%50==0```
#

cause I'm doing code golf

cursive plover
#

yeah I get that, I'm figuring out how they're the same

analog rock
#

cause if i%16!=0 then i%16>0

#

and we can replace the 0 with i%50

#

cause we need that to be 0

#

and then we just check if the i%50 is actually 0

cursive plover
#

by doing a <1, ah that's very nice

analog rock
#

thx lol

#

tbh it was a bit of a fluke ๐Ÿ˜„

#

would love some suggestions still tho

analog rock
#

I have recently come across a code golf technique: e.g.```py
"otnweo"[n::2]

#

In what cases is it beneficial to use this?

proper vault
#

whenever you need to decide between 2 strings of similar length based on a predicate

analog rock
#

or more than 2?

indigo sand
#

you could do something like (lambda n:[(print('zottffssenenwhoiieiireoruvxvgno ere ehe e nt '[int(i)::10])) for i in n])(input()) to print all of the digits in a number as words, or similar things for different scenarios.

proper vault
#

seldom do you a situation where the stars align so that it works

analog rock
#

for ordinal numbers it works

#

quite nicely

proper vault
#

what would be a case where you would get 0,1,2 and need print different things based on that?

analog rock
#

"tsnrhtdd"[x::4]

#

for the suffixes of ordinal numbers

vestal solstice
#

oh, maybe that's how primo did it

analog rock
#

๐Ÿคท

#

I found a relatively concise version using that method and it's still 30th

#

primo moves in mysterious ways

#

sweaty boi

vestal solstice
#

it kinda ignores my submissions, they don't get scored or saved

#

maybe it's a browser thing

#

yeah, Safari 11.1.2 is no good

frozen ice
#

anyone know if there's somewhere to discuss stackless python?

vestal solstice
#

here? makes sense to me

frozen ice
#

makes sense to me too, but not sure if anyone else around would have used it before. ๐Ÿ™‚

#

In particular, I'm having an issue with using stacklesssocket + boto3

#

and online resources seem to be rather scarce... so if any of you have some experience here, ding me in DM or hit me up in channel if you could.

analog rock
#

@vestal solstice u need to be signed into github

#

I mean u probably are?

#

idk

vestal solstice
#

yeah it works in chrome

analog rock
#

ooooof

#

yeet I'm higher than btnlq on a code golf hole

#

๐Ÿ˜ฎ

vestal solstice
#

b who

analog rock
#

that's his profile

vestal solstice
#

sick skills

analog rock
#

afaik on python he's highest apart from primo

vestal solstice
#

true

analog rock
#

primo must literally spend 90% of every day doing these lol

vestal solstice
#

lmao

analog rock
#

when u minify ur code and it's a byte longer

spare tide
#

Every time I come to this server I look at this room in awe thinking about what I would have to do to be able to post into esoteric Python.

analog rock
#

what's the shortest way to sum the digits in a string?

edgy kelp
#

can't sum strings to get the codepoint sum so I'm guessing just a simple sum with a genexp

analog rock
#

:/

#

that succs

sick hound
#

what do you mean by "digits in a string"?

analog rock
#

e.g."10293482"

#

I want 1+0+2+9etc

sick hound
#

if you int the string and then do %9 then (iirc) you get the correct result modulo nine

analog rock
#

I don't rly need modulo nine tho

#

๐Ÿ˜„

sick hound
#

but that probably isn't very useful- yeah

analog rock
#

I need modulo 2

sick hound
#

...i wonder if there's a similar trick for that

analog rock
#

I hope so

#

lemme know if u find one

#

if it helps all the digits are 1 or 0

edgy kelp
#

count the ones

sudden osprey
#

.count('1') would be quite short but i reckon somebody else can do better

#

Aah beat me๐Ÿ˜

analog rock
#

already tried that

#

but would like a shorter boi

indigo sand
#

is there a maximum length of the numbers?

analog rock
#

6

#

I mean if there's a way to do that without converting to binary in the first place

indigo sand
#

if they're 6 digit binary numbers, int()%9%2 should work and be a bit shorter than .count('1')

analog rock
#

aha

#

thx bro

#

wait wdym

#

int(number)?

#

wait nvm

#

I assume int of the bin

indigo sand
#

int of whatever string you have

sudden osprey
#

%9%6 maybe?

analog rock
#

%9%2 works

sudden osprey
#

But doesn't work with 111111

indigo sand
#

it gets 0

analog rock
#

still open to even shorter suggestions tho

#

any mathsy way to check if the number of 1s in a number's binary will be even?

indigo sand
#

this not very nice(and very long) bit of code should tell you if a number's binary will have an even number of ones:

import math
def m(n):
    return bool(sum([int(n/(2**i))%2for i in range(int(math.log2(n)))])%2)
```of course, it doesn't work for 0, but this is the most mathsy I could get it to be. I'm sure someone could make it much shorter.
sick hound
#

int(n/(2**i))%2
n//2**i%2

analog rock
#

Ahaa

#

Thanks!

sick hound
#

n//2**i%2 isn't a solution, i'm just golfing pie42's code

analog rock
#

Oh right

#

:/

sick hound
#

right now we have bool(sum([n//2**i%2for i in range(int(math.log2(n)))])%2)

#

that doesn't need to be a list comprehension bool(sum(n//2**i%2for i in range(int(math.log2(n))))%2)

#

we don't need bool() either honestly sum(n//2**i%2for i in range(int(math.log2(n))))%2

#

difficult to golf it more than that though

analog rock
#

Longer than what I have

#

I'll send the code soon

sick hound
#

iirc the current shortest way we've found is s.count('1')%2

zealous widget
#

this is basically the same as converting the number to binary and counting the ones

#

i mean pie's code, not jan's

#

there's no real shortcut besides that

analog rock
#
for i in range(51):int(f'{i:b}')%9%2or print(i)
#

that's what I got so far

old flint
#

what're some ways to replace an if __name__ == "__main__": main() with a single function call instead

#

I guess one option is to directly pass along __name__

#

is there some other hack to climb up the stack and pull out __name__?

zealous widget
#

(lambda name: (main if name == "__main__" else lambda:None)())(__name__)

old flint
#

ah, to clarify, the goal is to have an importable function that could be called

#

e.g.

from lib import run_only_if_main
run_only_if_main()
#

or more usefully

from lib import run_only_if_main
def main():
    pass
run_only_if_main(f=main)
rugged sparrow
#
run_only_if_main = lambda f:globals()['__name__'] == '__main__' and f()```
#

run_only_if_main(main)

old flint
#

right, but you'd still have to pass in __name__

rugged sparrow
#

honestly i think that would work

old flint
#

if run_only_if_main is defined in another file, it'll still pull __name__ as the imported module name

rugged sparrow
#

hmm

zealous widget
#

decorate it

rugged sparrow
#

@zealous widget __name__ is still pulled as the imported module tho

zealous widget
#

so

rugged sparrow
#

so how can the decorator check if the module it was imported into is main?

zealous widget
#

the decorator isn't imported

rugged sparrow
#

the goal is something that can be imported by itself

cursive plover
#
for i in range(51):int(f'{i:b}')%9%2or print(i)

@analog rock why do we have a %2 there?

cursive plover
#

Also, the %9 trick to get sum of digits in a number would fail if the number is a multiple of 9, no?

low acorn
#

if run_only_if_main is defined in another file, it'll still pull __name__ as the imported module name
@old flint```python
#in your lib utils
run_only_if_main = lambda f,g:g['name'] == 'main' and f()
#in the caller
from lib.utils import run_only_if_main
def main():
print("i am the main code")
run_only_if_main()(f=main,g=globals())

#

nothing magical but at least you avoid typing the annoying '__name__'

#

apparently you could make use of inspect but its dependent of the python implementaion so not suitable for production

old flint
#

yea, I guess that's what I'd be looking at

#

wondering if there's some hacky solution to look for __name__ where I want it

#

probably it'll be too finicky for me to use in any actual code but was curious if there was any obvious strategy I'm missing

brazen geyser
#

walk up the stack til you find the calling frame, check __name__ in its f_globals

#

in this case, you'd only need to go 1 level up the stack i suppose

#

if sys._getframe(1).f_globals.get('__name__', None) == '__main__':

#

@old flint

#

@low acorn how often do you see python builds that cpython based in production?

#

that aren't*

old flint
#

haha that might be it. Yea, I'll be using the assumption that I'm exactly one import away

analog rock
#

Any ideas for this fibonacci guy

#
a,b=0,1
exec('print(a);a,b=b,a+b;'*31)
analog rock
#

can I do +=1 on a string?

#

to make it go to the next ascii value?

#

cause that'd be niceee

brazen geyser
#

no

analog rock
#

didn't think so tbh

brazen geyser
#

not ordinarily

#

with some hackery yes

analog rock
#

probably hackery that is too long for my golf

thin trout
#

chr(ord(c)+1) it is pretty small I think

#

13 chars

marsh void
#

long

#

๐Ÿ‘€

distant wave
#

You'd be able to save ~9 chars by taking advantage of lower chars, probably

#

but that requires the chr(ord( so saves nothing

analog rock
#

yeah that's very longg

cursive plover
#

So I had this horrendously long code

#

which I managed to reduce to

#
x = bin(int(input()))[2:]
even = x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1')
odd = x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')
 
y = ""
for i in range(len(x)):
    y += ("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0")

print(int(y,2))
#

now if someone could help me baar this:

y = ""
for i in range(len(x)):
    y += ("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0")
#

then, I could get the whole program to be a baar thing

(lambda x, even, odd: (The baar code, print(int(y,2)))(input stuff)
#

so how do I get those three statements into a baar? :/

thin trout
#

A list comp and a join?

cursive plover
#

oh wait yeah, lemme try that

thin trout
#
"".join(("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))) ```
cursive plover
#

y = [("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))]

#

yep!

x = bin(int(input()))[2:]
even = x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1')
odd = x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')
 
y = [("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))]


print(int(("".join(y)),2))
#

bingo! thank you! so my final code would be this:

#

python (lambda x, even, odd: print(int(("".join([("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))])),2))) (bin(int(input()))[2:], x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1'), x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1'))

#

wait that gives me an error: NameError: name 'x' is not defined

#

Nevermind, that lambda conversion failed.
How do i convert the code into a lambda expression

#

Okay I got it, I got rid of even and odd and did it like this:


(lambda x: print(int(("".join([("0" if i%2 == 0 else x[i]) if (((x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')) < (x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1')) and len(x)%2 != 0) or ((x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')) >= (x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1')) and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))])),2)))(bin(int(input()))[2:])  
#

I wonder if there's a better way to write that :/

sick hound
#
x = bin(int(input()))[2:]
even = x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1')
odd = x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')```
#

you were using x to create even and odd

analog rock
#

x = f'{int(input()):b}'

#

shorter

sick hound
#

so you would need to do py (lambda x: (lambda even, odd: ...)(<define even>, <define odd>))(<define x>)

cursive plover
#

@sick hound well, then I did

(lambda x: 
(lambda even, odd: 
print(int(("".join([("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))])),2))))
(x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1'), x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1'))
(bin(int(input()))[2:])
sick hound
#

you broke something with the brackets

#

there's more ( than )

cursive plover
#

@sick hound it's not fixed but I still get name error

#

wait

#
(lambda x: 
(lambda even, odd: 
print(int(("".join([("0" if i%2 == 0 else x[i]) if ((odd < even and len(x)%2 != 0) or (odd >= even and len(x)%2 == 0)) else (x[i] if i%2 == 0 else "0") for i in range(len(x))])),2)))
(x[::2].count('1') if len(x)%2 == 0 else x[1::2].count('1'), x[1::2].count('1') if len(x)%2 == 0 else x[::2].count('1')))
(bin(int(input()))[2:])

is the fixed version

#

AND THAT WORKS!

#

Oh yeah! thank you
not pretty but yeah xd

#

x = f'{int(input()):b}'
@analog rock I know the f is for f string, but I googled that whole thing and I couldn't find much. How's that managing to convert the input to binary? What would I have to change b to get it into other bases? What should be the keywords I should be googling for this? I didn't find it in the docs either: https://docs.python.org/3/reference/lexical_analysis.html#f-strings

analog rock
#

the :b converts it to binary

#

idrk which docs tho

cursive plover
#

what is the :b thing called

analog rock
#

no idea I'm afraid

cursive plover
#

ah, alright

cursive plover
#

oh great, thank you ! โค๏ธ

low acorn
#

@low acorn how often do you see python builds that cpython based in production? that aren't*
@brazen geyser no idea, i just repeated the piece of advice i found on stackoverflow about inspect or even sys.get_frame , the guy seemed to have a solid stacko reputation so i trusted him as i have yet to use python in a professional context for now .

low acorn
proper vault
#

Thing is, very few companies use python that is not CPython

low acorn
#

i see

bitter iris
#

The bad thing about implementation details isn't only avability but also backwards compability. It is easy to do backwards-incompatible changes on implementation details rather then language specs (which is really rare)

brazen geyser
#

re: availability i think jython, ironpython and stackless all have _getframe and inspect. micropython and circuitpython probably dont

#

oh yeah pypy has them i think

marsh void
#

Oh thatโ€™s neat

#

I donโ€™t think they have gc tho

#

since like, PyPy does not even have a GC

bitter iris
#

pypy have GC

#

also check out pypy-stm, it is kind a mind blowing

marsh void
#

But does it have gc

#

the module

bitter iris
#

Looks like it does

gilded orchid
#

This page is about pypy-stm, a special in-development version of PyPy which can run multiple independent CPU-hungry threads in the same process in parallel. It is a solution to what is known in the Python world as the โ€œglobal interpreter lock (GIL)โ€ problem โ€” it is an implementation of Python without the GIL.

#

wow that's kinda insane

bitter iris
#

there is bunch of europython talks about that subject

#

it is a pretty cool concept

analog rock
#

is there a more concise way to say x>y<1

gilded orchid
#

what's y? (can it be a float or negative?)

vestal solstice
#

if they are boolean, x>y

#

otherwise doubt it

vocal nest
#

How does anybody understand how to write this

cursive plover
#

lol I wrote that

#

with jan's and akarys' help

#

I think I posted the normal long program before it which is baar here?

proper vault
#

You start with a more reasonable program and work your way down

#

Following some basic rules along with some creativity

analog rock
#

x and y are ints

vocal nest
#

@cursive plover what does that function do?

cursive plover
#

@vocal nest
okay so what that program does is:
You're given a number, which you are to convert to binary.
Then in the binary form, you need to check number of 1s at 'even' and 'odd' positions(the rightmost digit is at position 1, then the digit towards the left of it at position 2, so on..)
if number of ones at the 'odd' positions are less than those at 'even' positions, then make the numbers at odd positions 0.
Otherwise, make the numbers at even positions 0.

#

after that, print the resultant number

vocal nest
#

So say I give it this number

#

5

#

what would the output be?

#

Expected

cursive plover
#

@vocal nest it would be 5

vocal nest
#

because its an odd right?"

cursive plover
#

er no

#

because 5 is 101

#

so, starting from right

vocal nest
#

ooh

#

Yea

cursive plover
#

at position 1 you have a 1,
at position 2 you have a 0
at position 3 you have a 1

vocal nest
#

yeayea

cursive plover
#

so 1s at odd positions are greater than those at even positions, so make everything at even positions 0
(in this case, everything is already 0 at even positions)

#

so it remains 101, which is 5

#

if it was 12

vocal nest
#

wait I totally got it

#

it would be

cursive plover
#

it would bw 1100, which would become 0100 which is 4

vocal nest
#

1100

#

right

cursive plover
#

yup

vocal nest
#

Very cool, how are you using it?

cursive plover
#

erm, just came across it somewhere

#

someone was solving these algorithmic practice questions and she showed me this

vocal nest
#

oh right

cursive plover
#

i thought it would be good practice to hone my baar coding skills

vocal nest
#

yea thats awesome

cursive plover
#

since I'm very new to it

vocal nest
#

Yea esoteric looks like brainfuck

#

i mean

#

Lambda oneliners

cursive plover
#

lakmatiol here introduced it to me

vocal nest
#

awesome

proper vault
#

someone made this wonderful factorial function

assert (lambda f: (lambda x: x(x))(lambda y: f(lambda x: y(y)(x))))(
    lambda f: lambda n: (
        lambda n: n(lambda f: lambda x: lambda y: y())(lambda x: lambda y: x())
    )(n)(lambda: lambda f: lambda x: f(x))(
        lambda: (lambda x: lambda y: lambda f: y(x(f)))(n)(
            f(
                (
                    lambda n: (lambda p: p(lambda x: lambda y: y))(
                        n(
                            (
                                lambda p: (lambda a: lambda b: lambda s: s(a)(b))(
                                    (lambda n: lambda f: lambda x: f(n(f)(x)))(
                                        (lambda p: p(lambda x: lambda y: x))(p)
                                    )
                                )((lambda p: p(lambda x: lambda y: x))(p))
                            )
                        )(
                            (lambda a: lambda b: lambda s: s(a)(b))(
                                lambda f: lambda x: x
                            )(lambda f: lambda x: x)
                        )
                    )
                )(n)
            )
        )
    )
)(lambda f: lambda x: f(f(f(x))))(lambda x: x + 1)(0) == 6
#---------------------^ input here as a church numeral
analog rock
#

lol

#

I love code golf

vocal nest
#

Lambdas are amazing

#

But I dont rly get them

#

never used them although I know perfectly how they work

proper vault
#

they are not that useful in actual code

cursive plover
#

what's x(x)

proper vault
#

I mostly use them to do dumb things like integer math without integers

#

call x with x as an argument

vocal nest
#

like

#

how would

#

call x with x as an argument work

proper vault
#

you can call functions with functions as arguments

#

such as map and filter

cursive plover
#

did the person who write that also explain any parts of it?

#

I don't quite get how that works

proper vault
#

it is just lambda calculus

cursive plover
#

I've never heard of that term before

proper vault
vocal nest
#

it is abstracted calculus*

proper vault
#

it is quite unrelated to calc stuff like derivatives and intergrals

#

y'know how you have turing machines as the basis for computing. Lambda calculus is an alternative description of such machines, sometimes nice. e.g. erlang, haskell are based on it

cursive plover
#

right, thank you for the resource! I'll get onto it

vocal nest
#
position = max(enumerate(a), key=lambda x: x[1])[0]
#

Just used lambda

proper vault
#

I generally use operator.itemgetter for this

#

but key kwargs are one of the uses for lambdas

vocal nest
#

๐Ÿ˜„

calm rampart
#

i wish python had arrow lambdas

analog rock
#

what's the difference?

calm rampart
#

shorter

analog rock
#

yeah I guess

#

for golf

#

what's ur code-golf username?

proper vault
#

it would make me not feel like a failure for using a lambda

edgy kelp
#

That's exactly what guido wanted you to feel ๐Ÿ˜„

edgy kelp
#

realised we can do this

In [2]: from types import SimpleNamespace

In [3]: a=SimpleNamespace()

In [4]: setattr(a, "1()", "Magic string")

In [5]: "{0.1()}".format(a)
Out[5]: 'Magic string'
#

privat-er vars

snow beacon
#

It'll be in there somewhere.

cursive plover
#

@edgy kelp what is the 1() doing there in setattr

snow beacon
#

Does SimpleNamespace have a custom __setattr__?

edgy kelp
#

Just an object that can have instance vars.
Ought to work on them all, but it's a var only accessible through that, getattr and if there's anything else that fetches from strings

bitter iris
marsh void
#

Did you uhm

#

ast.parse?

#

@bitter iris

bitter iris
#

yea ast.parse + ast.dump with new indent = 4

sick hound
#

a = lambda n: for i in range(n): print(f"You have been funny for {i} times!");a(1000)

#

Condense this

#

Please

proper vault
#
for i in range(1000):print('You have been funny for',i,'times!')
wide depot
#
a = lambda n: for i in range(n):print('You have been funny for',i,'times!');a(100)
crystal mica
#
(lambda n: [*map(print, map("You have been funny for {} times!".format,range(n)))])(1000)```
#

hmm

marsh void
#
(lambda n: any(map(print, map("You have been funny for {} times!".format, range(n)))))(1000)``` @crystal mica
proper vault
#
(lambda n:[0 for i in range(n)if print('You have been funny for',i,'times!'])(1000)```
bitter iris
#
(f := lambda n: (n > 0 and print(f"You have been funny for {n} seconds") or f(n-1)))(100)
analog rock
#
(lambda n:[0for i in range(n)if print('You have been funny for',i,'times!'])(1000)```
#

lakmatiol left a space in

formal sandal
#

Why not just

(lambda n:[print('You have been funny for',i,'times!')for i in range(n)])(1000)
proper vault
#

wastes memory ๐Ÿ˜›

#

no one needs a list of 1000 Nones

formal sandal
#

Who needs a list of 1000 0's?

proper vault
#

the list is empty, because if print(... is always false

formal sandal
#

oh

#

Well, this is 1 character shorter:

(lambda n:any(print('You have been funny for',i,'times!')for i in range(n)))(1000)
#

If you fix the unmatched (

sick hound
#

why not py any(print('You have been funny for',i,'times!')for i in range(1000))

#

or py for i in range(1000):print('You have been funny for',i,'times!') if we're allowing it to not be an expression

#

or py [print('You have been funny for',i,'times!')for i in range(1000)]

proper vault
#

I have no idea

distant wave
#
(lambda n:print(('You have been funny for {} times!\n'*n).format(*range(n))))(1000)
marsh void
#

lmao

#

big brain

#

you didnโ€™t add \n though

analog rock
#

also it should be *n

#

in case n is not 1000

potent fulcrum
#

Hey on the topic of esoteric python / code-gore. What's anyone's favorite abuse of __init_subclass__ and metaclasses (or shudder using both at once)?

bitter iris
#

I used it to re-initalize mutable class defaults once

distant wave
#

derp

formal sandal
#
(lambda n:print('You have been funny for %s times!\n'*n%(*range(n),)))(1000)
marsh void
#
(lambda n:print(('You have been funny for %s times!\n'*n%(*range(n),))[:-1]))(1000)
#

for correct new lines

robust palm
#
i=0;exec("print(f'You have been funny for {i} times');i+=1;"*1000)```
vestal solstice
#

'You have been funny for',i,'times'

#

looks one shorter to me

analog rock
#

use ; instead of \n to save a character

#

in Friend's one

grizzled cloak
#

exec and ; are cheating!

brisk zenith
#

shush! their wives might hear if you scream that too loudly.

formal sandal
#

Check this out.
https://repl.it/@int6h/DataDrivenTesting
It's my new data-driven unit testing framework!

#

Suppose you have some code that you need to test, and that code consists of modules that export something.

#

Then you can create a 'mirrored' structure of folders that will be used to test these modules.

#

So each export corresponds to a test file

ripe depot
#

Has anyone here used the usbserial4a package?

marsh void
#

Soo? :)

bitter iris
#

first hint: PyRun_InteractiveOneObjectEx and the oenc

marsh void
cursive plover
#

So I'm trying to bar this piece of code now, but it's got try catch in it so idk how I'd lambda that:

~~```python
a = input()
num = int(input())
ans = []
i = 0
j = i

while True:
try:
form = [int(char) for char in a[j:i+1]]
if sum(form) == num:
ans.append("".join(str(char) for char in form))
if (sum(form) + int(a[i+1])) <= num:
i += 1
elif (sum(form) - int(a[i])) <= num:
j += 1
else:
j = i
i += 1
except:
break

print(*ans)

What the program does btw is, given a string say `9390215671237812390`, and a number `9`, find all substrings whose sum equals `9`. The output in this case would be `9 9 90 81 9 90`
#

actually, I got rid of the try catch, but it's uglier now

#
a = input()
num = int(input())
ans = []
i = 0
j = i

while i < len(a):
        form = [int(char) for char in a[j:i+1]]
        if not form:
            i += 1
            continue
        if sum(form) == num:
            ans.append("".join(str(char) for char in form))
        if i+1 < len(a) and (sum(form) + int(a[i+1])) <= num:
            i += 1
        elif (sum(form) - int(a[i])) <= num:
            j += 1
        else:
            j = i
            i += 1        

print(*ans)
#

still unsure how I would baar this, especially with that while thing in it
Any help? :/

crystal mica
#

Well, try to simplify it first imo, then you can do it

#

The simplest, straightforward is like this

#

!e ```py
string = '9390215671237812390'

def get_sum(s: str) -> int:
return sum(map(int, s))

def generate_all_substrings(s: str) -> list:
substrings = []
for length in range(1, len(s)):
for start in range(0, len(s) - length):
substrings.append(s[start:start+length])
return substrings

print([substr for substr in generate_all_substrings(string) if get_sum(substr) == 9])```

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

['9', '9', '9', '90', '81']
crystal mica
#

This is easy to put into one line

#

!e py (lambda s,total:print([_s for _s in(s[i:i+l]for l in range(1,len(s))for i in range(len(s)-l))if sum(map(int,_s))==total]))('9390215671237812390',9)

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

['9', '9', '9', '90', '81']
crystal mica
#

There we go

#

The idea of how you approach it is very important

#

Missing a 1

#
(lambda s,t:print([_s for _s in(s[i:i+l]for l in range(1,len(s))for i in range(len(s)-l+1))if sum(map(int,_s))==t]))('9390215671237812390',9)```
night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

['9', '9', '9', '90', '81', '90']
crystal mica
#

There we go

marsh void
#

May I question why

#

Ah and also

#

@crystal mica I am currently working on braces in python

cursive plover
#

@crystal mica hm yeah, that's nice
but

#

isn't that O(n^2) while mine is essentially O(n)?

#

also

#

this does not maintain the order in which the substrings occur in the string, I forgot to mention that is a requirement too

#

how would you alter the code for that :/

crystal mica
#

Ah I see, there are adjustment that you can do to prevent that, for example stop when substr is greater than the t

#

@marsh void that sounds very bracely!

marsh void
#

Indeed it does!

cursive plover
#

you mean if sum(substring) > total, don't append?

marsh void
#
(lambda x,y:{for x in range(x){for y in range(y){print(x,y)}})(10,10)``` @crystal mica
#

hehe

#

Ah, AND! Top-level awaits on < 3.8!

crystal mica
#

I mean when sum(substring) > t then exit the inner loop, takewhile is a good candiate for that

#

!e py (lambda s,t:print([_s for _s in(s[i:j+1]for i in range(len(s))for j in range(i,len(s)))if sum(map(int,_s))==t]))('9390215671237812390',9)

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

['9', '9', '90', '81', '9', '90']
crystal mica
#

Changing the order of the loop -> preserve the order of finding

#

!e py (lambda s,t:print([_s for _s in(s[i:j+1]for i in range(len(s))for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))))if sum(map(int,_s))==t]))('9390215671237812390',9)

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

['9', '9', '90', '81', '9', '90']
crystal mica
#

This is with takewhile

#

!docs get itertools.takewhile

night quarryBOT
#
itertools.takewhile(predicate, iterable)```
Make an iterator that returns elements from the iterable as long as the predicate is true. Roughly equivalent to:

```py
def takewhile(predicate, iterable):
    # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
    for x in iterable:
        if predicate(x):
            yield x
        else:
            break
crystal mica
#

It's very handy!

cursive plover
#

thanks, I'm reading through it at the moment!

#

I'll ask you again when I don't understand smth in that solution, or in takewhile

#

โค๏ธ

thin trout
#

I was wondering, is there any way to make this true?

(obj1 == obj2) and (obj1 != obj2) ```
crystal mica
#

Eh, by modifying ojb1.__eq__ I guess?

marsh void
#

^

#

We already made 1 == 1 and 1 != 1 some time ago

cursive plover
#

!e py (lambda s,t:print([_s for _s in(s[i:j+1]for i in range(len(s))for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))))if sum(map(int,_s))==t]))('9390215671237812390',9)
@crystal mica
ok so 2 things

One, is the takewhile(lambda j: ...) assigning j a list or something? because it's for j in .... , so that either is a list, or a generator? Right?

Second, how did you just do the __import__ thing? How's it different from import ? Does this thing have a name?
And why is the itertools in inverted commas, 'itertools' and not itertools ?

crystal mica
#

when you dopy import stringyou basically dopy string = __import__('string')

#

And py import string as built_in_stringispy built_in_string = __import__('string')

#

In this case we're importing itertools without doing a separate import line

#

And assign it to a variable

#

takewhile returns a generator

cursive plover
#

oh okay

crystal mica
#

Basically it's the same as py for things in my_iterable: if condition: yield things else: break

cursive plover
#

ah, it's a generator cuz it has yield, right?

crystal mica
#

You can certainly check what it is

#

!e py import itertools a = itertools.takewhile(bool, range(100)) print(type(a), a)

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

<class 'itertools.takewhile'> <itertools.takewhile object at 0x7f3b5fb9df40>
crystal mica
#

It should be an iterator, so unless you unpack it

cursive plover
#

unless I unpack it, I won't be able to print its content

crystal mica
#

Yep, unless you actually iterate over it and consume it

marsh void
#

itertools' objects are essentially iterable classes, not generators

crystal mica
#

!e py import itertools a = itertools.takewhile(bool, range(1, 10)) print(type(a)) print(list(a)) print(list(a))

night quarryBOT
#

@crystal mica :white_check_mark: Your eval job has completed with return code 0.

001 | <class 'itertools.takewhile'>
002 | [1, 2, 3, 4, 5, 6, 7, 8, 9]
003 | []
marsh void
#

Because writing generators is hella shit

#

In C

crystal mica
#

Hmm, that can be the case as well

#

itertools is a built in, so it is in C

marsh void
#

built-in != made in C

cursive plover
#

one more thing

#
(lambda s,t:print([_s for _s in(s[i:j+1]for i in range(len(s))for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))))if sum(map(int,_s))==t]))('9390215671237812390',9)```

why did the whole thing have to be inside brackets, for in
ie for _s in(...)
when I remove the brackets the code gives errors

#

when we do a for i in range(..) we don't need the brackets right? We don't do a for i in(range(...)), so why here

vestal solstice
#

because s[i:j+1]for i in range(len(s) isn't syntactiaclly anything

#

it needs [] or () around it

cursive plover
#

um don't we do that sort of thing in a list comprehension though?
like x = [i for i in range(something) for j in range(something)]

#

oh wait, that's what you just said

#

my bad

#

right, got it. thanks lol

vestal solstice
#

you can build it into the comprehension, so you'll have s[i:j+1] everywhere you have _s

#

which is two places

#

let me read it...

bitter iris
#

Yea, there is no yield in C level, so if you are going to define a generator it should be a class with iter and next

cursive plover
#

actually wait

#
print([_s for _s in(s[i:j+1]for i in range(len(s))for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))))if sum(map(int,_s))==t])
#

isn't the whole thing already in []

#

so

print([_s for _s in s[i:j+1] for i in range(len(s)) for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))) if sum(map(int,_s))==t])
vestal solstice
#

no

cursive plover
#

why wouldn't this work ?

#

but it's a list comprehension already isn't it?

vestal solstice
#

it's now in the wrong order

thin trout
#

!= isn't testing for __eq__ to return False?

vestal solstice
#

i and j donn't exist at that point

#

@thin trout there's __ne__ I think, it probably falls back on eq but it doesn't need it

cursive plover
#

oh yeah, so I'll have to change the order

#

so it would be

#

hm nah, that looks like the only way to do it

vestal solstice
#
print([s[i:j+1]for i in range(len(s))for j in __import__('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s)))if sum(map(int,s[i:j+1]))==t])
#

here

#

you replace _s with s[i:j+1] in two places and the tricky part is to find a closing ) to remove ๐Ÿ™‚

cursive plover
#

oh yeah that makes sense

#

so the earlier one had _s being picked from a generator, and being added to a list, which was finally printed

#

here, we've got a list which we append a substring directly to, and print the list out

#

yeah?

vestal solstice
#

sure

cursive plover
#

nice, that makes sense

#

thanks โค๏ธ

vestal solstice
#

and you can do this to "rename" it to _s anyway ```py
print([_s for i in range(len(s))for j in import('itertools').takewhile(lambda j:sum(map(int,s[i:j+1]))<=t,range(i,len(s))) for _s in [s[i:j+1]] if sum(map(int,_s)==t])

#

for _s in [s[i:j+1]]

#

make a list of one element to unpack it back under a different name

#

that's the problem with python comprehensions, that isn't there in haskell

#

where you can ..., let _s = s[i:j+1], ... , as a step

cursive plover
#

you mean assigning a list to a variable can be done inside a lambda expression in haskell?

vestal solstice
#

inside a comprehension

#

like there are two things you can do in a comprehension, a "guard" with if and an iteration with for

#

you can interleave them in any order

#

in haskell they are separated with commas:
[x + 3 | x <- nums, mod x 2 == 0] this means
[x + 3 for x in nums if x % 2 == 0]

#

python omits | and ,

cursive plover
#

oh right

#

is there a reason they chose to omit it?

vestal solstice
#

idk

cursive plover
#

also, when you say any order

#

I thought it's always [xyz for something if something] ?

vestal solstice
#

you can have ifs interleaved with fors

cursive plover
#

but never an if before all the fors, yeah?

vestal solstice
#

sure, you have no bound variables before the fors, so an if has nothing to work with

cursive plover
#

no I mean

vestal solstice
#

I guess you can just check some global flag

#

that should work

cursive plover
#

something like

if x>y:
  for i in range(something):
    blah blah
vestal solstice
#

i just checked, that;s invalid

cursive plover
#

yea

vestal solstice
#
a = 4
b = 9
print([d if a > b for d in [1,2,3]])
#

dont work

cursive plover
#

yeah

formal sandal
#

!e

a = 4
b = 9
print([d for d in[1,2,3]if a > b])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

[]
vestal solstice
#

!e```
print([1 for x in "a" if False for y in 5])

night quarryBOT
#
Did you mean ...

exit()
except
enumerate

vestal solstice
#

what

#

oh, !enumerate

formal sandal
#

!e

print([1for x in"a"for y in"b"if""])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

[]
vestal solstice
#

basically you try to iterate through an integer and it doesn;t crash

#

because it's after an if

#

so doesn't happen

formal sandal
#

๐Ÿ‘€

bitter iris
#

never noticed this ambiguity if""

lament ibex
#

On a related note, i.e. breaking out of comprehensions, this list(next(iter([])) if x == 'a' else x for x in 'blah') works in py2 but doesn't in py3 (list doesn't absorb the stopiteration). Anyone know a workaround?

sick hound
#

it works in python 3.6

#

in python 3.7 it doesn't

lament ibex
#

ah in my head you've either got prehistoric python (py2) or current python (3.7+) lol

sick hound
#

!e
print([1 for x in "a" if False for y in 5])

night quarryBOT
#

@sick hound :white_check_mark: Your eval job has completed with return code 0.

[]
marsh void
#

I guess

formal sandal
#

I can create new 'types' with tools like either, product, record etc. using simple data structures

#

Then I can use these 'types' as function annotations. The @tc makes them work as argument filters, and @mdtc allows overloading functions with help of this infrastructure.

#

I can't believe I even managed to make it all work together.

bitter iris
#

looks great except I guess a bit implicit @formal sandal

formal sandal
#

What do you mean?

bitter iris
#

namings, like md, tc, mdtc

#

they aren't clear about what their purpose

formal sandal
#

Maybe change tc => template_check and md => multiple_dispatch or overload

#

But I also have mdtc which is their composition. It's kinda hard to find a name for it...

#

Maybe I shouldn't use md and rename mdtc to overload

bitter iris
#

that totally makes sense and IMHO looks better

#

overload might be conflict with typing.overload

formal sandal
#

Hm...

#

Well, it would be strange to use both typechecking systems at the same time.

#

So to avoid confusion when using both libraries, explicitly state which library you're using

formal sandal
#

Maybe you can use these 'templates' to do some additional checks. A 'template' doesn't necessarily mean 'type'.

#

This will throw an "Invalid UID" error because UID is a result of msg.

tribal moon
#
[*(lambda _____: _____((lambda _: _([-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False)) for __ in range((-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False)).__rmul__(-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False))).__rmul__(-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False))) + 8))]))(lambda ___: [____ for ____ in range(1, sum(___).__add__(1))])))(lambda ______: [__import__('builtins').__dict__['print'](''.join(list(map(str, _______)))) for _______ in __import__('itertools').__dict__['product'](______, repeat=len(______)) if not None])]```
#

prints 111111111 and goes up from there

#

yewah

cursive plover
#

nice

#

is there a reason you named your variables as _, __, ____, instead of like a,b,c lol

#

I wanna fractionate the code down to understand it, but I'm scared I'll end up breaking it by replacing those vars incorrectly lol

snow beacon
#

They're just to confuse people.

tribal moon
snow beacon
#

@tribal moon You don't need to use abs because you can multiply by booleans as if they were integers. And if you did need integers, you could use +False to be slightly shorter.

tribal moon
#

Yeah this is really messy

#

@cursive plover if you want, you can replace the underscores with your own variable names

#

You can use notepad++ to do it

cursive plover
#

yeah I'm gonna do that

shell quiver
#

what does it mean 'obfuscation'

proper vault
#

making it hard to tell the actual purpose of a given part of code

shell quiver
#
[*(lambda _____: _____((lambda _: _([-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False)) for __ in range((-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False)).__rmul__(-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False))).__rmul__(-~True.__rmul__(abs(False))**-~True.__rmul__(abs(False))) + 8))]))(lambda ___: [____ for ____ in range(1, sum(___).__add__(1))])))(lambda ______: [__import__('builtins').__dict__['print'](''.join(list(map(str, _______)))) for _______ in __import__('itertools').__dict__['product'](______, repeat=len(______)) if not None])]```@tribal moon
#

tf

formal sandal
#

Deliberately making it hard to tell the actual purpose of a given part of code*

shell quiver
#

i-i can see...

#

all i see are lamda True and False

#

in that

formal sandal
#

Involuntary obfuscation is something I wish happened to my code more rarely...

shell quiver
#

w-why?

#

oh wait

#

mis-read it

marsh void
#

Why is there 1

#

range(True, True+True+True)

zealous widget
#

bunch of multiplications with 0

formal sandal
#

!e

def is_syntax_error(s):
  try: compile(s,'','eval')
  except SyntaxError: print(f"'{s}' = Syntax error")
  else: print(f"'{s}' = OK")

is_syntax_error("2.__add__")
is_syntax_error("(2).__add__")
is_syntax_error("2. __add__")
is_syntax_error("2 .__add__")
is_syntax_error("2..__add__")
is_syntax_error("2. .__add__")
is_syntax_error("2.. __add__")
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

001 | '2.__add__' = Syntax error
002 | '(2).__add__' = OK
003 | '2. __add__' = Syntax error
004 | '2 .__add__' = OK
005 | '2..__add__' = OK
006 | '2. .__add__' = OK
007 | '2.. __add__' = OK
formal sandal
#

!e

def catcher(handler, e=Exception):
  def catch(f):
    def _(*args, **kwargs):
      try:
        return f(*args, **kwargs)
      except e as _e:
        return handler(*args, _e=_e, **kwargs)
    return _
  return catch

# Now you can write crap like this:

v = catcher(lambda _e:eval("1 .__add__"))(lambda:eval("1. __add__"))()
print(v(41))
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

42
bitter iris
#
class NumberAttributes(TokenTransformer):
    
    @pattern("number", "name")
    def fix_number_attributes(self, number, attribute):
        if number.string.endswith("."):
            return number._replace(string = f"{number.string[:-1]} ."), attribute