#esoteric-python

1 messages ยท Page 148 of 1

fair quartz
#

guys how do i make decorators for classes?

#

such as data class

#

!e

from ctypes import py_object
x = "help"
py_object.from_address(id(x)).value = "me"
print(x)
night quarryBOT
#

@fair quartz :white_check_mark: Your eval job has completed with return code 0.

help
fair quartz
#

!e

from ctypes import py_object
x = 1000
py_object.from_address(id(x)).value = 3000
print(x)โ€Š
night quarryBOT
#

@fair quartz :white_check_mark: Your eval job has completed with return code 0.

1000
fair quartz
#

!e

@lambda _: _()
class true:
    def __new__(self):
        return False
    
print(true is False)โ€Š
night quarryBOT
#

@fair quartz :white_check_mark: Your eval job has completed with return code 0.

True
fair quartz
#

yes ofc

cerulean rivet
golden finch
#

What was the rationale for developing it like this? So what method of type is being called when I do type(some_class)?

quartz wave
#

there's a check in the same function before that snippet

golden finch
quartz wave
#

so the check is for one-argument no-keyword type() call https://github.com/python/cpython/blob/main/Objects/typeobject.c#L1075-L1096 ```py
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class # basically getting .ob_type which is equivalent to ctypes.py_object.from_address(id(args[0])+8).value
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")

GitHub

The Python programming language. Contribute to python/cpython development by creating an account on GitHub.

quartz wave
golden finch
#

so when I go type(cls) is type.__call__ being invoked?

golden finch
#

I can't read this very well I'm afraid

#

I know a fair bit of C but the internals of python are complex

#

if type=&PyType_Type - what does this bit do?

quartz wave
#

basically check against the builtin type class

earnest wing
#

type.__call__(type) is the funny one really, since both type(type) and type() are correct interpretations of it

golden finch
#

okay this is really perplexing

#

so do type instances inherit this?

quartz wave
#

any time you call a class, you do type.__call__

golden finch
quartz wave
golden finch
quartz wave
#

wait

golden finch
#

was trying to type that out

#

but

#

uh oh

quartz wave
#

!e ```py
def type_call(cls, *args, **kwargs):
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")
if cls.new is None:
raise TypeError(f"cannot create '{cls.name}' instances")
obj = cls.new(*args, **kwargs)
if not isinstance(obj, cls):
return obj
if cls.init is not None:
cls.init(obj, *args, **kwargs)
return obj

print(type_call(type, 5)) # type(5)
print(type_call(int, int, 3.3)) # int(3.3)
type_call(type) # type()

night quarryBOT
#

@quartz wave :x: Your eval job has completed with return code 1.

001 | <class 'int'>
002 | 3
003 | Traceback (most recent call last):
004 |   File "<string>", line 19, in <module>
005 |   File "<string>", line 7, in type_call
006 | TypeError: type() takes 1 or 3 arguments
quartz wave
#

what's wrong with non-type classes ๐Ÿค”

#

oh wait

#

i'm dumb

#

!e ```py
def type_call(cls, *args, **kwargs):
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")
if cls.new is None:
raise TypeError(f"cannot create '{cls.name}' instances")
obj = cls.new(cls, *args, **kwargs)
if not isinstance(obj, cls):
return obj
if cls.init is not None:
cls.init(obj, *args, **kwargs)
return obj

print(type_call(type, 5)) # type(5)
print(type_call(int, 3.3)) # int(3.3)
type_call(type) # type()

night quarryBOT
#

@quartz wave :x: Your eval job has completed with return code 1.

001 | <class 'int'>
002 | 3
003 | Traceback (most recent call last):
004 |   File "<string>", line 19, in <module>
005 |   File "<string>", line 7, in type_call
006 | TypeError: type() takes 1 or 3 arguments
quartz wave
#

@golden finch here's a theoretically full replication of type.__call__

golden finch
#

thank you

golden finch
#

How could I use inspect to get the source of a whole module? (esoteric purposes)

earnest wing
#

getsource should work on modules

#

Not C modules but

quartz wave
#

also packages

golden finch
earnest wing
#

the module is parsed and compiled before running

#

also yes

quartz wave
#

that was quite offensive code

golden finch
#

variable names were dubious

#

but perhaps a discord server is not the appropriate place fo this discussion

#

given the typical climate thereof

fair quartz
wheat river
#

!e

def decorator(_class):
    _class.hello = 10
    return _class()


@decorator
class lol:
    ...


print(lol.hello)
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

10
wheat river
#

!e

def singleton(cls):
    instances = {}
    
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return wrapper


@singleton
class Foo:
    def func(self):
        return 10


a = Foo()
b = Foo()
print(a is b)
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

True
pastel sparrow
#

!e why not just ```py
class singleton:
instance = None

def __new__(cls, *args, **kwargs):
    if cls.instance is not None:
        return cls.instance

    cls.instance = super().__new__(cls, *args, **kwargs)
    return cls.instance

a = singleton()
b = singleton()

print(a is b)

night quarryBOT
#

@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.

True
pastel sparrow
#

okay there

wheat river
#

they wanted class decorators ๐Ÿคทโ€โ™‚๏ธ

pastel sparrow
#

eh

wheat river
pastel sparrow
#

ah

#

mb

hard spoke
#

A nice toolbox for all* of your esoteric needs!
*some

import sys
import ctypes

def swap(a: object, b: object) -> None:
    assert sys.getsizeof(a) == sys.getsizeof(b)
    n = sys.getsizeof(a)
    A = (ctypes.c_byte * n).from_address(id(a))
    B = (ctypes.c_byte * n).from_address(id(b))
    for i in range(n):
        A[i], B[i] = B[i], A[i]

def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
    n = min(sys.getsizeof(to_replace), sys.getsizeof(replace_with))
    if not allow_diff_size:
        assert sys.getsizeof(to_replace) == sys.getsizeof(replace_with)
    OLD = (ctypes.c_byte * n).from_address(id(to_replace))
    NEW = (ctypes.c_byte * n).from_address(id(replace_with))
    for i in range(n):
        OLD[i] = NEW[i]
wheat river
#

๐Ÿ‘€ ๐Ÿ‘€ ๐Ÿ‘€

upbeat sonnet
#
divisors = lambda n: len([i for i in range(1, n + 1) if n%i==0])```
languid hare
#
divisors=lambda n:sum(n%i==0for i in range(1,n+1))
upbeat sonnet
#

!e py divisors=lambda n:sum(n%i==0 for i in range(1,n+1)) print(divisors(123))

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

4
upbeat sonnet
#

ohhh

#

ic

#

since we just need the len we dont need the if check

languid hare
#

close

upbeat sonnet
#
def digitize(n): return [int(i) for i in reversed(str(n))]```
languid hare
#

n%i==0 is truthy when i is a factor, and booleans are essentially 1 and 0, so taking the sum over them essentially counts the number of n%i==0

upbeat sonnet
#

and the false values are 0

#

so the sum cant add it

#

and the true ones are 1

languid hare
upbeat sonnet
#
def min_value(digits): return  int(''.join(sorted((set(map(str, digits))))))```
upbeat sonnet
languid hare
#

it's like string slicing

#

most commonly you see [start:stop]

#

but there's also [start:stop:step]

upbeat sonnet
languid hare
#

start and stop by default are "everything", so [:] just takes everything, but [::-1] takes everything with a step of -1, ie reversed

upbeat sonnet
#
def powers_of_two(n): return [1, *[2**i for i in range(1, n+1)]]```
earnest wing
#

[2**i for i in range(n+1)]

languid hare
#

overthinking is great

rugged sparrow
#

It adds in the overhead from the garbage collector, and whatever type(obj).__sizeof__(obj)returns

hard spoke
#

huh

#

I don't know anything about the former, but isn't adding the latter correct?

#

since different types can have different object sizes and all

rugged sparrow
#

Think about lists

quartz wave
#
>>> a = 4
>>> b = 5
>>> swap(a, b)
>>> a
5
>>> b
5
``` doesn't work for cached integers?
rugged sparrow
#

2 lists of different size have the same size in memory directly, but their backing arrays are different sizes

rugged sparrow
#

So list sizeof adds in the size of the backing array

#

Despite that array not being directly after the original object in memory

hard spoke
#

ah, I see

#

annoying, not sure what I can do

rugged sparrow
#

Yea all of the sizeof functions are more for memory profiling

hard spoke
#

well, I could manually calculate the size via ctypes The Right Way

#

by looking at the type, and reading the size from its header

#

sounds like work though

rugged sparrow
#

You can also use a combo of basic size and item size

#

But it would be tricky, and you would need to know the underlying semantics for each type

quartz wave
#

PyListObject has that allocated field

rugged sparrow
#

(Not even accounting for the fact that this would severely break the cycle garbage collector)

hard spoke
#

so seems to me like it works alright ๐Ÿฅด

rugged sparrow
quartz wave
#

ok

rugged sparrow
hard spoke
#

might be it

#

it did finish though

rugged sparrow
#

It'll still finish

#

It'll just modify unexpected addresses

hard spoke
#

I can do something fancy like, uhh

rugged sparrow
#

You could call memcpy directly but you'd still have the sizeof problem

hard spoke
#

got it

def swap(a: object, b: object) -> None:
    assert sys.getsizeof(a) == sys.getsizeof(b)
    n = sys.getsizeof(a)
    A = (ctypes.c_byte * n).from_address(id(a))
    B = (ctypes.c_byte * n).from_address(id(b))
    temp = (ctypes.c_byte*n)()
    ctypes.memmove(ctypes.byref(temp), A, n)
    ctypes.memmove(A, B, n)
    ctypes.memmove(B, ctypes.byref(temp), n)
#

4,5 still crashes interpreter, 20,25 works fine

fair quartz
#

wait

#

swap

#

two vars in place

#

right

quartz wave
#

@hard spoke an improvement to replace: ```py
def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
size_OLD = sys.getsizeof(to_replace)
size_NEW = sys.getsizeof(replace_with)
if not allow_diff_size:
assert size_OLD == size_NEW
elif size_OLD < size_NEW:
res = PyObject_Realloc(id(to_replace), size_NEW)
if res == 0:
raise MemoryError
ctypes.c_void_p.from_address(id(to_replace)).value = res
OLD = (ctypes.c_byte * size_NEW).from_address(id(to_replace))
NEW = (ctypes.c_byte * size_NEW).from_address(id(replace_with))
ctypes.memmove(OLD, NEW, size_NEW)

hard spoke
#

huh, PyObject_Realloc is inplace?

quartz wave
#

idk

#

ctypes.c_void_p.from_address(id(to_replace)).value = res may do something

quartz wave
# quartz wave `ctypes.c_void_p.from_address(id(to_replace)).value = res` may do something

without that line: ```py

a = 404
b = 'haha'
replace(a, b, True)
Exception ignored deletion of interned string failed:
Traceback (most recent call last):
File "<stdin>", line 12, in replace
KeyError: 'haha'
<segfault right after executing another line/exiting the interpreter>

with that line: ```py
>>> a = 404
>>> b = 'haha'
>>> replace(a, b, True)
>>> a
'haha'
>>> b
'haha'
rugged sparrow
#

PyObject_Realloc is not guaranteed to be in place

#

It does need a pointer to the address of the object, not the address of the object

#

And it returns the address of the new memory

#

(And afaik, if it needs to reallocate a new address it invalidates the old one)

quartz wave
#

well if the above code works then it works

#

just one problem ```py

a = 'haha'
replace(a, 3, True)
a
3
a is 3
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False

#

