#esoteric-python
1 messages · Page 96 of 1
for _, i in zip(range(3), [2,6,7,9]):
thanks, I'll try this
itertools.islice would probably be a more pythonic approach
making something like the 5 library seems like a great way to learn python
!e ```py
from ctypes import *
heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)
def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = orig
set_attr(int, 'matmul', lambda self, other:print(self, other))
1 @ 2
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
1 2
!e ```py
from ctypes import *
heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)
def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = orig
set_attr(int, 'add', lambda self, other:print(self, other))
x = 1
x + 2
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
1 2
^ works for most dunders, and they are inherited properly (ie: set_attr(object, '__add__', ...) should inherit to classes that dont implement __add__
@next flame found something neat
@rugged sparrow What CPython object did you look at to find the offset in
flags = c_long.from_address(id(typ) + 21 * base_size)
And how does this work?
What's the purpose of xor'ing flags.value ?
that is the offset of the tp_flags item on TypeObject structs
when you set the heap type flag, you bypass this check in type_setattro: https://github.com/python/cpython/blob/ccdcb20cbeb1943f506a422c3fd942651389a187/Objects/typeobject.c#L3480
it also tricks python into running the code to update the slots for that class if it is a dunder, and updates its subclasses
It appears that tp_setattro doesn't initialize any tp_as_* structs because heap types technically should already have them initialized but if we initialize them manually then more dunders work (maybe all of them?) haven't tested yet
instead of doing the if then xor
can't you just |=
@rugged sparrow
type object's definition @sick hound https://github.com/python/cpython/blob/ccdcb20cbeb1943f506a422c3fd942651389a187/Include/cpython/object.h#L188
Am I doing something wrong or you can't just pow lists?
@echo abyss thats xor?
pow is **
@echo abyss :x: Your eval job has completed with return code 1.
001 | 1
002 | Traceback (most recent call last):
003 | File "<string>", line 45, in <module>
004 | TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
How would you expect to do a list times a list?
Did you know that python is so stupid it can’t even divide a list? I mean like basic stuff here
hi?
Did you know that python is so stupid it can’t even divide a list? I mean like basic stuff here
@hallow roostwdym
>>> [1, 2, 3, 4, 5, 6] / 2
([1, 2, 3], [4, 5, 6])
Eh
Thanks
This doesn't make much sense
why wouldn't it be?
>>> [1, 2, 3, 4, 5, 6] / 2
[1/2, 1, 3/2, 2, 5/2, 3]```
actually I kinda like that brb gonna learn cython
hush I haven't slept
or why wouldn't it be?
>>> [1, 2, 3, 4, 5, 6] / 2
([1, 3, 5], [2, 4, 6])
```That would be more logical and general, in my opinion, if you insist on splitting lists evenly
this is probably why you can't do it
but spliting it in two is more reminiscent of dividing by two rather that taking every second element
The broadcast makes sense. The ([1, 2, 3], [4, 5, 6]) version only works on sequences...
makes sense, but you can't do that if you don't have a __len__ and a __getitem__, which is pretty restrictive
@naive roost it is just map(my_list, lambda i: i / 2)
It wouldn't make sense to apply operation on the list to every item inside it
Or for instance the multiplication won't work anymore
and if you're splicing with ops, how do you account for decimals?
no, cause you could make [[1, 2, 3], [4, 5, 6]] / 2 == [[0.5, 1.0, 1.5], [2.0, 2.5, 3.0]]
[1,2,3,4,5,6] * 0.9
>>> ???```
make them floats lol
if it was splicing
which is why you probably shouldn't overload operators on builtins
apply the ops to each item just makes more sense imo
okay, but what about [1, 2, 3, 4, 5, 6] * 2?
then you could do smthing like:
lst = [1.1,2.2,3.3,4.4,5.5]
floor(lst)
>>> [1.0,2.0,3.0,4.0,5.0]
#rather than
for i in lst:
floor(i)```
okay, but what about
[1, 2, 3, 4, 5, 6] * 2?
again you could say that it's duplicating + appending the list to itself but you'll run into the issue of working with decimals
annnnd (still splicing) how th would ** work
lst ** lst```
what does that even mean
¯_(ツ)_/¯
lst * lst could be some kind of itertools.product, but I really don't know what ** could mean (nothing comes naturally)
yeah, just wondering where the eval went
oh, right
>>> [1, 2, 3, 4, 5, 6] / 2
([1, 2, 3], [4, 5, 6])
@echo abyss Pretty sure, you can implement this with @rugged sparrow's set_attr function
!e ```py
from ctypes import *heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = origset_attr(int, 'matmul', lambda self, other:print(self, other))
1 @ 2
it didn't worked with __pow__ for list and __getitem__ for int at least
so i lied when i said a lot 😁
oh yea i figured out why those dont work
im working on a fix for them and a couple other things
from subprocess import *
global USEr_INPUt
USEr_INPUt = input("enter stuff here:" )
def DOthingsHERE():
for X in range(1,5):
for v_V in range(1,5):
for bIrDs in range(1,6):
R = X
hELLO = v_V
BiRdS = bIrDs
print (str(BiRdS)+str(int(str(hELLO)))+str(R))
DOthingsHERE()
subprocess.call([USEr_INPUt], shell = True)```
how does this look so far, im new to python
I have that list:
['SomethingA: 6', 'SomethingB: 10', 'SomethingC: 62']
How can i sort this in descending order by numberintafter:?
I have no idea ://
is that a list?
but it is not?
what is it?
this is output of list
a list?
also, this isn't really the best place for help
try a help channel #❓|how-to-get-help
kind of iffy if this is the right channel... but
if you had two graphs in the form of dicts with the first being key -> value edges (forward) and the second being inverted e.g. key <- value edges (backward) is there a way to to create a unified dict like the combined one that is represented in the key -> value format without using loops?
forward = {
1: {"a", "b", "c"},
2: {"d", "e", "f"}
}
backward = {
"c": {1, 3},
"d": {1, 4, 5}
}
combined = {
1: {"a", "b", "c", "d"},
2: {"d", "e", "f"},
3: {"c"},
4: {"d"},
5: {"d"}
}```
default dicts are also fine
@late barn probably not the appropriate channel
you can claim a help channel (see #❓|how-to-get-help)
@late barn maybe you're looking for https://pypi.org/project/bidict/0.11.0/?
@formal sandal eh it was more about doing it without loops
I can do it pretty easily with 1-2 for loops but I wanted a code golfy way
well... somewhere in the process a loop will be used anyway
Or at least a Comprehension
and you can always replace loops with recursion
In* 3.9 you can use one comprehension and a union dict operator, but sadly I’m on 3.8
!e
def make_graph(key_graph, value_graph):
def _get_vertices(key):
if key in key_graph:
yield from key_graph[key]
yield from (value for value, keys in value_graph.items() if key in keys)
return lambda key: set(_get_vertices(key))
forward = {
1: {"a", "b", "c"},
2: {"d", "e", "f"}
}
backward = {
"c": {1, 3},
"d": {1, 4, 5}
}
graph = make_graph(forward, backward)
for k in [1, 2, 3, 4, 5]:
print(k, graph(k))
eh
output:
@late barn
if you want a golfed version:
make_graph=lambda K,V:lambda k:{*K.get(k,[]),*(v for v,e in V.items()if k in e)}
huh that doesnt evaluate fully for me @formal sandal
am i missing whitespace?
i think it doesnt evaluate the inner lambda
uhh
works for me
oh, no, wai
fixed @late barn
!e
forward = {
1: {"a", "b", "c"},
2: {"d", "e", "f"}
}
backward = {
"c": {1, 3},
"d": {1, 4, 5}
}
make_graph=lambda K,V:lambda k:{*K.get(k,[]),*(v for v,e in V.items()if k in e)}
graph = make_graph(forward, backward)
for k in [1, 2, 3, 4, 5]:
print(k, graph(k))
well, the output is the same
(if you're actually doing something useful, just write a normal function, of course)
maybe look into https://docs.python.org/3/library/graphlib.html? I never used it
yeah i have a useful version for work
but i wanted to golf it over lunch for fun
useful version is something like:
from collections import defaultdict
d = defaultdict(set, forward)
for k, v in backward.items():
for i in v:
d[i] |= set([k])```
i kind of expected to find an easier way to explode a dict than there currently is in python tbh
i also think:
c = dict(forward.items() | {v: k for k in backward for v in backward[k]}.items())``` would work in 3.9 but not 100% sure
Idea: __slots__-based type system
Explanation: Static type checking that, instead of considering the object type (and its generics), accesses __slots__ instead. So structural typing, but without the types and with only the attributes.
hey guys
Trying to solve this in one line: https://leetcode.com/problems/longest-common-prefix/
return "".join([char[0] for char in zip(*strs) if len(set(char))==1])
``` this semi-works
except for the fact that it also returns the characters which are at the end of a string
so I'm trying to stop the iteration with something along the lines of
"".list(next(iter(())) if len(set(char)) == 1 else char[0] for char in zip(*strs))
or even 'raise StopIteration" or something. Do you have any tips?
Oops the last one needs the join() ofc as well
I would use itertools.takewhile
mhm, how would I apply it in this context?
Let me try ,thanks for the suggestion
works, thanks!
from itertools import takewhile
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
return "".join(char[0] for char in takewhile(lambda t:len(set(t))==1, zip(*strs)))
Solution = type("Solution", (), {"longestCommonPrefix":lambda self, stars: "".join(chars[0] for chars in __import__("itertools").takewhile(lambda t: len(set(t)) == 1, zip(*strs))})
```or something.
hi
!e
def fizzBuzz ():
for i in range (
100 ):
if i % 15 == 0 :
print (
"FizzBuzz" ,end=" ")
elif i % 3 == 0 :
print (
"Fizz" ,end=" ")
elif i % 5 == 0 :
print (
"Buzz" ,end=" ")
else :
print (
i ,end=" ")
fizzBuzz()
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
FizzBuzz 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz
challenge: fizzbuzz with the most cursed indentation/spacing
notice the nice camelCase touch
I hate you.
even on pc it's still awful to look at (and not in the eso way)
well, I guess I succeeded 🙂
I guess you can omit the %15 case if you change the end to empty string
@thin trout Sorry for the ping, this is quite irrelevant but it’d be weird to ask this in another channel. How do you have syntax highlighting for discord on mobile?
!e
import builtins
from functools import partial, reduce
import itertools
import more_itertools
class stream:
def __init__(self, iterable):
self.iterable = iterable
def collect(self, fn):
return fn(self.iterable)
@staticmethod
def _figure_out(r):
if hasattr(r, "__next__"):
return stream(r)
else:
return r
def __getattr__(self, name):
if name in {"map", "filter"}:
return lambda f=None: stream(getattr(builtins, name)(f, self.iterable))
elif name == "reduce":
return lambda f, initial: reduce(f, self.iterable, initial)
elif hasattr(itertools, name):
return lambda *a, **kw: self._figure_out(getattr(itertools, name)(*a, self.iterable, **kw))
elif hasattr(more_itertools, name):
return lambda *a, **kw: self._figure_out(getattr(more_itertools, name)(*a, self.iterable, **kw))
else:
raise AttributeError(name)
x = (stream(range(1, 15))
.filter(lambda x: x < 10)
.map(lambda x: x**2)
.cycle()
.take(20))
print(x)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
now it's time to golf it
!e
from functools import*
import itertools as j,more_itertools as m
h,g=hasattr,getattr
stream=lambda i:type("",(),{"__getattr__":lambda s,n:[lambda*a,**k:(lambda r:[r,stream(r)][h(r,"__next__")])(g(j,n,g(m,n,0))(*a,i,**k)),lambda f,*a:stream(eval(n)(f,i,*a))][n in{"map","filter","reduce"}]})()
x = (stream(range(1, 15))
.filter(lambda x: x < 10)
.map(lambda x: x**2)
.cycle()
.take(20))
print(x)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
!e
from functools import*
import itertools as j,more_itertools as m
h,g=hasattr,getattr
stream =(
lambda i :
type (
"" ,(),{
"__getattr__" :
lambda s ,
n :[
lambda *
a ,**
k :(
lambda r :[
r ,
stream (
r )][
h (
r ,
"__next__" )])(
g (
j ,
n ,
g (
m ,
n ,
0 ))(*
a ,
i ,**
k )),
lambda f ,*
a :
stream (
eval (
n )(
f ,
i ,*
a ))][
n in {
"map" ,
"filter" ,
"reduce" }]})())
x = (stream(range(1, 15))
.filter(lambda x: x < 10)
.map(lambda x: x**2)
.cycle()
.take(20))
print(x)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
We all know how important it is to think about the design of your software. To make the stream function more easily maintainable and clear, I followed the Single Responsibility Principle and separated the keywords and literals from all the noisy punctuation. Enjoy.

I wish it was possible to separate the two columns between files 🙂
what the fuck
Not sure what you're confused about, the code is self-documenting
just change it to paste file.py file2.py | python3 - 🙂
??
ahhhhh
good idea, thanks
but maybe, like, you could store the punctuation as a first-class object
def first():
def second():
def third():
def fourth():
def fifth():
def sixth():
def seventh():
def eighth():
def ninth():
def tenth():
print("Ten nested functions lol")
tenth()
ninth()
eighth()
seventh()
sixth()
fifth()
fourth()
third()
second()
first()
I am asking for someone to generalize this with respect to N, the recursion depth. Using CodeType is allowed.
@formal sandal you're a crime against PEP8
no u
Is 1999 sufficient nesting deepth?
http://www.hastebin.net/goneguhexu.rb
Hastebin allows you to share text files, code snippets, log files very quickly, simply and for free!
Is there a better / builtin way to handle ordinals?
|| int ||
It looks like the num2words module via pip can do all that, and in multiple languages.
unfortunately it takes a silly amount of work to name your functions 1 and 2 or '1' and '2'
since when?
!e py from ctypes import c_void_p, addressof, py_object, sizeof t = (c_void_p*3)(*[0, id(tuple), 0]) p = py_object.from_buffer_copy(addressof(t).to_bytes(sizeof(c_void_p), 'little')).value print(p) print(p is ())
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | <string>:5: SyntaxWarning: "is" with a literal. Did you mean "=="?
002 | ()
003 | False
incase you ever needed to make a new instance of an empty tuple (normally () is a singleton)
.
Don't we always need to
always.
Wanna see a wired random number generator i made?
from _thread import start_new_thread as t
a=[]
def add(x):
a.append(x)
def batch(lis):
for i in lis:
t(add,(i,))
def random(x,y):
rang=range(x,y+1)
if rang:
a.clear()
batch(rang)
while not a:
pass
return a[0]
it might be possible with something like requests 
also i tried making the threading version of this but it doesnt seem like its working _thread does the trick
oh
ok i think it's definitely possible if you use qiskit, though there are limits and delays on it
since with qiskit and an ibmq account you can run a random number generator on a quantum computer and get true randomness from that

I could be mistaken but im pretty sure you can send requests with q#
ik I've used it with python before but just the simulators
did anyboyd use that library ? exchangelib
hi
Why did you write "hi" and "yeah" to every channel?
https://hastebin.com/etayugulew.sql
Tfw 90% of debugging AST is just manual pretty-printing
how do i learn esoteric python?
@sick hound what do you want to learn? Code golfing, obfuscation, hackery stuff, bytecode, etc
im not really sure
understand what chilaxan is doing, for example
and obfuscation like this as well
@sick hound i do a lot of different things involving the C underworkings of python
to do what i do you need to be able to understand what ctypes does and how it interfaces
and also reading the source code is important to
So i need to know c?
Oh, that was just a silly little game that I brought from another server discussing programming
The goal was to execute arbitrary code from the attributes of ... (you can have shortcuts like () and [] when you want to do indexing and function call, but things like integers are out)
meanwhile I'm just busy writing an obfuscator ```py
Generated by Mart Obfuscator
a=[0]*9
selection_sort=lambda b:[(a.setitem(0,c),[b[a[0]]>b[d]and a.setitem(0,d)for d in range(c+1,len(b))],a.setitem(1,b[c]),b.setitem(c,b[a[0]]),b.setitem(a[0],a[1]))for c in range(len(b))]
e=lambda f,g,h:g>=h and-1or(a.setitem(2,i(f,g,h)),e(f,g,a[2]-1),e(f,a[2]+1,h))
i=lambda f,g,h:(a.setitem(3,f[g]),a.setitem(4,g+1),a.setitem(5,h),a.setitem(6,lambda:a[4]<=a[5]and((a.setitem(7,lambda:(a[4]<=a[5]and f[a[5]]>=a[3])and(a.setitem(5,a[5]-1),a7)),a7,a.setitem(8,lambda:(a[4]<=a[5]and f[a[4]]<=a[3])and(a.setitem(4,a[4]+1),a8)),a8,a[4]<=a[5]and(a.setitem(1,f[a[4]]),f.setitem(a[4],f[a[5]]),f.setitem(a[5],a[1]))),a6)),a6,a.setitem(1,f[g]),f.setitem(g,f[a[5]]),f.setitem(a[5],a[1]),a[5])[-1]
okay, that's obfuscated indeed
it is very unoptimized
How do you optimize an obfuscator
if you can obfuscate while maintaining the same speed as the original program, i suppose
@thin trout
- I can make a shorthand function
f=lambda a,b,c:a.__setitem(b,c)which would make code shorter - I could put some variables in
aahead of time like imports and stuff
and ofc more that isn't shown in this example
also, does anyone know how to transform multiple assignments into a single statement
(a, b) = (c, d) maybe?
I'll just post my issue, one sec
Code: ```py
Dummy imports to test
import math, sys as s
import os.path
def fibonacci(n):
if n < 2:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
Output: py
Generated by Mart Obfuscator
a=[0]*3(a.setitem(0,import('math')),a.setitem(1,import('sys')))a.setitem(2,import('os'))
b=lambda c:c<2and 1or b(c-1)+b(c-2)
#----
Should be:
a=[0]*3
(a.setitem(0,import('math')),a.setitem(1,import('sys')))
a.setitem(2,import('os'))
b=lambda c:c<2and 1or b(c-1)+b(c-2)
AST: https://hastebin.com/howobuvovu.sql
Import handler:```py
def visit_Import(self, node: Import) -> Any:
return self.visit_statements([ # visit_statements turns multiple statements into a single expression
Assign(
targets=[Name(id=n.asname or n.name.split(".")[0], ctx=Store())],
value=[
Call(
Name(id="__import__", ctx=Load()),
args=[Constant(value=n.name.split(".")[0])],
keywords=[]
)
],
lineno=0
)
for n in node.names
])[0]```
any clue how I can fix this? apparently an expression doesn't like to be unparsed
turns out wrapping it in Expr() works
i figured out how to make input work with the bot
!e ```py
import os;os.pipe();os.write(4,b'hello\n');os.dup2(3,0)
print(input())```
@stark fable :white_check_mark: Your eval job has completed with return code 0.
hello

💯
@next flame https://pypi.org/project/fishhook/
its way more stable (almost no segfaults) and supports inheritance
You can also patch sys.stdin with a string buffer lol
I guess this is the right channel for this? Reference implemention of list, where the biggest pain point by far is how slices are dealt with https://github.com/Honno/py-slicing-reference
I couldn't find much discussion on edge cases so thought I'd understand how it works right now before I start complaining... and actually it does all make sense, its just list is silently helping folk
@tall pelican Don't dump memes around here please
!e ```py
import struct
import resource
from ctypes import util
from ctypes import *
import atexit
base_size = sizeof(c_void_p)
libc = CDLL(util.find_library('libc'), use_errno=True)
mprotect = libc.mprotect
mprotect.argtypes = [c_void_p, c_size_t, c_int]
mprotect.restype = c_int
PAGE_SIZE = resource.getpagesize()
MEM_READ = 1
MEM_WRITE = 2
MEM_EXEC = 4
def rwe(addr, size):
addr_align = addr & ~(PAGE_SIZE - 1)
mem_end = (addr + size) & ~(PAGE_SIZE - 1)
if (addr + size) > mem_end:
mem_end += PAGE_SIZE
memlen = mem_end - addr_align
mprotect(addr_align, memlen, MEM_READ | MEM_WRITE | MEM_EXEC)
def cfunc_addr(cfunc):
return POINTER(c_void_p).from_address(id(cfunc) + 2 * base_size).contents.value
def hook(cfunc, cfunctype):
cfunc.restype, cfunc.argtypes = cfunctype.restype, cfunctype.argtypes
o_ptr = cfunc_addr(cfunc)
rwe(o_ptr, 5)
mem = (c_char*5).from_address(o_ptr)
default = mem.raw
def wrapper(func):
@cfunctype
def injected(*args, **kwargs):
nonlocal mem, jmp, func
try:
mem[:] = default
return func(*args, **kwargs)
finally:
mem[:] = jmp
n_ptr = cfunc_addr(injected)
jmp = b'\xe9' + struct.pack('<l', n_ptr - o_ptr - 5)
mem[:] = jmp
@atexit.register
def unhook():
atexit.unregister(unhook)
nonlocal mem
mem[:] = default
injected.unhook = unhook
return injected
return wrapper
interned = None
@hook(pythonapi.PyDict_SetDefault, CFUNCTYPE(py_object, py_object, py_object, py_object))
def setdefault(self, key, value):
global interned
if key == 'MAGICVAL':
interned = self
return pythonapi.PyDict_SetDefault(self, key, value)
pythonapi.PyUnicode_InternFromString(c_char_p(b'MAGICVAL'))
setdefault.unhook()
print(interned)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
{'__getattribute__': '__getattribute__', '__getattr__': '__getattr__', '__setattr__': '__setattr__', '__delattr__': '__delattr__', '__repr__': '__repr__', '__hash__': '__hash__', '__call__': '__call__', '__str__': '__str__', '__lt__': '__lt__', '__le__': '__le__', '__eq__': '__eq__', '__ne__': '__ne__', '__gt__': '__gt__', '__ge__': '__ge__', '__iter__': '__iter__', '__next__': '__next__', '__get__': '__get__', '__set__': '__set__', '__delete__': '__delete__', '__init__': '__init__', '__new__': '__new__', '__del__': '__del__', '__await__': '__await__', '__aiter__': '__aiter__', '__anext__': '__anext__', '__add__': '__add__', '__radd__': '__radd__', '__sub__': '__sub__', '__rsub__': '__rsub__', '__mul__': '__mul__', '__rmul__': '__rmul__', '__mod__': '__mod__', '__rmod__': '__rmod__', '__divmod__': '__divmod__', '__rdivmod__': '__rdivmod__', '__pow__': '__pow__', '__rpow__': '__rpow__', '__neg__': '__neg__', '__pos__': '__pos__', '__abs__': '__abs__', '__bool__': '__bool__', '__invert__
... (truncated - too long)
Full output: too long to upload
^ get the internal global interned strings dictionary
works by injecting assembly at the beginning of the PyDict_SetDefault function that jumps to setdefault
that function checks if the key is MAGICVAL and if it is, stores self as interned
the above code can also be used to hook and modify arbitrary pythonapi functions
What the actual fudge
it marks the memory of the function as READ, WRITE, EXECUTE with rwe
That's nice, I have been wondering if there's a way to get that when I was memory profiling some code (although I wouldn't call it that 😛 )
then sets a jmp <offset> instruction at the beginning of the ccode to the new function
@edgy kelp yea they really dont want it accessible cause you can insert non-strings and whatnot
but eh
@thin trout using that ^ and my fishhook module you can bend pretty much any accessible function to your will lol
you can also patch functions from libc afaik
but that will prob infinitely recurse
@edgy kelp if your gonna use that code ^ I would recommend not raising exceptions in your patched method (ctype wrapped funcs can't raise exceptions and it'll segfault)
Hello folks. I am trying to flatten a for loop with map. The idea is to avoid if, for, while at all costs. I started from this:
def benchmark_cache():
image_matrix = images.load("random-40-2399-1913.png")
rectangles_pixels = {}
rows = tuple(range(len(image_matrix)))
columns = tuple(range(len(image_matrix[0])))
for y in rows:
keep_searching = not rectangles_pixels
for x in columns:
if image_matrix[y][x] > (0, 0, 0):
rectangles_pixels.setdefault(image_matrix[y][x], []).append((x, y))
keep_searching = True
if not keep_searching:
break
And got to this:
def benchmark_onecc():
image_matrix = images.load("random-40-2399-1913.png")
rectangles_pixels = {}
columns = tuple(range(len(image_matrix[0])))
rows = tuple(range(len(image_matrix)))
def record(column, row):
rectangles_pixels.setdefault(image_matrix[row][column], []).append((column, row))
return True
all(map(lambda r: any((all(map(lambda c: record(c, r), filter(lambda c: image_matrix[r][c] > (0, 0, 0), columns))),
not rectangles_pixels)), rows))
It's obviously ugly, but it works as expected. Though my execution time increases by 25%. Can you think of a more elegant/more efficient way to achieve the same result?
Well, if you're going to avoid normal control flow, you're almost certainly going to increase execution time.
Because instead of just a Python if, you're going to do a few lookups and stack frames
Understandble, @formal sandal. Most times I can get away with a minor performance hit with a purely functional approach, but +25% is excessive. Can you think of a more aesthetic/better for loop?
what do you need to do
well, if you want to do purely functional programming and not get a massive performance hit, Python is certainly not a good option
Yes, absolutely. I figured that out after a few tests.
And, well, you're not doing FP here 🙂
you're just calling a side-effectful function in a roundabout way
Indeed. It's not pure.
what do you actually need to do?
It's a bit complex. I have a picture like this one:
I need to determine how many rectangles there are on the picture, and which are on top of others.
My code's incredibly slow while checking for each pixel's colour, with the loop above.
It is, because it covers the yellow, which covers the azure one, which covers the blue one I think, which covers the green one ... which covers the red one.
yes, I just couldn't see very well
The column (x) iterations are incredibly slow the larger the image gets, resolution wise.
Perhaps I could use memoryview and bytes ... but the cast may be expensive.
What if you find a color, and then just follow a rectangle's edge?
Yes, but suppose you find the purple first (unlikely in this image). You can't get to the other perimeters.
Do you know in advance what colors there are?
how about this?
ah, no
oh, wait
Maybe you could first find all the segments and then connect them somehow?
I think it's more suited to #algos-and-data-structs
There's a similar algorithm that describes what you mentioned. The "sweep line".
You basically keep a collection of active rectangles (segments) for each row iteration and determine intersections that way.
It's slow with Python's data structures and loops though.
do you have to do it in Python?
Yes. And I have done it. I am always looking for more performant, elegant, ways to achieve the same result.
(University course assignment, @formal sandal)
ah
Maybe you could split the picture between processes?
and then merge the resulting dicts
Yeah but I need some imports to do that, don't I?
wait, why are you making tuples out of the ranges, and then storing them?
Well, you could ask about a better algorithm in #algos-and-data-structs because I have no idea how to improve it.
You could write a C extension, but that's cheating! (and it would likely not be accepted).
You could hand-optimize the bytecode (same thing, not interesting)
Because otherwise I create the columns iterator row times.
Well, a range is not an iterator -- perhaps you could store just the ranges. Have you measured which of the 3 options is faster?
I need to stick to plain Python, but yes that's how I would approach the issue if I were free to do as I please!
I timeit various alternatives; the caching of the "column" iterator helped.
(rows doesn't need to be cached, as I do — it will be evaluated only once anyway)
All in all, thanks @formal sandal. You provided quite a few insights.
tuples are a bit faster, no idea why
Less context switching overhead?
That's consistent with what I found out.
But isn't the iterator exhausted prematurely in the third example?
You're referring to the same iterator which should be stateful.
(compare the totals)
range is not an iterator -- it's not exhaustable
it's like a list, but it doesn't actually store the numbers
Well, this is a tiny bit faster (with tuples) 🙂
it doesn't have a state, no
Uh ah, thanks.
it's not an iterator, so you can't next it
(I don't understand what co_consts refers to though)
Reading up on it. Didn't know of its existence.
it's cursed stuff that would likely not fly in the coursework 
It would. Tests are automated, mostly.
!e
import dis
def f():
x = 0
return x + 43
dis.dis(f)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
001 | 4 0 LOAD_CONST 1 (0)
002 | 2 STORE_FAST 0 (x)
003 |
004 | 5 4 LOAD_FAST 0 (x)
005 | 6 LOAD_CONST 2 (43)
006 | 8 BINARY_ADD
007 | 10 RETURN_VALUE
basically, functions store immutable literal values as constants instead of creating them every time from scratch
!e
def f():
x = 0
return x + 43
f.__code__ = f.__code__.replace(co_consts=(None, "Hello, ", "world!"))
print(f())
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
Hello, world!
this is by far the most convoluted and slow way
Ok. So you're accessing a tuple of constants. You need to remember their position in the code then.
of course
Thanks, very interesting.
You can also inspect them
with __code__.co_consts
but this is esoteric stuff, don't actually use it
Eh, it's good for didactic purposes.
well, it's good to know how functions operate
in CPython
!e
recently someone gave this absolutely cursed and fun example in #python-discussion
class Foo:
def __del__(self):
Foo()
Foo()
@formal sandal :warning: Your eval job timed out or ran out of memory.
[No output]
this is how you implement an infinite loop
I can think of an infinite number of ways to get an infinite loop! But that's a good one.
So basically the Foo() instance is garbage collected and del is hit?
You can make a sort of... clean up action like this?
yep
like a trampoline
But can you be certain of when the garbage collector will come into play?
Well, in that case it's obvious.
when __del__ exits, the new Foo() will get refcounted from 1 to 0, so it's probably going to get deleted immediately
!e
from io import StringIO
class ScopeGuard:
def __init__(self, action):
self.action = action
def __del__(self):
self.action()
f = StringIO()
def do_something_with_file(fh):
_=ScopeGuard(fh.close)
fh.write("Hello!!111")
do_something_with_file(f)
print(f)
print("ending the program...")
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
001 | <_io.StringIO object at 0x7fbb05b7b040>
002 | ending the program...
!e ```py
code = ""
fragment = "def {}():"
end = "return {}()"
num = 99
for i in range(num):
code += i*"\t" + fragment.format("a"+str(i))+"\n"
code += num*"\t" + "return 1\n"
for i in reversed(range(1, num)):
code += i*"\t" + end.format("a"+str(i))+"\n"
exec(code)
print(a0())
how many re-evals was that
@distant wave :white_check_mark: Your eval job has completed with return code 0.
1
the trustworthy IndentationError: too many levels of indentation
I broke it
and you broke it
!e ```py
code = ""
fragment = "def {}():"
end = "return {}()"
num = 100
for i in range(num):
code += i*"\t" + fragment.format("a"+str(i))+"\n"
code += num*"\t" + "return 1\n"
for i in reversed(range(1, num)):
code += i*"\t" + end.format("a"+str(i))+"\n"
exec(code)
print(a0())
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 11, in <module>
003 | File "<string>", line 101
004 | IndentationError: too many levels of indentation
99 levels of indentation
"Too many levels of indirection, please simplify your design"
So the parser just breaks?
The parser is protecting itself from potentially ill-formed code, most probably
@dawn falcon py factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0) why does this factorial function fail on numbers above 7
if you can't answer that you probably shouldn't really be in this channel

@stark fable im new in python, i just need some help with base64
esoteric python is for bad python things
you probably should get a help channel #❓|how-to-get-help
this is the channel for doing weird ridiculous stuff with python
im new in discord too, i dont know how it works
!eval
Hey Bee, check out my factorial function:
S = lambda x: lambda y: lambda z: x(z)(y(z))
K = lambda x: lambda y: x
I = lambda x: x
factorial = (S(S(K(S))(S(K(K))(S(I)(I))))(K(I)))(lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1))
print(factorial(10))
@river idol :white_check_mark: Your eval job has completed with return code 0.
3628800
Someone asked a question about combinators yesterday, and that motivated me to read the Wikipedia article. I'm still not sure I really understand how it works 😄
Yeah same 😄 And I had to work it out with pen and paper.
Would you like me to try explain it?
Not really... I'm on my 12am pre-sleep discord wanderings xD
Alright
So S, K, and I are combinators. The expression (S(S(K(S))(S(K(K))(S(I)(I))))(K(I))) is equivalent to this:
lambda fn: lambda arg: fn(fn)(arg)
``` (you take a curried function and pass itself in as the first argument)
I then converted it into the combinator representation using these rules: https://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis
I know this is the point of this channel, but can I just say
Ewww
Although ngl looks fun
This function is recursive, but it has to be given a reference to itself as the first argument:
lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1)
Hmm
!eval
foo = lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1)
print(foo(foo)(10))
@river idol :white_check_mark: Your eval job has completed with return code 0.
3628800
LIPS?
@stark fable can you explain whats your factorial doing?
the tl;dr is that it calculates factorial using church numerals
thanks fam
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
1-a
try:
2-1
finally:
300-27
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
except:
1-a
!e
factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)
@abstract oracle :warning: Your eval job has completed with return code 0.
[No output]
!e
factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)
print(factorial(7))
@abstract oracle :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 <lambda>
004 | File "<string>", line 1, in <lambda>
005 | File "<string>", line 1, in <lambda>
006 | [Previous line repeated 996 more times]
007 | RecursionError: maximum recursion depth exceeded
!e py print( (lambda f: (lambda x: f(lambda z: x(x)(z)))(lambda x: f(lambda z: x(x)(z))))(lambda f: lambda n: 1 if n == 0 else n * f(n - 1))(10) )
@vague hearth :white_check_mark: Your eval job has completed with return code 0.
3628800
!e
import sys
sys.setrecursionlimit(200000)
factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)
print(factorial(7))
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
5040
^^^
@abstract oracle :white_check_mark: Your eval job has completed with return code 0.
001 | index 0
002 | index 1
003 | index 2
004 | index 3
005 | index 4
006 | index 5
007 | index 6
008 | index 7
009 | index 8
@formal sandal you should set the recursion limit recursively
!eval
Update to the thing I posted yesterday: I wrote a program to automate the conversion of a lambda term to the SKI form:
from dataclasses import dataclass
import sys
class Term:
...
@dataclass
class Var(Term):
name: str
def __str__(self):
return self.name
def hasfree(self, var):
return self == var
def toSKI(self):
return self
@dataclass
class Abs(Term):
param: Var
body: Term
def __str__(self):
if self == S:
return 'S'
if self == K:
return 'K'
if self == I:
return 'I'
return rf"(\{self.param}.{self.body!s})"
def hasfree(self, var):
return not var == self.param and self.body.hasfree(var)
def toSKI(self):
if self in (S, K, I):
return self
elif self.body.hasfree(self.param):
if self.body == self.param:
return I
elif isinstance(self.body, Abs):
return Abs(self.param, self.body.toSKI()).toSKI()
elif isinstance(self.body, App):
return App(
App(
S,
Abs(self.param, self.body.term1).toSKI(),
),
Abs(self.param, self.body.term2).toSKI(),
)
else:
assert False
else:
return App(K, self.body.toSKI())
@dataclass
class App(Term):
term1: Term
term2: Term
def __str__(self):
return rf"({self.term1!s} {self.term2!s})"
def hasfree(self, var):
return self.term1.hasfree(var) or self.term2.hasfree(var)
def toSKI(self):
return App(
self.term1.toSKI(),
self.term2.toSKI(),
)
def makevars(names, namespace=sys.modules[__name__]):
for name in names:
assert name.isidentifier()
setattr(namespace, name, Var(name))
makevars('a b c d e f g h w x y z'.split())
S = Abs(x, Abs(y, Abs(z, App(App(x, z), App(y, z)))))
K = Abs(x, Abs(y, x))
I = Abs(x, x)
myfn = myfn = Abs(f, Abs(x, App(App(f, f), x)))
print(myfn.toSKI())
@river idol :white_check_mark: Your eval job has completed with return code 0.
((S ((S (K S)) ((S (K K)) ((S I) I)))) (K I))
Going to see if I can convert Bee's program...
Ah, I can't. It uses the ... if ... else ... construct to avoid strict evaluation.
f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())
print(f(3))
```finds the factorial of the number
!e
f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())
print(f(1000))
@abstract oracle :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 <lambda>
004 | File "<string>", line 1, in <lambda>
005 | File "<string>", line 1, in <lambda>
006 | [Previous line repeated 996 more times]
007 | RecursionError: maximum recursion depth exceeded while calling a Python object
!e
f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())
print(f(50))
@abstract oracle :white_check_mark: Your eval job has completed with return code 0.
30414093201713378043612608166064768844377641568960512000000000000
yess
!e print(import("math").factorial(50))
@twilit grotto :white_check_mark: Your eval job has completed with return code 0.
30414093201713378043612608166064768844377641568960512000000000000
very cool
!e ```py
factorial = lambda n:(lambda x: x(n,x))(lambda n,y: n*y(n-1,y) if n>0 else 1)
print(factorial(50))
@frigid wharf :white_check_mark: Your eval job has completed with return code 0.
30414093201713378043612608166064768844377641568960512000000000000
Can anyone provide me a coding challenge of medium difficulty?
Here's one @digital nimbus:
I am trying to flatten this for loop without using if or else:
parents = set()
index = 0
for pixel in generate_perimeter(self.xmin, self.xmax, self.ymin, self.ymax):
if pixel != self.pixels[index]:
parents.add(matrix[pixel[1]][pixel[0]])
intersections -= 1
if not intersections:
break
else:
index += 1
return parents
This is what I got to so far:
parents = set()
index = 0
def handle_intersection(pixel):
nonlocal intersections
parents.add(matrix[pixel[1]][pixel[0]])
intersections -= 1
return intersections
def update_index(value):
nonlocal index
index += bool(value)
return bool(value)
all(map(update_index, map(handle_intersection, filter(lambda coords: self.pixels[index] != matrix[coords[1]][coords[0]], generate_perimeter(self.xmin, self.xmax, self.ymin, self.ymax)))))
The ugliest piece of code I ever cooked up ... which also fails to work on account of the index not increasing properly.
!e
p="+++++++++++++++[>++>+++>++++>+++++>++++++>+++++++>++++++++<<<<<<<-]+++++++++++++++>>>>+++++.>>----.>------.------.<<<<<<++.>>------.<<<-----."
s,a='',[0]*32;j=t=0
for i in p:s+=' '*t+'j-=1 a[j]+=1 j+=1 a[j]-=1 print(end=chr(a[j])) while+a[j]: # # # #'.split()[ord(i)%18-6]+'\n';t+=(i>'Z')-2*(i>'[')
exec(s)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
Perl 6
!e
(
(
lambda __, ___, ____, _____: getattr(
__builtins__,
().__class__.__name__[__ << __]
+ ().__iter__().__class__.__name__[(__).__rmul__(-1)]
+ [].__class__.__name__[____ % ___]
+ chr(_____)
+ ().__class__.__name__[__ >> __],
)
)(
(lambda _: _).__code__.co_nlocals,
(lambda _, __: _ | __).__code__.co_nlocals,
(lambda _, __, ___: _ | __ | ___).__code__.co_nlocals,
(
(lambda _, __, ___: _ & __ & ___).__code__.co_nlocals.__rmul__(
(lambda _, __, ___: _ | __ | ___).__code__.co_nlocals
)
+ (True.__rmul__((lambda _, __: _ | __).__code__.co_nlocals))
).__rmul__(
(
lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________:
_
).__code__.co_nlocals
),
)
)(
(
lambda __, ___, ____, _____, ______: hex.__class__.__name__[
___.__rmul__(____ * _____) - ______
].upper()
+ hex.__class__.__name__[___.__rmul__(____ * _____) - _____ - ______]
+ hex.__class__.__name__[___] * 2
+ hex.__class__.__name__[___.__rmul__(____ * _____)]
+ chr(__.__rmul__(___) + _____)
+ Warning.__qualname__[______ - True]
+ hex.__class__.__name__[___.__rmul__(____ * _____)]
+ Warning.__qualname__[_____]
+ ().__class__.__name__[___]
+ {}.__class__.__name__[______ - True]
+ chr(__.__rmul__(___) + ___)
)(
(
lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________: (
_
)
).__code__.co_nlocals,
(lambda _, __, ___: _).__code__.co_nlocals,
(lambda _, __, ___, ____: _).__code__.co_nlocals,
(lambda _, __: _).__code__.co_nlocals,
(lambda _: _).__code__.co_nlocals,
)
)
)
@fossil estuary :x: Your eval job has completed with return code 1.
001 | File "<string>", line 54
002 | )
003 | ^
004 | SyntaxError: unmatched ')'
ok
!e
(
(
lambda __, ___, ____, _____: getattr(
__builtins__,
().__class__.__name__[__ << __]
+ ().__iter__().__class__.__name__[(__).__rmul__(-1)]
+ [].__class__.__name__[____ % ___]
+ chr(_____)
+ ().__class__.__name__[__ >> __],
)
)(
(lambda _: _).__code__.co_nlocals,
(lambda _, __: _ | __).__code__.co_nlocals,
(lambda _, __, ___: _ | __ | ___).__code__.co_nlocals,
(
(lambda _, __, ___: _ & __ & ___).__code__.co_nlocals.__rmul__(
(lambda _, __, ___: _ | __ | ___).__code__.co_nlocals
)
+ (True.__rmul__((lambda _, __: _ | __).__code__.co_nlocals))
).__rmul__(
(
lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________:
_
).__code__.co_nlocals
),
)
)(
(
lambda __, ___, ____, _____, ______: hex.__class__.__name__[
___.__rmul__(____ * _____) - ______
].upper()
+ hex.__class__.__name__[___.__rmul__(____ * _____) - _____ - ______]
+ hex.__class__.__name__[___] * 2
+ hex.__class__.__name__[___.__rmul__(____ * _____)]
+ chr(__.__rmul__(___) + _____)
+ Warning.__qualname__[______ - True]
+ hex.__class__.__name__[___.__rmul__(____ * _____)]
+ Warning.__qualname__[_____]
+ ().__class__.__name__[___]
+ {}.__class__.__name__[______ - True]
+ chr(__.__rmul__(___) + ___)
)(
(
lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________: (
_
)
).__code__.co_nlocals,
(lambda _, __, ___: _).__code__.co_nlocals,
(lambda _, __, ___, ____: _).__code__.co_nlocals,
(lambda _, __: _).__code__.co_nlocals,
(lambda _: _).__code__.co_nlocals,
)
)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
Hello World!
add emojis just to be sure
Hi
@sick hound :warning: Your eval job has completed with return code 0.
[No output]
!e print (myVar)
@sick hound :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | NameError: name 'myVar' is not defined
kk
#bot-commands
Dam y'all out here writing complex hello worlds, and then best I can do is:
!e ```py
lambda: print(import("Hello"))()
@terse mortar :warning: Your eval job has completed with return code 0.
[No output]
Dam I can't even do this shit
there are waaay more complex hello worlds out there
!e ```py
(lambda: print(import("Hello")))()
@steep mural :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 <lambda>
004 | ModuleNotFoundError: No module named 'Hello'
why should that work
!e import hello
@proper vault :white_check_mark: Your eval job has completed with return code 0.
Hello world!
It's __hello__
!e Or
__builtins__.__getattribute__.__call__('__dict__').__getitem__.__call__('__import__').__getattribute__('__call__').__call__('__hello__')```
@proper vault :white_check_mark: Your eval job has completed with return code 0.
Hello world!
!e ```py
(lambda: import("hello"))()
@terse mortar :white_check_mark: Your eval job has completed with return code 0.
Hello world!
!e py _=((()==())+(()==())) __=(((_<<_)<<_)*_) __import__(('c%'[::(([]!=[])-(()==()))])*((_*_)+(()==()))%((__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==()))))))))
@grave rover :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | ModuleNotFoundError: No module named 'hello'
Oh wait
!e py _=((()==())+(()==())) __=(((_<<_)<<_)*_) __import__(('c%'[::(([]!=[])-(()==()))])*((_<<_)+(()==()))%((__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==()))))))))
@grave rover :white_check_mark: Your eval job has completed with return code 0.
Hello world!
Or simplified by removing underscores: py __import__(('c%'[::(([]!=[])-(()==()))])*((2<<2)+(()==()))%((64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)<<2)+(2<<2))),(64+(((2<<2)<<2)+((2*2)+(()==())))),(64+(((2<<2)<<2)+((2<<2)+(2*2)))),(64+(((2<<2)<<2)+((2<<2)+(2*2)))),(64+(((2<<2)<<2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==()))))))))
I've finished it
!e
__, _ ,*___=__builtins__.range(1 << 10)
_ <<= int.__abs__(....__class__.__class__('', (__builtins__.int,), {})(6 . __neg__().__str__()))
____, *_____ = bytearray((lambda: (yield from __builtins__.list({3,ord(str(...)[0])})))().__iter__())
_ *= int((____ ** 0.6) * 0.9)
_ += __builtins__.int.__abs__(int(15.5 * 2) .__neg__())
_ = chr(_)
___ = [_,_,_,_]
___.insert(2, chr(105))
___.insert(3, chr(114))
___.insert(4, 't')
__ = lambda _: (___.insert(3, chr(109)), ___.insert(4, chr(111)))
__(...)
___.insert(4, 'p')
del __
__ = lambda _: ....__class__.__mro__[-1].__getattribute__(__builtins__, ''.join(___))(_)
____ = __builtins__.str.__name__
______ = __builtins__.list()
__builtins__.list(map(______.append, ____))
______.pop(1 .__neg__())
______.pop(1 .__neg__())
______ *= 2
______.insert(1, chr(__builtins__.tuple(__builtins__.range(121))[-1] + 1))
__ = __(''.join(______))
_ = ....__class__.__class__.__mro__[-1].__getattribute__(__, ....__class__.__mro__[-1].__name__.__class__.__name__[:2] + __builtins__.dict().__class__.__name__[~-1] + __builtins__.BlockingIOError.__name__[(~(....__class__.__class__('',(__builtins__.int,), {})(-3 .__neg__()))) + 2] + ().__class__.__name__[~-2] + ().__class__.__name__[~-1]).write
___ = __builtins__.bytearray()
___.append(33)
___.append(dir(__builtins__).index(RuntimeWarning.__name__) * __builtins__.int(__builtins__.list((lambda: (yield from __builtins__.range(3)))().__iter__())[-1]))
___.append(ord(....__class__.__class__.__mro__[-1].__getattribute__([].__class__, dir(....__class__.__class__)[26])[0]))
___.append(ord(__builtins__.int.__rdivmod__.__name__[~-3]))
___.append(ord(....__class__.__class__.__mro__[-1].__name__[0]))
___.append(ord(dir(__builtins__.OSError())[-1][0]))
___.append(32)
___.append(44)
___.append(___[4])
___.append(___[2])
___.append(___[2])
___.append(ord(....__class__.__class__.__mro__[-1].__getattribute__(().__class__, '__name__')[-1]))
___.append(72)
_(bytes(reversed(___)).decode())
@steep mural :white_check_mark: Your eval job has completed with return code 0.
Hello, world!
I wish they had an equivalent of getmembers that only returned unique members
IDK if this case is esoteric enough but I'm just looking for general advice. I have an application that's going to run on a Raspberry Pi with Picore, that needs to log some of the data it records as 'lifetime' statistics. But power could be cut at any time, unpredictably, and there's a small chance that would corrupt the file. I need to make that a 0% chance.
What do you guys think of this strategy; setup a rotating series of log files, after writing to each file check and store the hash and datetime in a tiny 2nd file, and then when I need to retrieve these data after reset pick the most recent log with a valid hash?
You should ask in #tools-and-devops. This channel is for weird and unholy things.
Ty error fixer upper 🙂
wait what call.call?
lol
how do you get letters with that? looks like jsfxxk but pyfxxk lol
It basically does ```py
"%c"*5%(63,64,65,66,67)
'?@ABC'```
It also abuses the fact that booleans are ints, using ()==() instead of 1
It's not that esoteric, but it's a start ```py
(lambda mod: print(True) if import(mod).class.module == "builtins" else print(False))("math")
any starter codes?
yes
im just kidding, do you need starter code for esoteric python or regular python
@wind token
!e
(lambda mod: print(True) if __import__(mod).__class__.__module__ == "builtins" else print(False))("math")
@cloud garden :white_check_mark: Your eval job has completed with return code 0.
True
How do you guys even understand this
!e ```py
, _ ,*=builtins.range(1 << 10)
_ <<= int.abs(....class.class('', (builtins.int,), {})(6 . neg().str()))
, * = bytearray((lambda: (yield from builtins.list({3,ord(str(...)[0])})))().iter())
_ *= int((____ ** 0.6) * 0.9)
_ += builtins.int.abs(int(15.5 * 2) .neg())
_ = chr()
___ = [,,,_]
___.insert(2, chr(105))
___.insert(3, chr(114))
.insert(4, 't')
__ = lambda : (.insert(3, chr(109)), .insert(4, chr(111)))
(...)
.insert(4, 'p')
del __
__ = lambda : ....class.mro[-1].getattribute(builtins, ''.join())()
____ = builtins.str.name
______ = builtins.list()
builtins.list(map(.append, ____))
______.pop(1 .neg())
______.pop(1 .neg())
______ *= 2
.insert(1, chr(builtins.tuple(builtins.range(121))[-1] + 1))
__ = (''.join())
_ = ....class.class.mro[-1].getattribute(, ....class.mro[-1].name.class.name[:2] + builtins.dict().class.name[~-1] + builtins.BlockingIOError.name[(~(....class.class('',(builtins.int,), {})(-3 .neg()))) + 2] + ().class.name[~-2] + ().class.name[~-1]).write
___ = builtins.bytearray()
___.append(33)
___.append(dir(builtins).index(RuntimeWarning.name) * builtins.int(builtins.list((lambda: (yield from builtins.range(3)))().iter())[-1]))
___.append(ord(....class.class.mro[-1].getattribute([].class, dir(....class.class)[26])[0]))
___.append(ord(builtins.int.rdivmod.name[~-3]))
___.append(ord(....class.class.mro[-1].name[0]))
___.append(ord(dir(builtins.OSError())[-1][0]))
___.append(32)
___.append(44)
.append([4])
.append([2])
.append([2])
___.append(ord(....class.class.mro[-1].getattribute(().class, 'name')[-1]))
_.append(72)
(bytes(reversed()).decode())
@grand tree :white_check_mark: Your eval job has completed with return code 0.
Hello, world!
cool
people just learn what each thing does, and adds them together
So whats the purpose of esoteric py
Check pins of the channel for definition of esoteric python @sick hound
As for purpose it doesn't really have one other than looking cool and I guess obfuscation
Like no one in their right mind would think "oh yea that's hello world" for #esoteric-python message
How to convert py file into executable exe or executable file?
How would you go about hashing the code of a function (I want to use that to invalidate a cache if the implementation change)? Is hash(function.__code__) good enough, or I should hash all the co_ attributes?
If you are wondering, I ended up using
function_hash = sha1(inspect.getsource(callback).encode())```
!e
TargetEmail = 'testaccount@gmail.com'
Name, DomainToSplit = TargetEmail.split('@')
Domain = DomainToSplit[:1]
DomainConf = requests.get(Domain)
if DomainConf.status_code is 404: print("Please Use A Valid Email Address."); exit
else: pass
@toxic jewel :x: Your eval job has completed with return code 1.
001 | File "<string>", line 3
002 | Domain = DomainToSplit[:1]
003 | IndentationError: unexpected indent
oh lol
!e
TargetEmail = 'testaccount@gmail.com'
Name, DomainToSplit = TargetEmail.split('@')
Domain = DomainToSplit[:1]
DomainConf = requests.get(Domain)
if DomainConf.status_code is 404: print("Please Use A Valid Email Address."); exit
else: pass
@toxic jewel :x: Your eval job has completed with return code 1.
001 | File "<string>", line 6
002 | else: pass
003 | IndentationError: unexpected indent
ugh
is this in #esoteric-python because of the non-pep8 variable names or did you just not read the channel description?

the first module i ever wrote https://paste.pythondiscord.com/funorularo.sql i still dont understand how i wrote it
i still dont understand how i wrote it
nice 👍
My guess is that you typed it on a computer
thank you i never would have guessed
,,, now... Why is it that when I want to import an arbitrary file my first instinct is not to use importlib and instead decide to use exec and globals?
Too much time here
How would you guys obfuscate numbers in a fairly efficient way?
space-efficient, not time-efficient
I've been thinking of how you can get 0 and 1 with boolean checks, and with bit shifts you can get higher numbers, but that easily gets out of hand

how would you do that tho
especially without importing anything or creating new funcs
I'd also prefer to avoid strings or bytes
a=lambda b:b<(()==())<<(()<=())and[]>=[]or a(b-(()==()))+a(b-(([]>=[])<<([]==[])))
beautiful
In [50]:[*map(a, range(10))]
Out[50]: [True, True, 2, 3, 5, 8, 13, 21, 34, 55]
```While it looks like an issue it should work in 99% of cases
heres some very weird compact code
dont mind using namespace std lol that was for a meme
You can convert them to int if it matters by using unary +.
for c in map(chr, [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]): print(c, end = "")
somewhat esoteric Hello, world! program using chr and map
I tried to use regression and numpy to get a polynomial that returns the character codes for Hello, World! for inputs 0..12, but it ended up being very sensitive to the coefficients
f(12) gave me -24072.868139308062, and I was using pretty precise coefficients
lol
are there case statments in python
Not as such, recomended "Pythonic way" is to use ```py
if ():
elif ():
elif ():
elif ():
else:
If you scroll up about a month someone posted a way to make with blocks do something weirdly similar.
yes there are, if you try hard enough
IIRC, @formal sandal found a way to do that with context managers
Oh they’re typing right now
^ Yep, I did this atrocity: https://github.com/decorator-factory/context_manager_patma
I used them to improve readability of some thing I did, and I think it worked out well https://github.com/decorator-factory/python-fnl/commit/8f877c94fb98408f551e6a7f6b32213e2e44b0cd?branch=8f877c94fb98408f551e6a7f6b32213e2e44b0cd&diff=split#diff-9cf42d8a3e3dc179388790be4fa8e897dbec989ac3740d7960e2c6dddad6899cL90
because all online sources that you can use dictionaries as a switch statment
You can, but that’s just not as pleasing as what fix error did
Yes you can, and you can use it with values, if none of your calcullations have side effects, or you can do it with lambda functions.
Wouldn’t lambda put quite a lot of restrictions for more complicated functions?
It’d be good for something small like a calculator
"switch-case" from C isn't particularly useful, it's not different from an if-else chain. Pattern-matching like in Rust/Haskell/Scala/Elixir/..., on the other hand, is also used for extracting data from a nested structure
so it is not really needed in python
pattern matching is nice, switch cases are less nice
::shrugs:: what is a lambda function, except a block of code, what is a case statement except a block of code. if you define it the very statement before you extract it from a dict to execute you don't even need to give it any args, it's operating on the local environment where it was just defined.
Unless you need the non-break fall through behavior of c in which case... you need something different anyway.
Probably you could make fix error's pattern into what you need.
I played around with fix error's thing to make it act like c or basic or something else, I don't know where I put it at this point.
yeah, what are programs except for blocks of code
I didn't like the [m] part of the syntax but couldn't get rid of it except for things even worse.
On a side note, I found something interesting that someone said from #python-discussion
i realised that i have zero idea how to type recursive iterables.
Was wondering if anyone knew how to do this
It's pretty much necessary unfortunately, in order to catch exceptions in __exit__ and to actually bind match values
recursive like [(x,y) for x in range(10) for y in range(20) if x % 2 == 1 and y % 3 == 1]?
As in,
Yeah, but for example type for recursive list you can have list[Union[list, int]. But you can go deeper, list[Union[list[Union[list, int]], int], ect...
That's what I figured out. And I agree. There are other ways to inject errors into a code context but nothing so straghtforward. requiring so few characters to type.
oh that meaning of type
Well, you can't really get around that. You somehow need to break out of the with right away if the match doesn't occur.
An alternative would be to rely on cpython shenanigans and stack frames which is arguably worse (or better, according to #esoteric-python)
I could ditch withs and do this:
for arg in args:
with match(arg) as case, m:
...
if case('Quoted(Name(name)|String(name))'):
options.append(m.name)
if case('Quoted(Sexpr(Name(name), String(value)))'):
options.append(f"{m.name}={json.dumps(m.value)}")
or
for arg in args:
with match(arg) as case:
...
if case('Quoted(Name(name)|String(name))'):
options.append(case.name)
if case('Quoted(Sexpr(Name(name), String(value)))'):
options.append(f"{case.name}={json.dumps(case.value)}")
It would be nice to be able to say: IntOrList = Union[list[IntOrList], int]
Recursive = Union[List["Recursive"], int] should work, but e.g. mypy might not support it
IIRC, some person used eval or exec to make higher order functions and got indentation error
Once when I had to I said something like:```py
IntOrList = Union[list, int]
for x in range (14):
IntOrList = Union[List[IntOrList], int]
Only worse, and I was annoyed by the non-aestheticness of the solution.
I suspect the correct answer involves templates, but I don't know how to do it either.
Wonder if that could be done for types
You might be able to use Protocol
Anyway, see: https://github.com/python/mypy/issues/731
Here
Oh
see
Pyright/Pylance does 😛
It is available as a VSCode extension or a command line tool
Hello.
Can anybody think of a way to de-uglify this:
for colour, rect in tuple(active_rectangles.items()):
# the second half of the check isn't ideal but prevents a few headaches and keeps CC down
if colour not in active_colours and image[y + 1][rect.xmin] != colour and image[y + 2][rect.xmin] != colour:
rect.ymax = y - 1
final_rectangles.add(rect)
del active_rectangles[colour] # remove before intersections check
rect.set_deactivation_intersections(active_rectangles.values(), image[rect.ymax])
(a) I am iterating a new tuple instance each time, so to remove items from the iterated dictionary ... that's bad
(b) the second line check is really verbose
I could use something like: if colour not in active_colours | {image[y+1][rect.xmin], image[y+2][rect.xmin]}:
... but it's much slower (I assume due to the creating of the new set).
Eh, you’re asking people in #esoteric-python to de-uglify your code? I think most people’s objective here is to uglify it.
And even if someone did attempt to refactor this on a deeper level, it wouldn’t be possible because we don’t know what your classes/methods do.
Nonsense @sick hound! Lambdas, maps, filters and the lot are as a cute as kittens.
Esoteric is pretty.
Wtf
This is pretty?
I find esoteric cool, never really thought of it as elegant or pretty...
@golden comet No, that's not pretty. But the intent was obviously to confuse readers there. It seems to me that functional tools in Python, although a bit awkward, have a high expressive potential. Concise code is prettier. Mine, above, isn't.
i need help
where do i get help
do i just ask?
i am building a website using html but i also need to use python to transfer info into a csv file
i need help
this isn't the right channel for that, check out #❓|how-to-get-help
just having some fun with esoteric code, and i think i made something functional with it! ```py
class Test:
pass
(lambda: print(f"Normaly calling str: {Test().str()}\nCalling str with my func: {(lambda obj: None if f'{name}.{obj.class.name} object at ' in obj.str() else obj.str())(Test())}"))()
@terse mortar What is this even supposed to do
!eval ```python
class Test:
pass
(lambda: print(f"Normaly calling str: {Test().str()}\nCalling str with my func: {(lambda obj: None if f'{name}.{obj.class.name} object at ' in obj.str() else obj.str())(Test())}"))()
@marsh void :white_check_mark: Your eval job has completed with return code 0.
001 | Normaly calling __str__: <__main__.Test object at 0x7fc97db487f0>
002 | Calling __str__ with my func: None
I guess to not use the default behavior
so i dont have to see the <__main__.Test object at 0x7fc97db487f0> part if they dont set __str__ in their class.
haha yes None is much better
Anyone knows what ... means in the following scenario x[..., np.newaxis].astype(np.float32)
it basically means all other axis, so that np.newaxis is applied to the last axis without needing several [:, : ... np.newaxis], in future, data science is probably better place to ask
in my very humble opinion, yes
@vague hearth without needing several what :D?
: to select each axis
the ... in his case skips over every axis of the array except the last one which np.newaxis is then applied to
best way to understand it may be to jump into a repl session and create a high dimension array and experiment
if you want more help ping me in a help channel because this isn't really on topic for this channel
@glad isle
no
. @glad isle
You can mutate globals()
nice
!e
or something like this
xs = [0]
f=lambda:xs.__setitem__(0,530)
f()
print(xs)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
[530]
Hey @quick stag, see #❓|how-to-get-help
ok
this channel was recommended to me after i suggest using string.__len__() instead of len(string)
i feel at home here
Good now please stay in here
Can I ask why did you suggest that? 😄 is it better on performance or something?
look at the channel we're in
no i just like watching the world burn
Oh! 
!e print("Hello World".len())
@terse mortar :white_check_mark: Your eval job has completed with return code 0.
11
Cursed.
!e
@print
@" ".join
@list
@hex
@len
@str
def hello_world():
...
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
0 x 2 8
xDDDD
Lol that looks like JavaScript or something
Python 3.9's relaxed syntax on decorators looks cool
yeah, you can do crazy things
takes off glasses "function composition"
basically, yeah
but only at definition
also, hello_world is now None
!e py @print @" ".join @list @hex @len @str def hello_world(): ... print (hello_world)
@naive roost :white_check_mark: Your eval job has completed with return code 0.
001 | 0 x 2 8
002 | None
!e
def a():
@yield
def b():
return 5
return b()
a().send(lambda f: lambda g: f()+5)
@proper vault :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | @yield
003 | ^
004 | SyntaxError: invalid syntax
that would be pertty cool
yield is a keyword, you can't assign...
yield is an expression
or more accurately, it's not a callable
!e
@__import__
@(lambda f: f.__name__)
def sys():
...
print(sys)
@steep mural :white_check_mark: Your eval job has completed with return code 0.
<module 'sys' (built-in)>
!e ```py
@5
def hello():
pass
@naive roost :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | TypeError: 'int' object is not callable
!e
def a():
@(yield)
def b():
return 5
yield b()
a = a()
next(a)
print(a.send(lambda f: lambda: f()+5))
@proper vault :white_check_mark: Your eval job has completed with return code 0.
10
so apparently, you've made it callable... need to wrap an expression inside parens to make them callable?
yield results in whatever you send to the generator if you make it an expression
but unlike most expression keywords like not, it can also be a statement, so you often need to put it parens
so the grammar is decorator: '@' namedexpr_test NEWLINE
basically, anything that's valid as a "while", "if", or "elif" condition is a valid decorator expression (up to parentheses)
oh, no sorry, the reference says : decorator ::= "@" assignment_expression NEWLINE
oh, imagine walrus in decorators
!e
import builtins
import operator as ж
@lambda c:c()
class Ж:__getitem__=ж.itemgetter;__getattr__=ж.attrgetter;__call__=lambda _,f:lambda a:f(*a);ь=lambda _,f,g:lambda h:(f(h[0]),g(h[1]));ъ=lambda _,f:lambda x:f(x[0])(x[1])
@Ж.ъ(lambda x:x)
@Ж.ь(lambda f:f(builtins),str)
@Ж.ь(ж.attrgetter,str)
@Ж[::2]
@Ж(ж.concat)
@ж.attrgetter("co_names","co_consts")
@Ж.__code__
def hello_world():
print <- "Hello, world"
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
Hello, world
wtf
damnnn
^
!e
(lambda ж,й:(lambda Ж:Ж.ъ(lambda x:x)(Ж.ь(lambda f:f(й),str)(Ж.ь(ж.attrgetter,str)(Ж[::2](Ж(ж.concat)(ж.attrgetter("co_names","co_consts")(Ж.__code__(lambda: print <- "Hello, world"))))))))(type("",(),dict(__getitem__=ж.itemgetter,__getattr__=ж.attrgetter,__call__=lambda _,f:lambda a:f(*a),ь=lambda _,f,g:lambda h:(f(h[0]),g(h[1])),ъ=lambda _,f:lambda x:f(x[0])(x[1])))()))(__import__("operator"),__import__("builtins"))
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
Hello, world
ah
understandable
I defined ж in the REPL before, so it used to work
just don't confuse it with Ж
Very hard to confuse those two
this made me laugh really hard
its simple, but im starting well i think
!e
_ = ()==()
____ = "%c"*5%(((_+_)*int((72/2))),((_)*(69)),((_+_)*int((76/2))),((_+_)*int((76/2))),((_)*(79)))+" "+"%c"*5%(((_)*(87)),((_)*(79)),((_+_)*int((82/2))),((_+_)*int((76/2))),((_+_)*int((68/2))))
print(____)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
HELLO WORLD
!e
_=()==()
__=(_+_)+(_+_)
___=(__*__)
____ = "%c"*(_+_+_+_+_)%(((_+_)*int(((___*__+(__+__))/(_+_)))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)-(__))/(_+_)))))
print(____)
@fossil estuary :white_check_mark: Your eval job has completed with return code 0.
HELLO WORLD
haaaa
what in the name of all things holy
why do you do int()
!e ```py
print((lambda x: "".join([w.replace(w[0], w[0].upper()) for w in x.split(' ') if w not in [' ', '']]))("hello there boises"))
@hidden radish :white_check_mark: Your eval job has completed with return code 0.
HelloThereBoises
hm
portability?
because division makes it a float for some reason 🤷♂️
Okay, thank you.
but it will break it for python2
I use 3.9
with int() it works anywhere
Well, that broke it 😅
anyone heard of the programming langauge brainfuck? https://www.google.com/search?q=brain+fuck+programming+langauage&rlz=1C1SQJL_enLB892LB892&oq=brain+fuck+programming+langauage&aqs=chrome..69i57.7285j0j7&sourceid=chrome&ie=UTF-8
!e ```python
#I don't expect this works if the first letter of a word is repeated in the word.
print((lambda x: "".join([w.replace(w[0], w[0].upper()) for w in x.split(' ') if w not in [' ', '']]))("test"))
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
TesT
I literally just learned about esoteric code and now I find this channel. I need to explore more
what does "esoteric" mean
making shit as ugly and unreadable as possible.
jkjk, altho thats basicly all that happens here.
The channel subject says: Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness
I think a language like Coconut (which I particularly like but sadly don't use that much), which is transpiled into Python (and is a strict superset of Python) might also count as esoteric, but I'm not sure
@thin trout :white_check_mark: Your eval job has completed with return code 0.
_='_=%r;print (_%%_)';print (_%_)
The fuck haha
try adding syntax highlighting to it
_='_=%r;print (_%%_)';print (_%_)```
it looks a lot more sensible now, doesn't it

_='_=%r;print (_%%_)';print (_%_)
^^^^^^^^^^^^``` this bit
Oh, it is just duplicating the content?
@formal sandal :warning: Your eval job has completed with return code 0.
[No output]
well, it shows "no output", but it's actually empty
the %r turns into the string, the rest of the string is a duplicate of the code around the string
yes it does. Its called a quine. The output is the same as the code itself
Sorry, first time here. My bad😅
I somehow can never wrap my head around a quine
Ooh, that's cool
(Reposting from #internals-and-peps )
Fun challenge: explain why this snippet segfaults the cpython interpreter (requires cpython 3.8+)
(lambda:0).__class__(eval(f"lambda:{list(range(99999))} if 0 else -1").__code__.replace(co_consts=()),{})()
!e
minimal example:
def f(): return None
print(f.__code__.co_consts)
f.__code__ = f.__code__.replace(co_consts=())
# to return None, the constant at the index 0 will be looked up, but there isn't one:
f()
@formal sandal :x: Your eval job has completed with return code 139 (SIGSEGV).
(None,)
The reason I have the list(range(99999)) is because it leaves more room for Fun Stuff on the heap 😛
I had a version written for pypy that would crash some percentage of the time, and other times return garbage
quines are cool
@radiant anchor because on a low level, when the interpreter hits the opcode LOAD_CONST 0 it attempts to read out of bounds on that tuple (due the Python/ceval.c accessing the tuple directly, not through its safe methods) and the bytecode created by a function will always have a LOAD_CONST 0 even if empty
!e ```py
import dis
def f():pass
dis.dis(f)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 3 0 LOAD_CONST 0 (None)
002 | 2 RETURN_VALUE
it is possible to build a valid code object that does not use co_consts but the code object needs to be built manually
the code that actually causes the segfaults is here c case TARGET(LOAD_CONST): { PREDICTED(LOAD_CONST); PyObject *value = GETITEM(consts, oparg); Py_INCREF(value); PUSH(value); FAST_DISPATCH(); } https://github.com/python/cpython/blob/804d6893b801e8f30318afc38c20d4d0e6161db3/Python/ceval.c#L1624
which calls GETITEM which is a macro for #define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
and PyTuple_GET_ITEM is #define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i])
if python is compiled with debug flags, then this would likely not cause a segfault, and would instead raise an IndexError from PyTuple_GetItem which is used for GETITEM when built with Py_DEBUG defined
guess what this code prints https://hastebin.com/oditesesox.php
Is it a Quine. It seems like it would be somehow lmao
It crashes pythonista. I’ll have to run it when I get to my laptop.
it just sums a bunch of int(True)s (that returns 1) and then uses chr to find the character based on that sum
i'm only starting with esoteric python too
Yeah when I added word wrap I seen it was way longer than I thought than I thought lol.
lol
Here's some fun I had using that LOAD_CONST bug: https://github.com/DavidBuchanan314/unsafe-python
No need to sum int(True)s, you can just sum Trues :v)
oh yeah
@radiant anchor that is clever
Check out the shellcode_example.py script I just added 😛
i really want to write a pyctypes that has all the features of ctypes in pure python now
Yeah that's kinda my end goal
It'll probably involve automatic ROPchain construction
yea
Finding the ELF base etc. is kinda tricky, although I do have some code that does it semi-reliably
I consider /proc/self/maps to be cheating
👀 auto convert python bytecode to asm would be cool
converting between c values and python values would be tricky
nah that's easy
like, the cpython interpreter has functions for that
just call them via rop
or as part of shellcode
well you could just construct simple types manually if you dont want to bother with the rop there
True
@radiant anchor if you dont mind, i might implement some of these strategies in my fishhook module
to reduce the reliance on ctypes
Sure
seems to be running into issues in python3.9
yea it doesnt work on 3.9 ill try to figure out where it fails
ok
I'm installing 3.9 now so I'll also take a look
strange. What OS are you on?
I'm guessing either BYTES_HEADER_LEN or TUPLE_HEADER_LEN needs tweaking
nice
I wonder if there's a reliable way to detect BYTES_HEADER_LEN and TUPLE_HEADER_LEN at runtime
maybe like, allocate a bunch of them and observe the minimum distance between their id()'s
minus the libc heap overhead
object().__sizeof__() returns 16 (refcount, ob_base)
on a tuple its a variable type, so it has another field, ob_size
@radiant anchor use ().__sizeof__() it returns the size of an empty tuple
woah I had no idea __sizeof__ was a thing, tyvm
which is just the tuple header with a 0 ob_size
are they different on 3.8 and 3.9?
hm
ok I can reproduce the 2 bug on 3.9
ah
the problem is with how it builds co_consts
on py3.8 it looks like, for example (None, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
on 3.9 it looks like (None, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 13)
I need to make it not do that...
damn optimisations...
ah, If you're gonna talk about quines, you have to mention the uroboros quine https://github.com/mame/quine-relay
its a thing of beauty
@radiant anchor this is super clever tho
ty
would it not be easier to make the bytecode for LOAD_CONST yourself?
because then you dont run the risk of the compiler optimizing anything
That's what I was doing originally lol
the problem is, the bytecode changes between python versions
and until 3.9 came along, my method worked on every version, lol
I think I can find another
@radiant anchor your setrip wont work on 3.9 either because FunctionType uses vector call
rip
thats easier to fix tho, just unset a flag on the type to disable it
also you can get the opcode for LOAD_CONST dynamically without imports right? py def get_load_const(): f = lambda:None code = f.__code__ for op, arg in zip(code.co_code[::2], code.co_code[1::2]): if len(code.co_consts) < arg and code.co_consts[arg] is None: return op
wait that doesnt work on py2.7
@rugged sparrow fixed it
rather than putting the numbers in a big array, they're now in function arguments
also setrip() seems to work fine
I think the flag is already cleared
for vectorcall
it shouldnt be?
$ python3.9 shellcode_example.py
sh-5.0$
i was messing with patching tp_call on functiontype and it wasnt working
because of that flag
weird
When I instantiate it, everything after the type pointer is zeroes https://github.com/DavidBuchanan314/unsafe-python/blob/main/unsafe.py#L152
I think that's why mine works?
or is the flag in the FunctionType type object itself?
its in the functiontype type object
(it's actually been a while since I wrote that code)
in tp_flags
it segfaults for me on 3.9
with a traceback that looks similar to the vectorcall issue i was running into
huh, I wonder if we have different 3.9 sub-versions
whats yours?
The vectorcallfunc pointer may be NULL, in which case the instance behaves as if Py_TPFLAGS_HAVE_VECTORCALL was not set: calling the instance falls back to tp_call.
what's that random hex offset
Python 3.9.0 (v3.9.0:9cf6752276, Oct 5 2020, 11:29:23)
how do you get the full version string?
its at the start of the interpreter
Python 3.9.0 (default, Dec 6 2020, 01:25:29)
i just copied it
i used brew to install mine so it built when i installed
oh, that's just the refcount, its an arbitary nonzero value
also, technically the vectorcallfunc pointer shouldnt be null in your code
yeah
well its easier to just flip the flag
you sure?
its at a stable offset on the type
and you can find it if you need to
because you can get the flags value from the type
17568768
so you could encode that to bytes and just look from id(typ):id(typ) + type.__sizeof__(typ)
Really strange that it works on my machine though
well you also are instantiating an object larger than it should be
https://github.com/DavidBuchanan314/unsafe-python/blob/cc61ab7eeb8d8a832f06e540a0b5542e32972575/unsafe.py#L143 should use type.__sizeof__(FunctionType) instead of 0x800
been there since before 2.7
and yea it shouldnt, but you dont know whats after the FunctionType object in your version
cause the vectorcallfunc can be placed directly after (but that depends on the compiler) afaik
which is why it would cause an issue on mine and not yours
oh interesting
yea so its safer to just use type.__sizeof__ (you need to use that one because FunctionType.__sizeof__ is an overloaded method for getting the size of a func object)
'''"""""'''''safer'''"""""'''''
looks really fun though
hmmmm are you sure that FunctionType.sizeof() gets the size of the type
TypeError: unbound method object.__sizeof__() needs an argument
like, isn't it supposed to be called on an instance
at first i assumed it was for interfacing with old badly memory managed c libraries
then i realised it's mostly for breaking stuff
is FunctionType.__sizeof__(FunctionType) valid
tbh I'm still not sure exactly what its for
ah
yea thats gotten me a few times too
if you want a universal sizeof method here py def sizeof(obj): return type(obj).__sizeof__(obj)
that will work on any pyobject
ty, I'll use that
just pushed an update that uses that for BYTES_HEADER_LEN etc. too
noice that should get rid of all your magic numbers right?
@radiant anchor still getting a vector call related segfault
yeah I wasn't expecting that to be fixed yet
the last magic number is the 0x100
how do I get the size of a FunctionType instance
so tp_flags is a c_long at the offset 21 * (ptrsize)
I guess I can sizeof any function?
is tp_vectorcall also always at a fixed offset?
if you unset the flag then itll ignore the tp_vectorcall slot
segfault again
interesting
Would you mind testing with my_functype[50*8:50*8 + 8] = p64a(0) added?
I believe that should clear tp_vectorcall
yea one sec
segfaulted again
can you get any more details about the segfault?
0 ??? 0x0000000108df301b 0 + 4443811867
1 org.python.python 0x0000000108b358fc call_function + 876
2 org.python.python 0x0000000108b32e2b _PyEval_EvalFrameDefault + 25371
3 org.python.python 0x0000000108a5fa28 function_code_fastcall + 104
4 org.python.python 0x0000000108b3586c call_function + 732
5 org.python.python 0x0000000108b32d93 _PyEval_EvalFrameDefault + 25219
6 org.python.python 0x0000000108b36563 _PyEval_EvalCode + 2611
7 org.python.python 0x0000000108b2c9eb PyEval_EvalCode + 139
8 org.python.python 0x0000000108b7f352 PyRun_FileExFlags + 434
9 org.python.python 0x0000000108b7e92f PyRun_SimpleFileExFlags + 831
10 org.python.python 0x0000000108b9b7e9 Py_RunMain + 1801
11 org.python.python 0x0000000108b9bc7f pymain_main + 223
12 org.python.python 0x0000000108b9be7b Py_BytesMain + 43
13 libdyld.dylib 0x00007fff6e0e4cc9 start + 1```
wdym