also another problem ```py

a = 3
replace(a, (), True)

segfault

rugged sparrow
#

Ie: the realloc problem

quartz wave
#

so it's not from realloc

rugged sparrow
#

3 is interned tho so it's gonna do numerical operations without checking

rugged sparrow
quartz wave
#

hmm yeah

quartz wave
# rugged sparrow Hard to know the issue without the trace back too
>>> replace(a, (), True)
Debug memory block at address p=00007FFC8C3E4368: API ''
    72057594037927936 bytes originally requested
    The 7 pad bytes at p-7 are not all FORBIDDENBYTE (0xfd):
        at p-7: 0x00 *** OUCH
        at p-6: 0x00 *** OUCH
        at p-5: 0x00 *** OUCH
        at p-4: 0x00 *** OUCH
        at p-3: 0x00 *** OUCH
        at p-2: 0x00 *** OUCH
        at p-1: 0x00 *** OUCH
    Because memory is corrupted at the start, the count of bytes requested
       may be bogus, and checking the trailing pad bytes may segfault.
    The 8 pad bytes at tail=01007FFC8C3E4368 are Windows fatal exception: access violation

Current thread 0x000014cc (most recent call first):
  File "<stdin>", line 7 in replace
  File "<stdin>", line 1 in <module>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in replace
OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF
#

py -X dev

rugged sparrow
#

Oh I meant like building python with debug symbols and running it in a debugger like lldb

#

That's how I normally diagnose stuff

quartz wave
#

ok

rugged sparrow
#

You are still calling Realloc with just the address of the object, not a pointer to the address of the object

#

@quartz wave ^

#

Try wrapping id(obj) with c_void_p

#

So it's c_void_p(id(obj))

rugged sparrow
#
>>> x = (1,2,3)
>>> y = "hello world"
>>> replace(x, y, True)
>>> x
'hello world'
>>> y
(1, 2, 3)
>>> ```
#

^ with the fix

#
import ctypes
import sys

def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
    size_OLD = sys.getsizeof(to_replace)
    size_NEW = sys.getsizeof(replace_with)
    if not allow_diff_size:
        assert size_OLD == size_NEW
    elif size_OLD < size_NEW:
        res = ctypes.pythonapi.PyObject_Realloc(ctypes.c_void_p(id(to_replace)), size_NEW)
        if res == 0:
            raise MemoryError
    OLD = (ctypes.c_byte * size_NEW).from_address(id(to_replace))
    temp = (ctypes.c_byte * size_NEW).from_buffer_copy(OLD)
    NEW = (ctypes.c_byte * size_NEW).from_address(id(replace_with))
    ctypes.memmove(OLD, NEW, size_NEW)
    ctypes.memmove(NEW, temp, size_NEW)
#

still will crash on exit due to massive memory corruption

quartz wave
#

also the exact thing i'm trying to fix is replacing a cached integer with the cached empty tuple

golden finch
#

G'day, eso people

#

This is probably impossible, but if it's possible, how could you extract comments from within a function or within the global scope? Not docstrings, comments

quartz wave
# rugged sparrow Oh I meant like building python with debug symbols and running it in a debugger ...

how do i do it with mingw-w64 gdb because it does this ```py
Python path configuration:
PYTHONHOME = 'C:\mingw64\bin..\opt'
PYTHONPATH = (not set)
program name = 'C:\Program Files\Python311\python.exe'
isolated = 0
environment = 1
user site = 1
import site = 1
is in build tree = 0
stdlib dir = 'C:\mingw64\opt\Lib'
sys._base_executable = 'C:\Program Files\Python311\python.exe'
sys.base_prefix = 'C:\mingw64\bin\..\opt'
sys.base_exec_prefix = 'C:\mingw64\bin\..\opt'
sys.platlibdir = 'DLLs'
sys.executable = 'C:\Program Files\Python311\python.exe'
sys.prefix = 'C:\mingw64\bin\..\opt'
sys.exec_prefix = 'C:\mingw64\bin\..\opt'
sys.path = [
'C:\Program Files\Python311\python311.zip',
'C:\mingw64\opt\Lib',
'C:\mingw64\opt\DLLs',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

golden finch
#

So it's not 'esoteric-possible', just straight-up nope

wheat river
#
>>> def foo():
...   exec('a = 10')
...   print(locals())
...   print(a)
...
>>> foo()
{'a': 10}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in foo
NameError: name 'a' is not defined

huh? why? is it looking for a in the global scope?

quartz wave
#

can't find a definition of a anywhere in the function so it looks for it in the global scope

wheat river
#

i c

quartz wave
#
>>> from ast import dump, parse
>>> dump(parse("#oh hi"))
'Module(body=[], type_ignores=[])'
golden finch
#

๐Ÿ‘

#

shame

#

what about just for functions running in a script?

quartz wave
golden finch
# quartz wave strings?

I mean, can you have

def f(x):
  #comment
  ...

#code here that extracts the string 'comment', given f as argument
quartz wave
golden finch
#

so not even by getting the filename and directly reading the file to find the definition of f?

quartz wave
#

yeah you can do that actually

sick hound
#

id like to look at the source code of it

quartz wave
sick hound
#

u didnt print

night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

001 | def generate_tokens(readline):
002 |     """Tokenize a source reading Python code as unicode strings.
003 | 
004 |     This has the same API as tokenize(), except that it expects the *readline*
005 |     callable to return str objects instead of bytes.
006 |     """
007 |     return _tokenize(readline, None)
008 | 
009 | def _tokenize(readline, encoding):
010 |     lnum = parenlev = continued = 0
011 |     numchars = '0123456789'
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/itusemiriv.txt?noredirect

sick hound
quartz wave
#

also regex patterns ๐Ÿค”

#
Whitespace = r'[ \f\t]*'
Comment = r'#[^\r\n]*'
Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
Name = r'\w+'

Hexnumber = r'0[xX](?:_?[0-9a-fA-F])+'
Binnumber = r'0[bB](?:_?[01])+'
Octnumber = r'0[oO](?:_?[0-7])+'
Decnumber = r'(?:0(?:_?0)*|[1-9](?:_?[0-9])*)'
Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
Exponent = r'[eE][-+]?[0-9](?:_?[0-9])*'
Pointfloat = group(r'[0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?',
                   r'\.[0-9](?:_?[0-9])*') + maybe(Exponent)
Expfloat = r'[0-9](?:_?[0-9])*' + Exponent
Floatnumber = group(Pointfloat, Expfloat)
Imagnumber = group(r'[0-9](?:_?[0-9])*[jJ]', Floatnumber + r'[jJ]')
Number = group(Imagnumber, Floatnumber, Intnumber)
wheat river
sick hound
#

!e print(dir())

night quarryBOT
#

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

['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
sick hound
#

!e print(chr(abs(len(dir(reversed))-131))+chr(abs(len(dir(vars))-134)))

night quarryBOT
#

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

hi
wheat river
#

!e

import builtins
from pprint import pprint
pprint(sorted(dir(builtins), reverse=True, key=lambda x: len(dir(eval(x)))))
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 | ['bytearray',
002 |  '__name__',
003 |  'str',
004 |  'bytes',
005 |  'False',
006 |  'True',
007 |  '__debug__',
008 |  'bool',
009 |  'int',
010 |  'float',
011 |  'set',
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/xuwedegubi.txt?noredirect

wheat river
#

bytearray wow

sick hound
#

what

wheat river
#

the builtin class with most methods

#

!e

print(len(dir(bytearray)))
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

87
wheat river
#

bruhv

#

i though str had most lol

sick hound
#

!e print(len(dir(object)))

night quarryBOT
#

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

23
sick hound
#

23 is min and 87 is max

#

damn

wheat river
#

and i thought classes with over 20 methods is a lot lmao

earnest wing
#

23 includes all the preimplemented dunders and mro-related attributes etc

humble rune
#

is this the peak of fizzbuzz or is there something more we can do with this?

#
for i in range(100):print(i%3//2*'Fizz'+i%5//4*'Buzz'or-~i)
earnest wing
#

it's as good as it gets

#

if there was anything better someone in CGCC would have posted it

wheat river
#

CGCC?

earnest wing
wheat river
humble rune
#

any way of making .replace shorter?

earnest wing
#

depends

#

what kind of replace

upbeat sonnet
#

guys what is 0(n) and all the other time complexity

#

thingies

sick iris
#
(
    guess_word_game := lambda word: (
        guessed_word := ["_" for _ in word],
        letter_list := list(word.lower()),
        correct := set(),
        wrong := set(),
        print(f"We are searching for a word with {len(letter_list)} characters"),
        tries := 0,
        (lambda a: lambda: a(a))(
            lambda f: (
                tries := len(correct) + len(wrong),
                letter := input("Letter: ").lower(),
                (
                    (
                        (
                            (guessed_word.__setitem__(i, letter), correct.add(letter))
                            if letter == c
                            else ()
                        ),
                        (wrong.add(letter) if letter not in letter_list else ()),
                    )
                    for i, c in enumerate(letter_list)
                ),
                print("".join(guessed_word)),
                f(f) if guessed_word != letter_list else (),
            )
        )(),
        print(f"End! Correct: {set(correct)} ({len(correct)})"),
        print(f"Wrong: {set(wrong)} {len(wrong)} | Total tries {tries}"),
    ),
    guess_word_game("Oneliner-Challenge"),
)


# def guess_word_game(word: str):
#     guessed_word = ["_" for _ in word]
#     letter_list = list(word.lower())
#     correct = set()
#     wrong = set()
#     print(f"We are searching for a word with {len(letter_list)} characters")

#     while guessed_word != letter_list:
#         tries = len(correct) + len(wrong)
#         letter = input("Letter: ").lower()
#         for i, c in enumerate(letter_list):
#             if letter == c:
#                 guessed_word[i] = letter
#                 correct.add(letter)
#             if letter not in letter_list:
#                 wrong.add(letter)
#         print("".join(guessed_word))
#     else:
#         print(f"End! Correct: {set(correct)} ({len(correct)})")
#         print(f"Wrong: {set(wrong)} {len(wrong)} | Total tries {tries}")


# guess_word_game("Oneliner-Challenge")

im clueless as to how i can modify tries or anything, nothing is propegating out of the function

humble rune
# earnest wing what kind of replace
x:x.replace("Green","G").replace("Red","R").replace("Blue","B").replace("Dark","D").replace("Light","L").replace("Medium","M").replace("White","W").replace("Grey","Y").replace("Gray","Y").replace("Turquoise","T")```
languid hare
#

issue is same as

x = 0
def set_x():
  x = 1
  print(x)
set_x() # 1
print(x) # 0
humble rune
languid hare
#

you could use a dict as ryuga said (making sure not to rebind the name of the dict, only changing its keys), or you could return tries from the function and set tries to the result

sick iris
wheat river
rugged sparrow
#

you can use an unbounded list comp to implement the while loops in the same scope without recursion

#
>>> (x:=[1])and[x.append(1)or(y:=len(x)) for _ in x if input() != 'end']
1
2
3
end
[2, 3, 4]
>>> y
4
>>> ```
#

iterate over a list with one item in it, and add an item if you don't want to exit the loop yet

#
f = lambda:(x:=[1])and[x.append(1)or(y:=len(x)) for _ in x if input() != 'end']and y
``` example in a lambda
wheat river
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

hello R G world
languid hare
#

neat

humble rune
upbeat sonnet
#

guise what exactly is time complexity and how to lower it

pastel sparrow
#

was just helping someone in a help channel and figured that this problem seemed pretty apt for golfing. i have no clue how to describe what it's supposed to do so here's some examples

"AaBb" -> ["AB", "Ab", "aB", "ab"]
"AaBbCc" -> ["ABC", "ABc", "AbC", "Abc", "aBC", "aBc", "abC", "abc"]
#

here was my attempt at golfing a solution: ```py
f=lambda i:["".join(a[int(c)]for a,c in zip([i[x:x+2]for x in range(0,len(i),2)],bin(j)[2:].zfill(len(i)//2)))for j in range(2**(len(i)//2))]

pastel sparrow
#

a kata?

#

it was in a biology context, those letters representing alleles

rose beacon
night quarryBOT
#

@rose beacon :white_check_mark: Your eval job has completed with return code 0.

['ABC', 'ABc', 'AbC', 'Abc', 'aBC', 'aBc', 'abC', 'abc']
severe canyon
night quarryBOT
#

:incoming_envelope: :ok_hand: applied mute to @smoky sleet until <t:1651795717:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).

quartz wave
#

shouldn't that always produce 0?

#

oh

#

2*a + (i//2**a % 2)

severe canyon
#

Yeah, somehow it gets parsed correctly without brackets

quartz wave
long hamlet
sick hound
unreal echo
#

yup, my confidence is now back down to healthy levels after viewing this channels posts, works great when you're overconfident

quartz wave
severe canyon
upbeat sonnet
#

whats golfing-

primal idol
#

Trying to tackle a problem in the least amount of characters possible

upbeat sonnet
#

ah

sick hound
#

write a function that prints some message without actually writing the message

#

maybe even write a generator that generates obfuscated python code to print messages

wheat river
#

!e

def foo():
    import __hello__

foo()```
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

Hello world!
sick hound
#

lol

rugged sparrow
#

!e py import this

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | The Zen of Python, by Tim Peters
002 | 
003 | Beautiful is better than ugly.
004 | Explicit is better than implicit.
005 | Simple is better than complex.
006 | Complex is better than complicated.
007 | Flat is better than nested.
008 | Sparse is better than dense.
009 | Readability counts.
010 | Special cases aren't special enough to break the rules.
011 | Although practicality beats purity.
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/pajolosuxo.txt?noredirect

crimson pumice
#

I don't fully remember, but is there anyway to modify the variables of a closure?

#
def a():
    var = None

    def b():
        return var
    return b

func = a()

What can I do with func() to get access to var?

rose beacon
#

doesn't func() call b which returns var to you?

#

oh modify the var. if you want to change what it refers to, there's no way short of messing with cpython internals via ctypes

crimson pumice
#

Okay, thanks! Good ๐Ÿ˜‹

rugged sparrow
night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

hacked
rugged sparrow
#

closures are stored in a tuple on the function object

crimson pumice
#

Thank you

#

I have to decide between closures, or mocks. Do you think closures are safer against tampering?

rugged sparrow
#

Either work

rose beacon
#

wwwwwwoah

sick iris
#

Has anyone managed to get the concept of returning early (for/while loops) in lambdas

#

I'm stuck on this, tried unittest assertRaises and assertTrue to propagate out but variable scopes as it's inside the function for assertRaises fucked me

#

Maybe I can use it like a ctx manager

#

If that even works

short crag
#

Anyway I can use semicolons in sets?

true=True;
class console:
    def log(self, value):
        print(value)

while (true):{
    console.log('hmm');
}
``` Tryin to do a cursed loop.
restive void
#

I don't think that's possible, "sadly"

#

(short of the usual transformative solutions like an import hook or a codec)

#

U+037E (GREEK QUESTION MARK), the only lookalike I can think of, is not a letter, otherwise you could do console.log('hmm').อพ

short crag
#

good idea, thanks!

rugged sparrow
#

#esoteric-python message this is an example of while loops in a lambda (it works by extending a list as you iterate over it)

#

You can do something similar to end a for loop early ( by clearing the list early inside the loop )

#

For while loops that work like the above example, you can just skip the extend call

quartz wave
#

like this

#

u back now?

long hamlet
rugged sparrow
# sick hound u can if u edit ctypes

even with ctypes it is near impossible to modify syntax because parsing happens before execution. The only way that would moderately work would be like this ```py

code to enable new syntax

import module_with_new_syntax

sick hound
#

if u do it there

rugged sparrow
#

the code to modify syntax would need to run before the altered syntax code is even parsed

#

so ```py
import code_that_changes_syntax

custom::code

verbal talon
#

So apparently the Python discord bot's eval has os.fork() which means you can spawn multiple processes from !eval. Unfortunately there are no temp files/named pipes as far as I'm aware so I came up with a hacky solution to get IPC: use POSIX signals (like from kill) to send bits from the child process to the parent process.

#

#bot-commands message

#

^ this spawns a child process, which then converts "Hello world!" to a stream of bits, and sends them to the parent as SIGUSR1 for 0 and SIGUSR2 for 1. Since POSIX signals are not ordered, the two processes do a little handshake where the parent acknowledges each bit, allowing the child to send the next bit.

granite flax
#

I saw this

#

I was staring at it for a good 10 seconds as it looked like something that should be here

verbal talon
#

I'm very pleased with this hack

#

You could legit use it to do a parallel foreach/map, a la multiprocessing

granite flax
verbal talon
#

!e

from lzma import decompress
from base64 import b64decode
c = """
/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AX/AixdADSbSme4Ujxz7TRXz/YuKYOoy6/+/qHJAf2Y
kZ+Tei44AMHe4K+pz733TFmzsTIcdIqSdrob3TqE6OQHmnicrKa0QXNEizjJI/dNNnU2VNgwoWus
bXAA0X9/Q9EDTGrHdCkznHbeu0AsJu136ugjEkcNnrPmMNmHQOsQSPVO6TEy4YVgFrJ63u9WghA+
DB3TpncfiQrGsBZhvi2/lFJOu+igl0404PDRkZtYDLVlWnMR+OFB8QYmA3DaqlWwAY8qPJIp3Dw0
adov/THThzICPCwTqzWaYizZnIAjiUYg5wubfXU9djlAHmMOEUfSWJtDsnang2WonnaLyZ039KSs
RGtFSRWRMDOtP2e4KfJvrRDAcgYZs9WW+Lpxuwx8lGMqVCdjeghIkF1tv5TAgQa3NVOSTxx1k6PC
ny/ZMJdrmhOsu+f8GAS99EV9PJq3UL5a78BLQlZ709srdnV0CPvv9YtLetC+iVY+F/B/YEodB7kj
x9opLF3qTp/VG9TFEEoCpc5b+x41rAz3i5PrqHF4v32mlaWU91O6BFXPwWXtWh0UAMTdnPDaUPpO
nkVW+vO61CQkVdLyuifR70ep0PGRDZJ4/kwcKRInlawkQ2C+Ag6A8RAFp12WkpecN2HpuTCcvyV0
zarwW/9iYM4g3cqpDCOSoqwkvB+edZDZAi4iNG25xnKS9dI5YBgt32zaRBiN6LlPK6XAt55TxYvB
UOMQryWj2qlJA10gfIMUtQAAw9BOqH1bJoMAAcgEgAwAAJuhLS+xxGf7AgAAAAAEWVo=
"""
exec(decompress(b64decode(c)).decode())
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Hello, world!๏ฟฝ
verbal talon
#

It's just self-extracting code in an eval. Problem?

#

๐Ÿ™‚

granite flax
verbal talon
granite flax
verbal talon
#

How much do you know about signals in Unix/Linux?

#

Have you written a signal handler?

granite flax
granite flax
verbal talon
#

Hmm, so this is a way that processes can communicate each other that something has happened or changed. e.g. kill process just sends the SIGTERM signal. The default behavior for programs is to exit when they get that

#

The two I use are SIGUSR1 and SIGUSR2 which are basically general purpose

#

Since these are asynchronous, you basically register a callback to handle each signal. When the kernel runs process again (say it's in the sleep part of the loop in my code) it will trigger the signal handlers in some order

#

These lines register the handler logic to both SIGUSR1 and SIGUSR2:

signal.signal(signal.SIGUSR1, handler)
signal.signal(signal.SIGUSR2, handler)
#

I do that before the call to os.fork() because after that, I don't know what order the code is going to run in (e.g. the child could finish and send its result before the parent has its handler registered)

granite flax
#

Okay

#

I'll pretend i understood that

verbal talon
#

Here's the proof. A monte carlo estimation of pi with one worker:

#

!e

import random
NUM_WORKERS=4
NUM_ITERATIONS=5000000
result = 0
for i in range(NUM_WORKERS * NUM_ITERATIONS):
  x, y = random.random(), random.random()
  if x * x + y * y < 1:
    result += 1
print(f"pi = {4 * result / (NUM_WORKERS * NUM_ITERATIONS)}")
night quarryBOT
#

@verbal talon :warning: Your eval job timed out or ran out of memory.

[No output]
verbal talon
#

With four worker processes:

golden finch
#

can you access a lambda within itself?

verbal talon
#

!e

from lzma import decompress
from base64 import b64decode
NUM_WORKERS=4
NUM_ITERATIONS=5000000
c = """
/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AtFBAFdADSbSme4Ujxz7TRXz/YuKYOoy6/+/qHJAf2Y
kaj5JrjpXHFk4VJJibh/QOHdouojmx1aK6zmJRS7b+EpB6qvEJ1G+Hy8HiQsVmGnx7C23YXKDeyL
X5YCU0I5Y323MFysA/os8HhUtcNjdHjKuvMVtNyNWUl8TOoxr3mrHUwul2kq+WmRIwxPWQAb4R/O
2X6CGHfKp4WbdRxY2jAWrcwbGsJSgLYzdskDM+e69b/p7Fm2puCipScVM+ncbZncUAu4gWuaq3Ez
ipu9VdHQgGin9PPPMBMRfJU4wgN/p6UJpA9iwdxhZp62MQRkYX3Zdh8gtYwS8iMbJ9EwIdAkppul
7cF3LS+j0RIUJQYYSVwa0ddq7XuWux7myKphLqIbWNW9MNkle8ZomHvIcCa2QsZJmj9FASkF/HKm
eOUlUXZRQq5lSlyoSURpB5Xp/4K0+RcbJ+sQyoLhFencaVcBnMbny3LFuSxKoSJ3PrJNh9Avn+yI
HrCYEy1FPsCRi8l/TWKdzkblOwYgTzgR8piLzuewdM3v97zf2jFTNjAI8iuCZRkMQlflbzD8c6LR
WUOOnRYb9u/PaBW1W0F48VuZ9pVKM6sJbX1fB58IClxqx0ob/C8ugtNmbiqqqpINzpITRlMnhemo
7h1pJtFjgR/k13O705ClamLwPNLxObFWv0BuwQyetFO53ujzCWDPZfDvQoq3X5fMGKTkYZ5++S2F
VB7vCBXjxvW6B1teasm12ljGUu4S9GQAk0KA/g6zrBSPd2eRaDOYRRjeeMw08e/sJfMAYImACGGA
nWi32+Zk5yudIF1HXJYQ3ul2AHudqEs0ongOS4SnZggwG06v4eIzNTt3LNVLdll2/mAhLr359GKy
f4Te6RhHoYNBFaALO/5e9h6HL9cemawAL310syEpcRSeqs6zCNdmrmUaIuFJ2YPNrI15ZSRromXF
SOUIq1NfBw/ra+etxzwlCM76BEyd6WnoXiVwodYANH3hBUgY56LMti6dWG70EGXtiAfqw1LIEC0I
pLzjtuQ9d/ok1U1xPKLXPbjUyObdok0DU3yeQ5FGvLy0Z7YKFdSgl9sIzR3cxB9PRVnZk3DIOtA7
/DYg67V4NOoh8q9wGpgcttfhOJ5ZfLu7dMLk3e8dztorijQMUv9QEYLsFVr6GRvC7oZu4qaChTFp
iO71fR9VFn3nUQdB8lvSMCHr9tuai4Vjodp7MZR+aswUsEmEgWk2ZKMTZwklNyCW3+RsGNAM5NWh
uXVdlzQ6zSBGMM08po8Q2LAhkkhZhXspQgC7IqUDQBzyslgmWAaKEn9S0BI73NKFNUaaKooF8bx3
oUQo5RNYcMxXqUfSdQ8DbtVXUT8LYdnRCY6RuE8LAAAAAPJuudUoMDr0AAGdCMYWAACZ9FAZscRn
+wIAAAAABFla
"""
exec(decompress(b64decode(c)).decode())
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Num processes: 4, total iterations: 20000000, pi ~= 3.14113
golden finch
#
lambda:__import__('sys')._getframe().f_code

wait what

#

you can just do that

#

Is there a way to do that without imports?

verbal talon
#

Hmm, could you pass the lambda to itself?

def fix(f):
  return f(f)

fix(lambda f: f(f))
golden finch
#

You could, but that's cheating

severe canyon
#

!e ```py
f=lambda:f.code.co_code
print(f())

import dis
print(dis.dis(f))

night quarryBOT
#

@severe canyon :white_check_mark: Your eval job has completed with return code 0.

001 | b't\x00j\x01j\x02S\x00'
002 |   1           0 LOAD_GLOBAL              0 (f)
003 |               2 LOAD_ATTR                1 (__code__)
004 |               4 LOAD_ATTR                2 (co_code)
005 |               6 RETURN_VALUE
006 | None
severe canyon
#

along the lines of this?

earnest wing
golden finch
#

A what?

#
fib_lambda=lambda n,cache={0:0,1:1}:(f:=type(lambda:0)(__import__('sys')._getframe().f_code,globals()),a:=cache[n-1] if n-1 in cache else f(n-1,cache),b:=cache[n-2] if n-2 in cache else f(n-2,cache),cache.__setitem__(n,a+b),a+b)[-1]

I made this PoC

sick hound
golden finch
#

I have just been immensely outgolfed in the esolangs server

#

I was not aware of the ฮฉ combinator

sick hound
#
fact = lambda n: n*fact(n-1) if n > 1 else 1```
#
fact = lambda self, n: n*self(self, n-1) if n > 1 else 1```
#
a = fact
fact = lambda n: a(a, n)
quartz wave
#
f=lambda n:n<2or n*f(n-1)
``` immensely golfed
quartz wave
long hamlet
sick iris
#

-e ```py
(lambda: (
[
(a := 1, ret_val := a, (_ for _ in "").throw(StopIteration)) for _ in ""
],
ret_val
)[-1])()

im trying conditional returning early in oneline (expanded for viewing here) but im stuck on the 3.7 behaviour of wrapping `StopIteration` in a `RuntimeError`
#

using next with a generator has no luck either

pastel sparrow
#

oh, i thought about something like this before

#

my approach was to use any

#

not sure if it helps you here

sick iris
#

might do, thank you

#

unsure as to how i would conditionally return a value with that

pastel sparrow
#

yeah, didn't think that far hm

sick iris
#

i could always catch an error raised from it, that gets quite long though

pastel sparrow
#

have a return value + a temp value that indicates if the loop was returned early?

sick iris
#

-e ```py
print((lambda: (
any((
(ret := True, ret_val := None, a := 1, ret_val := a, ret := True, ret)[-1] for _ in "_"
)),
ret_val
)[-1])())

#

this is an awful example for what im using this for but this might work

pastel sparrow
#

!e ```py
print((lambda: (
any((
(ret := True, ret_val := None, a := 1, ret_val := a, ret := True, ret)[-1] for _ in "_"
)),
ret_val
)[-1])())

night quarryBOT
#

@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.

1
sick iris
#

nice

pastel sparrow
#

are you trying to turn any python file into one-liners ๐Ÿ‘€

sick iris
#

maybe

#

im way far off for and while loops but i keep thinking so far

#

and, ive got this

#

!e ```py
(func := lambda a: (
any(
(
(
ret := False,
ret_val := None,
print(f"{i=}"),
(
ret := True,
ret_val := i
) if a and i == 1 else (),
ret
)[-1] for i in range(5)
)
),
ret_val
)[-1]),
print(func(True))
print(func(False))

night quarryBOT
#

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

001 | i=0
002 | i=1
003 | 1
004 | i=0
005 | i=1
006 | i=2
007 | i=3
008 | i=4
009 | None
sick iris
#

which, works as intended

#

!!!

#

conditional return in a for loop, which may also be a while loop

#

of course, this can go to

#

!e ```py
(func := lambda a:(any(((ret:=False,ret_val:=None,print(f"{i=}"),(ret:=True,ret_val:=i)if a and i==1 else(),ret)[-1]for i in range(5))),ret_val)[-1],print(func(True)),print(func(False)))

night quarryBOT
#

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

001 | i=0
002 | i=1
003 | 1
004 | i=0
005 | i=1
006 | i=2
007 | i=3
008 | i=4
009 | None
pastel sparrow
#

i tried doing that, but got stuck at assignments

pastel sparrow
pastel sparrow
sick iris
#

i mayyyy or may not be using libcst, full programmatic conversion

#

intended for just a library i work on rn but the hope is for it to work with any sane library that doesnt do immense amount of magic

pastel sparrow
short crag
#

Anyone know of a article/guide on to converting code into true one liners?

#

I know of the one line loops, if else etc just not sure how to apply them into a true one liner

short crag
#

Actually I think I got it down

#

Heres a messy one line of rock/paper/scissors

(lambda:(print(((f'Won: {_} beats {__}'if(not(___[_]==__))else(f'Lost: {__} beats {_}'))if(not(_==__))else(f'Tie: {_} is {__}'))if((_:=input('Move: '))and(__:=__import__('random').choice(['rock','paper','scissors']))and(___:={'rock':'paper','paper':'scissors','scissors':'rock'}))else('Invalid input..'))))()
verbal talon
#

Love it

#

!e

exec(__import__('lzma').decompress(__import__('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo=")).decode())
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Hello, world!
verbal talon
short crag
verbal talon
#

!e

(lambda i: exec(i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo="))))(__import__)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Hello, world!
verbal talon
#

I think this is my new pattern for pasting in LZMA-compressed code

short crag
short crag
verbal talon
#

In some cases I've written more code than can reasonably be pasted into a code block here haha

short crag
#

ah, gotcha

verbal talon
#

Like my crazy multi-process monte carlo thing I wrote last night

short crag
#

nice nice

verbal talon
#

I also like that you can change the exec to a print to just get the code itself:

#

!e

(lambda i: print(i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo="))))(__import__)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

b'print("Hello, world!")\n'
short crag
#

oh sweet

#

how do you compress the code?

verbal talon
#

I use the xz utility: xz < foo.py | base64 -w0

short crag
#

oh, I see. seems useful

#

now im confused by something

verbal talon
#

Oh?

short crag
#

if I do:

def test():
    return 'r'

test.ok = lambda: 'rrr'
print(test.ok)

x = lambda:'x'
x.x = lambda: 'xxx'
print(x.x)
``` I am allowed to add attributes to them
#

but if I do it with regular types:

x = 2
x.two = lambda:'222'
print(x.two)
``` I get a attribute error
#

AttributeError: 'int' object has no attribute 'two'

#

now these all are classes of their type

verbal talon
#

!e

class Foo():
    pass

f = Foo()
f.x = lambda: 'x'
print(f.x())
short crag
#

so shouldnt it work the same?

night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

x
verbal talon
#

idk why it's different for int. To be honest I'm surprised you're allowed to add arbitrary attributes to functions?

short crag
#

yeah its weird

#

ints, strings and regular data types throw a attribute error

verbal talon
#

Hmm

#

I have a weird idea

#

Can you use this to make f.g represent function composition

short crag
#

!e

z = lambda:print('test')
z.z = lambda:print('ok')
z.z()

x = [1, 2]
x.two = lambda:print(2)
x.two()
verbal talon
#

How do you override the behavior of foo.a in general, for all a?

#

I forget

short crag
vestal solstice
#

getattribute

#

would be called something like that

verbal talon
#

That's the one

#

Thanks

vestal solstice
#

!e

class f:
  def __setattr__(x,y,z):
    print("python's closed")
h = f()
h.val = 14
night quarryBOT
#

@vestal solstice :white_check_mark: Your eval job has completed with return code 0.

python's closed
verbal talon
#

ty

#

Okay brb trying this

short crag
#

so I am assuming, with regular variable data types they have a raise put in there for that method

verbal talon
#

!e

f = lambda x: x
f.__getattr__ = lambda s, name: name
f.x
night quarryBOT
#

@verbal talon :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 3, in <module>
003 | AttributeError: 'function' object has no attribute 'x'
short crag
#

!e

class new_int(int):
  def __setattr__(self, name, value):
    raise Exception('Error...')

x = new_int(5)
x.two = 2
print(x.two)
night quarryBOT
#

@short crag :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 6, in <module>
003 |   File "<string>", line 3, in __setattr__
004 | Exception: Error...
verbal talon
#

I'm trying to avoid creating a wrapper class for function haha

short crag
#

I see

#

hmm

verbal talon
#

I mean I guess it's possible with a wrapper

short crag
#

!e

class test(int):
  def __getattr__(self, name):
    return 'Test..'

x = test(2)
print(x.two)
night quarryBOT
#

@short crag :white_check_mark: Your eval job has completed with return code 0.

Test..
short crag
#

!e

def x():
  return 'x'

x.__getattr__ = lambda self, name: 'Test..'
print(x.two)
night quarryBOT
#

@short crag :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 5, in <module>
003 | AttributeError: 'function' object has no attribute 'two'
short crag
#

looks like you cant override it without wrapping the type?

verbal talon
#

Hmm it's interesting that this works:

#

!e

class Foo():
    pass

f = Foo()
f.__getattribute__ = lambda s, name: name
print(f.x)
night quarryBOT
#

@verbal talon :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 6, in <module>
003 | AttributeError: 'Foo' object has no attribute 'x'
verbal talon
#

Wait one sec...

short crag
#

lol

verbal talon
#

Oh it only worked in my other session because I had already defined __getattr__ in the class, nvm

#

!e
print(dir(lambda x: x))

night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

['__annotations__', '__builtins__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
short crag
#

getattribute

#

looks to be spelt diff?

verbal talon
#

I've tried overriding both on function though and it doesn't seem to get called.

short crag
#

fuck

#

idk

#

this is weird

verbal talon
#

Yeah I'm a bit stumped here too

#

It looks like function has a __getattribute__ but setting it to something else doesn't change anything

short crag
#

confusing

magic wraith
#

__getattribute__ is dangerous and in most cases you only want to override getattr

verbal talon
#

@magic wraith in this channel we like to live dangerously

magic wraith
#

(what if you access attributes inside the getattribute? nice recursion lel)

#

lmao ik

short crag
verbal talon
#

With a minifier + LZMA I can get the eval block pretty small

#

!e

exec((lambda i: i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4ASMAo1dACsPRodj/gB+nUa8nWwC2g+4QUdgxFlAPCgO71ujypqzwh+cdGdBER97T6HlEk9cyiyQ9wITsd3Wp5ax2GtOHr0LWY2yzDWmvVWXLyiaG2W1xugCOIsPjsfRhaRtU2EWjJpNYA53k1x9ZrZuvguHB8xYqkVQADOPWU4PTYUBN+G/7iQdQfgjkT9nA3ooWiLVtlY22YoEW5ZZXHX1gXHNe/qKNVBlhAgNNAzwceSk2Zcn2eBG9Ckw+IA0s3cSZr0bTskNY7oPcBnfHI7w11298MCowr16eoZuWFhDgEaH14TStDLfiZzdj2A8fGK2qNrJSs1x5WumaWclm6FesfIae/InIsOkJbl5HXjzD6FZ1r9QeJpTdvcJez9QbqRRxXpGI+t1thYlEJRGxbMFFSd1efXYwKaKMCrnBG/BbIGj82tyOn4fqy2iBWMVMoMYrOGUF7FQWOmcnmqPSU9+4qHkfJLbkZWV2ntYKd/uHQjxW/IQ3h+P63keT8Mw8QRx9cbyTXFSL3wAsWfm9ZbI0gj15iFKaKB6B5mU5edgS88TNxzJhV5n9hxkQtwR16I4BscXg/fqeRy0UkpGRAKSg8Fddnt5ApPxQEv4rsaRx0Lztd5JeqrwCStI1OCbDMJ5cmthsmb/Pr14RNoeYffS4GFtXH+b8r2qgE8UBFJBeMKkppUQI/kgaChoTZwEnmORxZZAVVvb6n5mcJEp+mJeZGmDbTnqjYBEyirmttHoaicTxY5Ut8rRqEaPsV07nI8xovqJxm/ms3z7Jo08KPMEBgR2NYrDeDthgL/F0BP0QZ7tUdoNHiDFa13d1tvpPmG6ZwOhCGG0G5yjeQr/2OOVxP85b3APp3OvUH+QYcGwD0KKAAAAAM0wtZ5r1yNkAAGpBY0JAADiTkQlscRn+wIAAAAABFla")))(__import__))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Num processes: 4, total iterations: 20000000, pi ~= 3.1412286
verbal talon
#

I think that's fun, you can fit some fairly complex programs

short crag
#

huh thats neat

verbal talon
#

I bet with unicode characters instead of just base64, you could pack a LOT more bits into the text block

verbal talon
#

!e

fib = lambda n: (lambda f: f(f, 0, 1, n))(lambda f, a, b, n: f(f, b, a + b, n - 1) if n > 0 else a)
print(fib(100))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

354224848179261915075
verbal talon
#

Not sure if you can do while-loops in an expression some other way?

#

!e

print([(lambda n: (lambda f: f(f, 0, 1, n))(lambda f, a, b, n: f(f, b, a + b, n - 1) if n > 0 else a))(n) for n in range(10)])
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
short crag
#

!e

x = 2
print(x.__dir__())
night quarryBOT
#

@short crag :white_check_mark: Your eval job has completed with return code 0.

['__new__', '__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__add__', '__radd__', '__sub__', '__rsub__', '__mul__', '__rmul__', '__mod__', '__rmod__', '__divmod__', '__rdivmod__', '__pow__', '__rpow__', '__neg__', '__pos__', '__abs__', '__bool__', '__invert__', '__lshift__', '__rlshift__', '__rshift__', '__rrshift__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__int__', '__float__', '__floordiv__', '__rfloordiv__', '__truediv__', '__rtruediv__', '__index__', 'conjugate', 'bit_length', 'bit_count', 'to_bytes', 'from_bytes', 'as_integer_ratio', '__trunc__', '__floor__', '__ceil__', '__round__', '__getnewargs__', '__format__', '__sizeof__', 'real', 'imag', 'numerator', 'denominator', '__doc__', '__str__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__dir__', '__class__']
short crag
#
class int(int):
    def __setattr__(self, name, value):
        confirm = input(f"Are you sure you wanna set {name} to {value} for type {type(self).__name__}(y\\n) ")
        if confirm == 'y':
            return super().__setattr__(name, value)
        raise AttributeError('Attribute not accepted!')
``` Imagine python had you confirm everything you did in the code
worldly yew
#

Greetings, I am having issues implementing some functions from the cfgmgr32 API on Windows.

Currently, I'm attempting to receive a pointer instance of a device based on its pDeviceID, however, whenever I attempt to convert it into anything that's a pointer, it returns CR_INVALID_POINTER, so I'm currently confused on how I'd be able to convert a regular string to a null-terminated one, and obtain a valid pointer of that.

Here's my current code:

import ctypes

cfgmgr = ctypes.WinDLL("cfgmgr32.dll")

# Let's try to obtain this mouse:
#    HID\VID_0B05&PID_18AA&MI_02&COL06\7&2C012244&0&0005

CM_Locate_DevNodeA = cfgmgr.CM_Locate_DevNodeA
CM_Get_DevNode_Property_Keys = cfgmgr.CM_Get_DevNode_Property_Keys

pdnDevInst = ctypes.c_void_p()
pDeviceID = ctypes.c_char_p(
    "HID\\VID_0B05&PID_18AA&MI_02&COL06\\7&2C012244&0&0005".encode("UTF-8"))

if CM_Locate_DevNodeA(
    pdnDevInst,
    pDeviceID,
    ctypes.c_ulong(0),
) != 0:
    print("ERROR") # It reaches here each time

else:
    print(pdnDevInst)

Here's the documentation I'm referencing:
https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_locate_devnodea

short crag
rapid sparrow
#

hmm.. is that c_ulong supposed to be a pointer to memory

worldly yew
#

I don't think so

#

It's merely a flag argument

verbal talon
#

@short crag so if I'm reading this right, it assigns the globals() dict to __annotations__ so that when you do x:2 it adds it to the annotations collection, making it a global variable?

rapid sparrow
#

what if you do

pdnDevInst = c_ulong()```
then in the call use
```py
ctypes.byref(pdnDevInst)```
worldly yew
#

Although I'm not sure if it's a valid result returned - it's ulong(1)

#

I wonder if that's the index to its relative path in the device tree

#

Hm, it shouldn't be though

#

A pointer to a device instance handle that CM_Locate_DevNode retrieves. The retrieved handle is bound to the local machine.

short crag
#

I havent experimented around with it, but I think:

globals(), __annotations__ = __annotations__, globals()
``` should swap them entirely(**not sure**)
#

@verbal talon

verbal talon
#

hahahahaha

#

Wait, can that be right? Can globals() be on the left hand side like that?

short crag
#

ยฏ_(ใƒ„)_/ยฏ

verbal talon
#

__globals__ right?

short crag
#

hmm

#

__globals__ isnt defined

#

TypeError: 'builtin_function_or_method' object does not support item assignment

__annotations__, globals = globals, __annotations__

x:2
print(x)
``` @verbal talon looks like we cant do this, sadly.
#

though

verbal talon
#

globals() is mutable itself tho

#

Could swap the elements

short crag
#

just using __annotations__ = globals() causes weirdness

#

the annotations take higher priority when making a variable

short crag
#

!e

__annotations__ = globals()
x: 2 = 4
print(x)
y: 4
print(y)
z = 6
print(z)
night quarryBOT
#

@short crag :white_check_mark: Your eval job has completed with return code 0.

001 | 2
002 | 4
003 | 6
rapid sparrow
short crag
verbal talon
#

!e

x: 2 = 4
y: 4
z = 6

tmp = __annotations__
__annotations__ = globals()
for k in tmp:
  globals()[k] = tmp[k]

print(x)
print(y)
print(z)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

001 | 2
002 | 4
003 | 6
worldly yew
languid hare
#

it's actually a cool way to be explicit with global vs local variables

#

= is local, : is global

short crag
#

oh shit

#

thats actually smart

verbal talon
#

that is cool

#

What do we use for types now lol

short crag
#

it would be confusing if you didn't know what that one line did, but otherwise it could be useful.

rapid sparrow
short crag
#
#HERE X IS ACTUALLY A INT SORRY
x: 2
verbal talon
#

okay... doc strings are for type annotations, : annotations are for global variables, and globals are for local variables

#

This should clear it up for beginners

short crag
#

we are gonna invent our own pep guide

verbal talon
#

pep420

worldly yew
short crag
#

lol

verbal talon
#

oh that exists already lol

verbal talon
short crag
#

fyi you can do:

open(1, 'w').write('stuff')
``` to print
and
```py
open(0, 'r').readline(1)
``` for input in a more cursed manner
verbal talon
#

oh interesting, Python is sometimes surprisingly C-like

languid hare
#

i forgot to .close on 0, keyboard privileges revoked

short crag
#

I mean its only built on C

verbal talon
#

Sure but I mean, there's no reason that Python itself has to treat ints as file handles

short crag
short crag
worldly yew
#

Hm, does None act similarly to C's NULL when using ctypes?

#

Because I'm getting CR_INVALID_POINTER when I pass None

short crag
#

!e

function = type
main = function("main", (), {'__init__': lambda self, x, y:{print(x+y)}and None})
main(1, 2)
``` @verbal talon cursed way of making a function
night quarryBOT
#

@short crag :white_check_mark: Your eval job has completed with return code 0.

3
verbal talon
#

Hmm, there needs to be a wiki

short crag
#

lmao

verbal talon
#

@short crag do you know if there is a way to put while loops in one-liners?

short crag
#

one line while loop

#

hmm

verbal talon
#

I guess I could define a while loop function using exec

#

And then use that in the rest of my one-liner

short crag
#

hmm

#

wait

#

I think I got a idea

#

act nvm

languid hare
#

you could make an infinite for loop then comprehension over that

short crag
#

any(print(i) for i in range(9999999))

languid hare
#

9999999 is basically infinity

short crag
#

basically

rapid sparrow
short crag
#

thank god python is slow

verbal talon
#

!e

any(print(i) for i in __import__('itertools').count(0))
night quarryBOT
#

@verbal talon :x: Your eval job has completed with return code 143 (SIGTERM).

001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
007 | 6
008 | 7
009 | 8
010 | 9
011 | 10
... (truncated - too many lines)

Full output: too long to upload

rapid sparrow
#

A are ascii functions and W are wide char functions?

worldly yew
#

Seems to be working fine now lol - just have to figure out how I'd allocate the property keys appropriately

old socket
verbal talon
#

!e

any(print(i) if i <= 5 else True for i in __import__('itertools').count(0))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
verbal talon
#

Ah I see, any lets you bail out early

verbal talon
old socket
# verbal talon Can you explain what you mean?

An example from cpython docs of iter, py from functools import partial with open('mydata.db', 'rb') as f: for block in iter(partial(f.read, 64), b''): process_block(block) here, basically iter calls the partial until it returns b'' here, the sentienl object

#

It shouldn't be to hard to utilise this in a one-liner inside of a lambda

worldly yew
# rapid sparrow oh ok <:ok_handbutflipped:779364331350523909>

Although I am interested how I'd replicate a "buffer array of a struct"

Say I have a struct like this:

struct DEVPROPKEY {
  DEVPROPGUID fmtid;
  DEVPROPID   pid;
};

how would I translate this over to Python using ctypes and create a buffer arr of this type?

languid hare
#

!e

for i in iter(int, 1):
  print(i)
night quarryBOT
#

@languid hare :x: Your eval job has completed with return code 143 (SIGTERM).

001 | 0
002 | 0
003 | 0
004 | 0
005 | 0
006 | 0
007 | 0
008 | 0
009 | 0
010 | 0
011 | 0
... (truncated - too many lines)

Full output: too long to upload

languid hare
#

looks good

verbal talon
languid hare
#

i was almost about to suggest the lambda calc way ๐Ÿฅด

#

no omega combinator for you

short crag
old socket
#

lambda and calc, the two things I hate the most

#

well, at least a very rocky relationship

verbal talon
#

!e

from itertools import islice

def get_iterator():
    x = 0
    def next():
        nonlocal x
        x += 1
        return x - 1
    return iter(next, None)

for i in islice(get_iterator(), 0, 10):
    print(i)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
007 | 6
008 | 7
009 | 8
010 | 9
short crag
#

([_:=(...)],[__:=({_}|{_})]) I love this expression lol

verbal talon
short crag
old socket
#

({}|{})

worldly yew
#

Hmph. I'm a little stuck.

Say I had a structure called DEVPROPKEY, how would I define a buffer of an array accepting DEVPROPKEY-typed items?

Here's what the structure looks like, if relevant:

class DEVPROPKEY(Structure):
    _fields_ = [
        ("fmtid", c_void_p),
        ("pid", c_void_p)
    ]
verbal talon
#

!e

(lambda N, r: print(f"pi ~= {sum(4 if (lambda x, y: x * x + y * y < 1)(r(),r()) else 0 for i in range(N))/N}"))(1000000, __import__('random').random)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

pi ~= 3.141396
worldly yew
#

This is where I'm currently stuck:

    buf = c_buffer(b"", sizeof(DEVPROPKEY) * 256)
    count = c_ulonglong(0)

    stat = CM_Get_DevNode_Property_Keys(
        pdnDevInst,
        buf,
        byref(count),
        c_ulong(0)
    )

    if stat != 0x0:
        print("STATUS #2: " + str(stat))
        print(buf, buf.value, count)
    else:
        print(buf, buf.value, count)

The stat value is 0x1A, which is, CR_BUFFER_SMALL - I must've declared the DEVPROPKEY structure improperly.

short crag
#
lambda _:(__)if(any(('...'if(__:=False)else'...'if((_) %___==0)else'...' if(__:=True)else'...')for(___)in(range(2, _)))if((__:=True)and(_) >0)else('...'if(__:=False)else'...'))else(__)
``` Can't be bothered to test it more, or clean up the shitty code. but I think its a working prime checker.
verbal talon
#

I'm actually trying to convert a Sieve of Eratosthenes implementation to a one liner

short crag
#

ooh

#

nice

verbal talon
#

!e

a = [*range(100)]
a[0] := 1
night quarryBOT
#

@verbal talon :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     a[0] := 1
003 |     ^^^^
004 | SyntaxError: cannot use assignment expressions with subscript
verbal talon
#

Running into a hitch though, can't assign into my array as an expression

short crag
#

hmm

#

I see

verbal talon
#

Hmm the algorithm is usually implemented as an array

#

What else did you have in mind?

#

It seems like only variables support := right?

#

Hmm for now I'm going to ignore this and do my old trick of "take in the solution to the problem as a parameter"

short crag
#

!e

stuff = {1: '1'}
stuff[1] := '2'
night quarryBOT
#

@short crag :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     stuff[1] := '2'
003 |     ^^^^^^^^
004 | SyntaxError: cannot use assignment expressions with subscript
short crag
#

nope

#

fuck u python

quartz wave
#

you can always do .__setitem__()

verbal talon
#

!e

def s(a, i, v): a[i] = v
print((lambda N, s: (lambda arr: (any(any(s(arr, j, False) for j in range(2 * i + 2, N, i + 2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100, s))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
verbal talon
#

!e

print((lambda N,s:(lambda arr: (any(any(s(arr,j,False) for j in range(2*i+2, N, i+2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100, lambda a,i,v:a.__setitem__(i, v)))
short crag
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
verbal talon
#

Got it

#

Okay I think this is cleaned up a bit:

#

!e

print((lambda N:(lambda arr: (any(any(arr.__setitem__(j,False) for j in range(2*i+2,N,i+2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
verbal talon
#

I should also change it to iterate only up to math.sqrt(N)

quartz wave
#

!e ```py
print([2,3,5,7,*(i for i in range(2,100)if all((i%6in(1,5),i%5,i%7)))])

night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
short crag
#

lol

verbal talon
#

Hah now do 1000

quartz wave
#

!e ```py
print([2,3,5,7,*(i for i in range(2,1000)if all((i%6in(1,5),i%5,i%7)))])

night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139, 143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209, 211, 221, 223, 227, 229, 233, 239, 241, 247, 251, 253, 257, 263, 269, 271, 277, 281, 283, 289, 293, 299, 307, 311, 313, 317, 319, 323, 331, 337, 341, 347, 349, 353, 359, 361, 367, 373, 377, 379, 383, 389, 391, 397, 401, 403, 407, 409, 419, 421, 431, 433, 437, 439, 443, 449, 451, 457, 461, 463, 467, 473, 479, 481, 487, 491, 493, 499, 503, 509, 517, 521, 523, 527, 529, 533, 541, 547, 551, 557, 559, 563, 569, 571, 577, 583, 587, 589, 593, 599, 601, 607, 611, 613, 617, 619, 629, 631, 641, 643, 647, 649, 653, 659, 661, 667, 671, 673, 677, 683, 689, 691, 697, 701, 703, 709, 713, 719, 727, 731, 733, 737, 739, 743, 751, 757, 761, 767, 769, 773, 779, 781, 787, 793, 797, 799, 803, 809, 811, 817, 821, 823, 827, 829, 839, 841, 851, 853, 857, 859, 863, 869, 871, 877, 881, 883
... (truncated - too long)

Full output: https://paste.pythondiscord.com/aleseyiyab.txt?noredirect

quartz wave
#

correct?

verbal talon
#

lol

short crag
#

my prime number code is giving me 5 errors bruh

quartz wave
verbal talon
#

!e

print((lambda N:(lambda a: (any(any(a.__setitem__(j,0) for j in range(2*i+2,N-1,i+2)) for i in range(__import__('math').isqrt(N)-1)), [i+2 for i in range(N-1) if a[i]]))([1 for i in range(N-1)])[1])(1000))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
verbal talon
#

Hmm those all look like numbers to me. Most of them odd, too.

short crag
rapid sparrow
short crag
rapid sparrow
#

mission accomplished incident_actioned

flint hollow
verbal talon
flint hollow
verbal talon
#

ah yeah

short crag
#

@umbral heron youll like this place

umbral heron
short crag
#

i wanna compress something into 1 line but ik im tired and fuck it up greatly

short crag
#

idk

#

1 line disc bot

#
discord_bot = (lambda: client.run('TOKEN') if(client:=__import__('discord.ext', fromlist=['commands']).commands.Bot(command_prefix='!', intents=__import__('discord.ext').Intents.all())) else '...')()
``` Got this so far @umbral heron
#

just need to a ping command

umbral heron
short crag
#

it uses decorators

#
@client.command()
async def ping(ctx):
  await ctx.send('Pong!')
``` @umbral heron
#

I gotta compress those 3 lines into 1

umbral heron
#

not sure if that's even possable

short crag
#

im gonna try

sick hound
#

!e
2="sa"
print(2)

#

!e
A="s"
print (A)

#

!e
A="s"
print (A)

#

!e
def exercise53(capital, interest_rate, target):
year =
while capital < target:
year =
capital =
print("La premiรจre annรฉe oรน son capital a dรฉpassรฉ", target ......,"est :", ......)

#

!e

!e
import random

print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))

night quarryBOT
#

@sick hound :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     !e
003 |     ^
004 | SyntaxError: invalid syntax
sick hound
#

!e
!e
import random

print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))

night quarryBOT
#

@sick hound :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     !e
003 |     ^
004 | SyntaxError: invalid syntax
sick hound
#

!e
import random

print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))

night quarryBOT
#

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

001 | B
002 | ['B']
wheat river
short crag
#
discord_bot = (lambda: (client.run('TOKEN') or client.command()(ping)) if(ping:=lambda ctx: ctx.send('test'), client:=__import__('discord.ext', fromlist=['commands']).commands.Bot(command_prefix='!', intents=__import__('discord.ext').Intents.all())) else '...')()
``` So I am trying this, the bot runs and everything is fine. but its not reccognizing my ping command
sick hound
#

!e
_2="s"
print (_2)

night quarryBOT
#

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

s
short crag
short crag
#

its ok

sick hound
#

easier way of ''.join(str(x) for x in []) ?

#

please ping on reply

wheat river
sick hound
short crag
wheat river
short crag
#

ah, gotcha. Thanks.

#

wonder why we dont have async lambdas Thonk

#

async lambda ctx: await ctx.send('I am async') would be so much better

wheat river
#

it doesn't really makes sense to have it

#

why would someone ever use it (except here)

short crag
#

true, but arent lambdas handled the same way as (regular)functions? So couldnt they just add the check if its lambda or def after async?

worldly yew
#

welp

#

I've started segfaulting

#

I've reached a new low

quartz wave
upbeat sonnet
quartz wave
#
>>> foo = async lambda a: await a
>>> foo
<function <lambda> at 0x0000026846595BD0>
>>> async def bar(a):
...     return await a
... 
>>> from dis import dis
>>> dis(bar)
  1           0 RETURN_GENERATOR
              2 POP_TOP
              4 RESUME                            0

  2           6 LOAD_FAST                         0 (a)
              8 GET_AWAITABLE                     0
             10 LOAD_CONST                        0 (None)
        >>   12 SEND                              3 (to 20)
             14 YIELD_VALUE
             16 RESUME                            3
             18 JUMP_BACKWARD_NO_INTERRUPT        4 (to 12)
        >>   20 RETURN_VALUE
>>> dis(foo)
  1           0 RETURN_GENERATOR
              2 POP_TOP
              4 RESUME                            0
              6 LOAD_FAST                         0 (a)
              8 GET_AWAITABLE                     0
             10 LOAD_CONST                        0 (None)
        >>   12 SEND                              3 (to 20)
             14 YIELD_VALUE
             16 RESUME                            3
             18 JUMP_BACKWARD_NO_INTERRUPT        4 (to 12)
        >>   20 RETURN_VALUE
>>> baz = async lambda: 5
>>> main = async lambda: await foo(bar(baz()))
>>> from asyncio import run
>>> run(main())
5
#

implemented async lambda

upbeat sonnet
#

fire

quartz wave
pastel sparrow
#

:0 found someone else who tried doing it

earnest wing
#

I know this isn't technically esoteric python per se, but is anyone interested in esoteric versioning schemes?

#

Semver is pretty boring, it would be much more exciting to publish version {{{}}{}} of your ctypes-heckery library...

magic wraith
# umbral heron not sure if that's even possable

Its possible but you have to look into the decorator function source code and just copy paste it to get rid of the decorator , instead of it you would have another function that you call with the ping function as first argument

short crag
#

Anything is possible as long as it isn't a syntax error :)

maiden vine
#

Heya esoteric people

#

Question for you

#

I'm writing a library to enforce privacy and type annotations at runtime

#

So far so good!

#

The syntax looks a bit like this...

languid hare
maiden vine
#
from <library> import Object
from <library> import Attribute

class ThingWithPrivateAttributes(Object):
    
  private  = Attribute(int,  access=False)
  readonly = Attribute(str,  access=None)
  public   = Attribute(bool, access=True)

  def __init__(self, arg1: int, arg2: str, arg3: bool) -> None:

    self.private  = arg1
    self.readonly = arg2
    self.public   = arg3
#

And then a bunch of descriptor magic takes over

#

Cool! So here's my question

#

With a normal object, which has no attributes of its own by default, it makes sense to just throw an error if someone tries to set an attribute on the object that doesn't have a corresponding Attribute descriptor declared in the class

#

But if I extend this to class attributes, well, things get uglier

#

Classes have lots of attributes by default. __name__, __bases__, __itemsize__ โ€” some of them quite general use, others yucky implementation details

#

What do I do about setting an attribute on a class that enabled with this privacy-and-enforcement protocol if that attribute is something other than an attribute explicitly delcared using the library

restive void
#

You can define __name__ on the metaclass, and do whatever you want with it there (e.g. make it a property). But I hope it's clear to you that your library is esoteric indeed, unpythonic, and can't possibly truly work.

maiden vine
#

You'd have to gut the language like a fish and rebuild it pretty much from scratch to do it properly

#

They goal, though, well its two fold

#

Its a good demonstration of where my abilities stand with python and hence, a good portfolio piece

#

And beyond that, it isn't about installing privacy in the traditional sense so much as in the philosophical sense. Privacy != security. Its meant be an unambiguous Berlin-Wall between the public and private APIs which is nontrivial enough to get around that it states unequivocally "here be dragons"

primal idol
#

and can't possibly truly work
That is bold xD

maiden vine
#

The principal is simple, and seems to be working fine

rugged sparrow
#

(Or any other way to do memory corruption)

#

Using ctypes, you can make objects that can only be accessed with ctypes

rugged sparrow
#

!e ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]

class container:
slots = 'value'

def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)

def make_container(init_val=(sentinel:=object())):
raw = ptr_to_bytes(0xffffffff)
+ ptr_to_bytes(id(container))
+ bytes(PTR_SIZE * 2)

fake = PyObj_FromPtr(id(raw) + BYTES_HEADER)
if init_val is not sentinel:
    fake.value = init_val
return raw

def get_value(raw):
return PyObj_FromPtr(id(raw) + BYTES_HEADER).value

def set_value(raw, new_val):
PyObj_FromPtr(id(raw) + BYTES_HEADER).value = new_val

def clear_value(raw):
del PyObj_FromPtr(id(raw) + BYTES_HEADER).value

raw_container = make_container('abc')
print(raw_container)
print(get_value(raw_container))
clear_value(raw_container)
print(raw_container)``` this example makes a bytes object that contains the real container object (thus making it only accessible through ctypes

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | b'\xff\xff\xff\xff\x00\x00\x00\x00\x103\x1cX\xd6U\x00\x000Dt\x81%\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
002 | abc
003 | b'\xff\xff\xff\xff\x00\x00\x00\x00\x103\x1cX\xd6U\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
maiden vine
#

Could you explain to me what ctypes is?

#

It lets you call c functions from python, but only using primitive types?

#

*as arguments

quartz wave
#

sort of

#

ctypes can implicitly convert though

quartz wave
maiden vine
#

Blughg

#

Looks yucky

rugged sparrow
#

!e ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]

class container:
slots = 'value'

def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)

addr = id(
s := ptr_to_bytes(id(container)) \

  • ptr_to_bytes(0xffffffff) \
  • bytes(PTR_SIZE * 2)
    ) + BYTES_HEADER
    print(py_object.from_address(addr))```
night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

py_object(<class '__main__.container'>)
rugged sparrow
#

!e yea cause that code is the same as this: ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]

class container:
slots = 'value'

def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)

addr = id(
s := ptr_to_bytes(id(container))
) + BYTES_HEADER
print(py_object.from_address(addr))```

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

py_object(<class '__main__.container'>)
quartz wave
#

ok i guess

gentle pagoda
#

had a cursed idea, but im not sure if its possible. it would need:

automatic function currying (maybe hooking function __init__ if thats a thing)
replacing @ on object with an elixir-style |>
object called _ that returns operators, so _+_ returns operator.add
Then you could do functional pipeline programming :) ```py

[3, 4, 5] @ map (+) @ reversed
[6, 5, 4]

verbal talon
#

I'm trying to turn this code into a one-liner but a bit stuck because I don't know how to move the nonlocal bit into the lambda:

def get_mock_input(user_input):
    x = -1
    def input(prompt):
        nonlocal x
        return user_input[(x := x + 1)]
    
    return input

input = get_mock_input(["foo", "bar"])
#

Like normally I'd work from the inside and turn this into:

def get_mock_input(user_input):
    x = -1
    return lambda prompt: user_input[(x := x + 1)]
#

and then proceed from there, but I can't because x is no longer accessible from that scope...

#

I think for now I'm going to work around this by using a different type anyway:

def get_mock_input(user_input):
    q = __import__('collections').deque(user_input)
    return lambda prompt: q.popleft()
rugged sparrow
#

!e ```py
get_mock_input = lambda ui:iter(ui).next

input = get_mock_input(l:=[])

l.extend(['a', 'b', 'c'])
print(input())```

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

a
rugged sparrow
#

just use an iterator

verbal talon
#

ah, of course

#

Because ultimately I wanted this to just be one line

input = iter(["foo"], ["bar"]).__next__
#

Should make it easier to test some interactive scripts...

rugged sparrow
#

input = iter(["foo", "bar"]).__next__ should be this

verbal talon
#

yeah that

#

Except that's not right either, because it should accept one argument, and ignore it

#
input = lambda _: iter(["foo", "bar"]).__next__()

I don't think this is right either because it will make a new iter on every call

#

This seems to do the trick:

input = (lambda f: lambda _: f())(iter(["foo", "bar"]).__next__)
#

!e

input = (lambda f: lambda _: f())(iter(["foo", "bar"]).__next__)
print(input("ignored1"))
print(input("ignored2"))
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

001 | foo
002 | bar
verbal talon
verbal talon
#

!e

o = object()
o.x = "foo"
night quarryBOT
#

@verbal talon :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | AttributeError: 'object' object has no attribute 'x'
verbal talon
#

!e

o = lambda: None
o.x = "foo"
night quarryBOT
#

@verbal talon :warning: Your eval job has completed with return code 0.

[No output]
verbal talon
#

What explains the difference in behavior?

rugged sparrow
#

Functions allow you to set attributes on instances

verbal talon
#

Hmm, explicitly functions and not other types of objects?

#

Well that's very useful for my purposes haha

verbal talon
#

!e

(lambda c,s,seq,run:(lambda ipc:any((__import__('sys').exit(0)if s.pc>=len(c)else{'+':lambda:run(s.arr.__setitem__(s.ptr, s.arr[s.ptr]+1),ipc()),'-':lambda:run(s.arr.__setitem__(s.ptr, s.arr[s.ptr]-1),ipc()),'>':lambda:run(setattr(s,"ptr", s.ptr+1),ipc()),'<':lambda:run(setattr(s, "ptr", s.ptr-1),ipc()),',':lambda: run(s.arr.__setitem__(s.ptr, ord(__import__('sys').stdin.read(1))),ipc()),'.':lambda:run(print(chr(s.arr[s.ptr]),end=''),ipc()),'[':lambda:run(s.rs.append(s.pc),ipc()),']':lambda:setattr(s,"pc",(lambda ppc:ppc if s.arr[s.ptr] != 0 else s.pc + 1)(s.rs.pop()))}[c[s.pc]]())for _ in __import__('itertools').count(0)))(lambda:setattr(s,"pc",s.pc+1)))(">++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+.",(lambda x:(x,setattr(x,"arr",[0]*1024),setattr(x,"ptr",0),setattr(x,"pc",0),setattr(x,"rs",[]))[0])(lambda _:None),lambda x,y:y,lambda *x:None)
night quarryBOT
#

@verbal talon :white_check_mark: Your eval job has completed with return code 0.

Hello, World!
verbal talon
#

This was my project for the evening -- learning how to write hello world in python

#

The fact that you can stick arbitrary attributes on functions was helpful here. just create lambda:None and then start assigning key-value pairs to it lol

amber ravine
verbal talon
#

we all gotta start somewhere man

onyx jacinth
#

any shorter ?
!e

c=12
while c>0:d=("*"*c).center(12);print(d,d);c-=2
night quarryBOT
#

@onyx jacinth :white_check_mark: Your eval job has completed with return code 0.

001 | ************ ************
002 |  **********   ********** 
003 |   ********     ********  
004 |    ******       ******   
005 |     ****         ****    
006 |      **           **     
wheat river
#

use fstrings

#

u can replace ("*"*c).center(12) with f'{"*"*c:^12}'

#

!e

c=13
while c>0:print(f'{"*"*(c:=c-2):^12}'*2)
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 | *********** *********** 
002 |  *********   *********  
003 |   *******     *******   
004 |    *****       *****    
005 |     ***         ***     
006 |      *           *      
007 |                         
wheat river
#

!e

c=12
while c>0:print(f'{"*"*c:^12} '*2);c-=2
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 | ************ ************ 
002 |  **********   **********  
003 |   ********     ********   
004 |    ******       ******    
005 |     ****         ****     
006 |      **           **      
onyx jacinth
#

ohh i did not know about align in f strings nice

humble rune
#

how in the fuck does my man ryuga do it

#

my guy looks at a 35 line program

#

and goes

#

"heres the same exact program but in 99% less characters"

quartz wave
humble rune
#

is this like a mega golfed lambda inside an f string

quartz wave
#

if i see str.center i'd think "hmm, that same functionality is in f-strings isn't it"

split salmon
upbeat sonnet
#
def rot13(message): return ''.join(map(lambda x: chr(ord(x) + 13) if x.isalpha() and ord(x) < 96 - 13 else (chr(ord(x) - (96 - ord(x))) if x.isalpha() and ord(x) < 96 - 13 else x), message))```
#

whats the problem with this-

split salmon
#

!e py exec(''.join(['c3\nhl >:rn("\'\'c^1";-2\nrn("n\'ee on ieYuU ):3})wiec3:rn("\'\'c^1";+2'[i//2] if i%2==0 else '=1wiec0pitf{1*:3})c=\npitf\\{NvrGnaGv o p:\'^0"\nhl <2pitf{1*:3})c=;'[i//2]for i in range(128)]))

night quarryBOT
#

@split salmon :white_check_mark: Your eval job has completed with return code 0.

001 | 1111111111111111111111111111111
002 |  11111111111111111111111111111 
003 |   111111111111111111111111111  
004 |    1111111111111111111111111   
005 |     11111111111111111111111    
006 |      111111111111111111111     
007 |       1111111111111111111      
008 |        11111111111111111       
009 |         111111111111111        
010 |          1111111111111         
011 |           11111111111          
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/ikicakajup.txt?noredirect

split salmon
#

YS!!!!

wheat river
wheat river
#

!e

print('a'.center(10))
print(f'{"a":^10}')
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 |     a     
002 |     a     
humble rune
#

How does that work???

floral meteor
night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

001 | 0.00000000
002 | 0000000001
003 |     ^     
floral meteor
#

except f-strings do all that within {:} inside the strings.

humble rune
#

what????

floral meteor
#

the string has an internal method __format__ that does these things, and it comes with syntax sugar to abbreviate it

#

!e ```py
print(f"0{'.':0<9}")
print(f"{'1':0>10}")
print(f"{'^': ^10}")

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

001 | 0.00000000
002 | 0000000001
003 |     ^     
floral meteor
#

what an f string does is it looks for the {:} characters and replaces them and the characters between them with calling str.__format__ with the arguments between as arguments and inserts them back into the "main" f-string

wheat river
# humble rune How does that work???

there are some parts to an fstring

f'{some-object:<format-specifier>}'

some-object is the object u want to format (u can also add flags (starts with !) like !r(repr of the obj)
format-specifier the format specifier ........

so its like a mini lang
some format specifiers
^ centers some text
< left aligns
> right aligns
and so on

upbeat sonnet
#

so like

night quarryBOT
#
Missing required argument

code

upbeat sonnet
#

!e py print(f"{10:.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

10.00
upbeat sonnet
#

there

#

!e py print(f"{10:<10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

10.00     
upbeat sonnet
#

indent not working as i hoped but i think thats discord

#

anyhow

#

!e py print(f"{10:>10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

     10.00
upbeat sonnet
#

ah there

#

and to centre

#

!e py print(f"{10:^10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

  10.00   
upbeat sonnet
#

oh.

#

it is centered, but it doesnt look like it

#

!e py print(f"{10:.^10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

..10.00...
upbeat sonnet
#

oh...

#

good enough ig

floral meteor
#

!e I likes symmetry ```py
print(f"0{10:0^10.2f}")

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

00010.00000
split salmon
#

k

#

!e py print(f"{10:.2f.^10}")

#

oh

night quarryBOT
#

@split salmon :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 1, in <module>
003 | ValueError: Invalid format specifier
humble rune
upbeat sonnet
#

it would be

#

!e py print(f"{10:.^10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

..10.00...
upbeat sonnet
#

!e py print(f".{10:.^10.2f}")

night quarryBOT
#

@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.

...10.00...
upbeat sonnet
#

๐Ÿ™

split salmon
#

lol me dum

wheat river
#

!e

@lambda m:(f:=lambda*a,**k:(a or k)and print(m(*a,**k))or f)
def factorial(lim):
    from functools import reduce
    return reduce(lambda x,y:x*y,range(1,lim+1))

factorial(10)(3)(4)()()(2)
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 | 3628800
002 | 6
003 | 24
004 | 2
pastel sparrow
#

!e ```py
factorial=type("e",(),{"new":lambda c,i=():[print(import("math").factorial(i))if i!=()else 1,factorial][1]})

factorial(10)(3)(4)()()(2)

night quarryBOT
#

@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | 3628800
002 | 6
003 | 24
004 | 2
pastel sparrow
#

wait dammit mine is still longer than a one line version of yours

#

!e ```py
factorial=lambda i=():[print(import("math").factorial(i))if i!=()else 1,factorial][1]

factorial(10)(3)(4)()()(2)

night quarryBOT
#

@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | 3628800
002 | 6
003 | 24
004 | 2
split marsh
#

what is esoteric python?

vague cairn
split marsh
vague cairn
#

Hey! golfing my explanation wasn't an issued challenge...

#

๐Ÿ˜‰

inner blade
#

Python should have some special div and maybe sqrt ops that return integer values when the inputs and outputs are precisely integer

humble rune
#

is there a golfed method of getting the first X letters of a string

inner blade
#

so like 4.0 / 2 = 2.0, that's fine, but they should make it so that 4 / 2 = 2

#

and sqrt(4) should be 2 instead of 2.0

humble rune
humble rune
inner blade
#

something like this

def fancy_div(a, b):
    """
    Returns quotient as an integer if a and b are integers, and a is divisible
    by b, otherwise returns quotient as a float 
    """
    div, mod = divmod(a, b)
    return div if mod == 0 else a / b
#
>>> fancy_div(4,2)
2
>>> fancy_div(4.0,2)
2.0
>>> fancy_div(5,2)
2.5
#
def fancy_sqrt(n):
    """
    Returns the โˆšn as an integer if n is an integer and perfect square,
    otherwise calculate and return sqrt(n) as a float
    """
    if isinstance(n, int):
        isqrt = math.isqrt(n)
        if isqrt ** 2 == n:
            return isqrt
    else:
        return math.sqrt(n)
humble rune
#

its better to be consistent in what type of data you return

#

you dont know if some big application relies on it being a float everytime

earnest wing
#
T = TypeVar("T", bound=float)
def fancy_div(a: T, b: T) -> T: ...

:>

vague cairn
inner blade
#

intermediate calculations of anything to prevent from moving over to float for as long as possible

#

keep perfect precision; this wouldn't help make things readable generally if you've already got float numbers since it would keep them float

quartz wave
night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

None
rugged sparrow
night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | 3628800
002 | 6
003 | 24
004 | 2
quartz wave
inner blade
quartz wave
# inner blade like what?

i noticed there was a flaw in your code in which if it's an integer and not a perfect square, it returns None

inner blade
#

oh you're right, the logic is broken; should just delete the else line

#
import math

def fancy_sqrt(n):
    """
    Returns the โˆšn as an integer if n is an integer and perfect square,
    otherwise calculate and return sqrt(n) as a float
    """
    if isinstance(n, int):
        isqrt = math.isqrt(n)
        if isqrt ** 2 == n:
            return isqrt
    return math.sqrt(n)
#

something like that

night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

001 | 4
002 | 2.23606797749979
003 | 4.0
quartz wave
#

!e ```py
import math
fancy_sqrt=lambda n:int(s)if(type(n)==int)==(not(s:=math.sqrt(n))%1)else s
print(fancy_sqrt(16))
print(fancy_sqrt(5))
print(fancy_sqrt(16.))

night quarryBOT
#

@quartz wave :white_check_mark: Your eval job has completed with return code 0.

001 | 4
002 | 2.23606797749979
003 | 4.0
rugged sparrow
rugged sparrow
# quartz wave ok

!e py fancy_sqrt = lambda n:[sq:=n**.5,int(sq)][(type(n)==int)and(sq**2==n)] print(fancy_sqrt(16)) print(fancy_sqrt(5)) print(fancy_sqrt(16.)) golfed it more

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

001 | 4
002 | 2.23606797749979
003 | 4.0
wheat river
#

!e

fancy_sqrt = lambda n:[sq:=n**.5,int(sq)][(type(n)==int)&(sq**2==n)]
print(fancy_sqrt(16))
print(fancy_sqrt(5))
print(fancy_sqrt(16.))
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

001 | 4
002 | 2.23606797749979
003 | 4.0
inner blade
wheat river
#

!e

from math import isqrt as ii

for i in range(1, 100):
    if (a:=int(i**.5)) != (b:=ii(i)):
        print(a, b)
night quarryBOT
#

@wheat river :warning: Your eval job has completed with return code 0.

[No output]
floral meteor
#

a python script I made outputted this abomination when I fed it my desktop background.

granite flax
pastel sparrow
near gust
#

fuck you typing

wheat river
wheat river
night quarryBOT
#

@wheat river :white_check_mark: Your eval job has completed with return code 0.

False
earnest wing
#

"why is"

near gust
#

!e

locals = {}
exec("""
import typing
from tokenize import Token
def f() -> typing.List[Token]:
    pass

f()
"""
{}, locals)
print(locals)
night quarryBOT
#

@near gust :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     exec("""
003 |          ^^
004 | SyntaxError: invalid syntax. Perhaps you forgot a comma?
near gust
#

!e

locals = {}
code = """
import typing
from tokenize import Token
def f() -> typing.List[Token]:
    pass

f()
"""
exec(code, {}, locals)
print(locals)
night quarryBOT
#

@near gust :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "/usr/local/lib/python3.10/typing.py", line 665, in __init__
003 |     code = compile(arg, '<string>', 'eval')
004 |   File "<string>", line 1
005 |     [ \f\t]*(\\\r?\n[ \f\t]*)*(#[^\r\n]*)?((([0-9](?:_?[0-9])*[jJ]|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)[jJ])|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)|(0[xX](?:_?[0-9a-fA-F])+|0[bB](?:_?[01])+|0[oO](?:_?[0-7])+|(?:0(?:_?0)*|[1-9](?:_?[0-9])*)))|(\r?\n|(\~|\}|\|=|\||\{|\^=|\^|\]|\[|@=|@|>>=|>>|>=|>|==|=|<=|<<=|<<|<|;|:=|:|/=|//=|//|/|\.\.\.|\.|\->|\-=|\-|,|\+=|\+|\*=|\*\*=|\*\*|\*|\)|\(|\&=|\&|%=|%|!=))|((|U|RB|BR|F|rF|u|R|r|fr|B|b|bR|rf|rb|Fr|rB|br|Br|Rb|Rf|f|fR|FR|RF)'[^\n'\\]*(?:\\.[^\n'\\]*)*'|(|U|RB|BR|F|rF|u|R|r|fr|B|b|bR|rf|rb|Fr|rB|br|Br|Rb|Rf|f|fR|FR|RF)"[^\n"\\]*(?:\\.[^\n"\\]*)*")|
... (truncated - too long, too many lines)

Full output: https://paste.pythondiscord.com/urajajever.txt?noredirect

near gust
#

yep that's the problem

#

lemme look into this

#

i need flag ast.PyCF_TYPE_COMMENTS

#

I need to run compile and then exec

#

!e

locals = {}
code = """
import typing
from tokenize import Token
def f() -> typing.List[Token]:
    pass

f()
"""
import ast
code = compile(code, '<string>', 'exec', flags=ast.PyCF_TYPE_COMMENTS)

exec(code, {}, locals)
print(locals)
night quarryBOT
#

@near gust :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "/usr/local/lib/python3.10/typing.py", line 665, in __init__
003 |     code = compile(arg, '<string>', 'eval')
004 |   File "<string>", line 1
005 |     [ \f\t]*(\\\r?\n[ \f\t]*)*(#[^\r\n]*)?((([0-9](?:_?[0-9])*[jJ]|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)[jJ])|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)|(0[xX](?:_?[0-9a-fA-F])+|0[bB](?:_?[01])+|0[oO](?:_?[0-7])+|(?:0(?:_?0)*|[1-9](?:_?[0-9])*)))|(\r?\n|(\~|\}|\|=|\||\{|\^=|\^|\]|\[|@=|@|>>=|>>|>=|>|==|=|<=|<<=|<<|<|;|:=|:|/=|//=|//|/|\.\.\.|\.|\->|\-=|\-|,|\+=|\+|\*=|\*\*=|\*\*|\*|\)|\(|\&=|\&|%=|%|!=))|((|U|rb|RB|br|F|rf|FR|u|rF|b|RF|R|BR|rB|Br|fr|f|fR|B|Fr|r|Rb|Rf|bR)'[^\n'\\]*(?:\\.[^\n'\\]*)*'|(|U|rb|RB|br|F|rf|FR|u|rF|b|RF|R|BR|rB|Br|fr|f|fR|B|Fr|r|Rb|Rf|bR)"[^\n"\\]*(?:\\.[^\n"\\]*)*")|
... (truncated - too long, too many lines)

Full output: https://paste.pythondiscord.com/fucepigada.txt?noredirect

earnest wing
#

Token is a string btw

#

not a type

#

Do you want a TokenInfo or something else?

near gust
#

nah I was just testing something

#

!e

locals = {}
code = """
import typing
from tokenize import TokenInfo
def f() -> typing.List[TokenInfo]:
    pass

f()
"""
import ast
code = compile(code, '<string>', 'exec', flags=ast.PyCF_TYPE_COMMENTS)

exec(code, {}, locals)
print(locals)
night quarryBOT
#

@near gust :white_check_mark: Your eval job has completed with return code 0.

{'typing': <module 'typing' from '/usr/local/lib/python3.10/typing.py'>, 'TokenInfo': <class 'tokenize.TokenInfo'>, 'f': <function f at 0x7f67465a4ca0>}
near gust
#

oh

#

I'm dumb

#

!e

locals = {}
code = """
import typing
from tokenize import TokenInfo
def f() -> typing.List[TokenInfo]:
    pass

f()
"""
import ast
code = compile(code, '<string>', 'exec')

exec(code, {}, locals)
print(locals)
night quarryBOT
#

@near gust :white_check_mark: Your eval job has completed with return code 0.

{'typing': <module 'typing' from '/usr/local/lib/python3.10/typing.py'>, 'TokenInfo': <class 'tokenize.TokenInfo'>, 'f': <function f at 0x7f9e55214ca0>}
near gust
#

yeah

#

i was just dumb

earnest wing
#

the naming is a bit misleading but yeah Token (and all the specific token types) are just the actual regex patterns

near gust
#

Just why

earnest wing
#

old code

near gust
#

-_-

#

This is why I usually write my own lexers

wheat river
#

gvanrossum committed on Jan 2, 1992
how long has github been around for

restive void
#

Given that Git itself is from 2005, not that long

wheat river
#

idfk

restive void
#

Python was initially developed with some other version control software (CVS?). When the repository was converted to Git, the old commits were translated into Git commits, including commits older than Git.

Since Git is decentralized, GitHub doesn't know when a commit really was created anyways; I can push a commit from before 1900, too, I think.

wheat river
#

ah intresting