#esoteric-python
1 messages Β· Page 79 of 1
Behold
!e py add=lambda x, y: x + y sum=lambda iterable, start=None:__import__('functools').reduce(lambda x, y: f"{x}{y}", map(lambda g: __import__('functools').reduce(add, g[1], (start or 0, '')[g[0].__name__ == 'str']), __import__('itertools').groupby(iterable, key=type))) print(sum([1, 2, 3, 'h', 4, 10, 100, '5', 6, 7, '8'])) print(sum(range(10))) print(sum(map(str, range(10))))
@crystal mica :white_check_mark: Your eval job has completed with return code 0.
001 | 6h1145138
002 | 45
003 | 0123456789
I need help
nice
''.join(map(str,__import__('functools').reduce(lambda a,v: (([a+v] if v*0 is 0 else str(a)+str(v)) if a*0 is 0 else (((a[:-1]+[a[-1]+v] if v*0 is 0 else ''.join(map(str,a))+str(v)) if a[-1]*0 is 0 else ([a]+[v] if v*0 is 0 else ''.join(map(str,a))+str(v))))),['19',28,'4',67,6])))
Oh, this will always return a string
A simple fix, but it is awful enough
heheh
python is now LISP
from typing import Tuple, Any
def eval_arg(tup: Tuple):
return tup[0](*tup[1:]) if hasattr(tup[0], "__call__") else tup[0]
def thread_first(*args: Any):
var: Any = eval_arg(args[0])
for cmd in args[1:]:
if isinstance(cmd, tuple):
var = eval_arg((cmd[0],var) + cmd[1:])
else:
var = eval_arg((cmd, var))
return var
def thread_last(*args: Any):
var: Any = eval_arg(args[0])
for cmd in args[1:]:
if isinstance(cmd, tuple):
var = eval_arg(cmd+(var,))
else:
var = eval_arg((cmd, var))
thread_last(
(range, 20),
(map, lambda x: x+4),
list,
print
)
thread_first(
(range, 20),
(sum, 8),
(pow, 6),
print
)```
just look at Hy
@proper vault best to use callable rather than check for __call__
Oh, did not know of that
You're allowed subscripts in assignment patternsβ½
Yes
!e ```py
a = [1, 2, 3]
for a[:] in [[4, 5, 6], [7,8,9], [10, 11, 12]]:
print(a)
@distant wave :white_check_mark: Your eval job has completed with return code 0.
001 | [4, 5, 6]
002 | [7, 8, 9]
003 | [10, 11, 12]
Hm, perhaps not the best example
!e ```py
a = [1, 2, 3]
for a[-1::1] in [[4, 5, 6], [7,8,9], [10, 11, 12]]:
print(a)
@distant wave :white_check_mark: Your eval job has completed with return code 0.
001 | [1, 2, 4, 5, 6]
002 | [1, 2, 4, 5, 7, 8, 9]
003 | [1, 2, 4, 5, 7, 8, 10, 11, 12]
ok, that's lit
the biggest takeaway is that Hello Satan is infinitely better than Hello World
may we rewrite all programming texts
!e ```py
a = []
for a[-1::1] in "Help lom Satan".split(): pass
print(''.join(a))
@distant wave :white_check_mark: Your eval job has completed with return code 0.
HelloSatan
Sneaky!
Sneaky!

Sometimes I feel just so embarrassingly stupid...
Recently I started learning Elixir.
In Elixir, you can get the ASCII code of a character like this:
?a (= 97)
Knowing that, I stumbled by accident at the fact that ?* = 42
For a few minutes, I genuinely thought it was an easter egg!
Just couldn't connect the two pieces of information together.
ascii egg
haha. that would be a very cool easter egg
AOC spoiler ||print((lambda np:(lambda o:(lambda f,r,a:f(f,r,a))(lambda f,r,a: f(f, r+a, np.clip(a//3-2, 0, np.inf)) if np.any(a) else np.sum(w),o,o//3-2))(np.loadtxt('aocin.txt')))(__import__('numpy')))||
You can mentally desugar it
i keep trying π
for a[1::-1] in ["abc", "123", "def"]:
\/
i = iter(["abc", "123", "def"])
while i:
a[1::-1] = next(i)
π
well yea
Yeah, that's not functional code per say
something like
while True:
try:
a....
except StopIteration:
break
mhm
Hi does anyone know how to remove all tags in an html document except a few? For example, let's say I have <title>, <head>, <body>, <author> tags, but only would like <title> and <author> to show in the document. Is that possible, if so how? I've heard of regexp but not sure how to create it in this example.
You could use BeautifulSoup, I guess.
This isn't really esoteric, so I think it belongs to #help-n
Hi guys
Everyone in this channel can now use the eval command
3.8 is also coming soon
enjoy
!e
class dope:
def __matmul__(self, other):
print("That's dope!")
back = you = dope()
back@you
@zealous widget :white_check_mark: Your eval job has completed with return code 0.
That's dope!
got there
I believe that constitutes abuse of some sort
!e
print(int(''.join(str(ord(c)&1^1) for c in "ββββββββββββββββββββββββββββββββ"),2).to_bytes(len("ββββββββββββββββββββββββββββββββ")//8,'big').decode())
@edgy kelp :white_check_mark: Your eval job has completed with return code 0.
cool
!e ```py
import this
@pure dew :white_check_mark: Your eval job has completed with return code 0.
001 | The Zen of Python, by Tim Peters
002 |
003 | Beautiful is better than ugly.
004 | Explicit is better than implicit.
005 | Simple is better than complex.
006 | Complex is better than complicated.
007 | Flat is better than nested.
008 | Sparse is better than dense.
009 | Readability counts.
010 | Special cases aren't special enough to break the rules.
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ewecuxelug
that zen doesn't belong here
read from right
shush
write some algorithm to calculate the readability of the code of course
when an is is present swap first and last words
if "is" in zen_line:
zen = zen_line.split()
zen[0], zen[-1] = zen[-1][:-1], zen[0]
print(" ".join(zen).capitalize())
there
!e
from contextlib import redirect_stdout
import io
f = io.StringIO()
with redirect_stdout(f):
import this
s = f.getvalue().splitlines()
s[2:8] = [" ".join([line.split()[-1][:-1].capitalize()] + line.split()[1:-1] + [line.split()[0].lower() + '.'])
for line in s[2:8]]
s[8] = " ".join([s[8].split()[0], "doesn't", s[8].split()[-1][:-2] + '.'])
s[9] = " ".join(s[9].split()[:2] + [s[9].split()[2][:-3]] + s[9].split()[3:])
print("\n".join(s[3:10]))
@zealous widget :white_check_mark: Your eval job has completed with return code 0.
001 | Implicit is better than explicit.
002 | Complex is better than simple.
003 | Complicated is better than complex.
004 | Nested is better than flat.
005 | Dense is better than sparse.
006 | Readability doesn't count.
007 | Special cases are special enough to break the rules.
welp
awese
>>> back = you = type('dope', (object,), {'__matmul__': lambda self, other: print('That\'s dope!')})()
>>> back@you
That's dope!``` heh
huh. type.__init__ does parameter count validation, but no actual logic (or parameter type validation)
>>> type.__init__(C, 'name', (B,), {'a':1})
# no effect on C
>>> type.__init__(C, '', '')
TypeError: type.__init__() takes 1 or 3 arguments
>>> type.__init__(C, '', '', '')
# no error```
all the actual work is obviously in type.__new__
just thought that was interesting
we made 4 into 5 ```py
import ctypes
ctypes.memmove(id(4), id(5), 28)
1712680048
4
5
4 == 5
True```
but then what's -4?
>>> -4
-5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: raw write() returned invalid length 5 (should have been between 0 and 4)
-5```
>>> -4
-5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: raw write() returned invalid length 5 (should have been between 0 and 4)
-5
>>> -4
-5
-5
>>> -4
-5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: raw write() returned invalid length 5 (should have been between 0 and 4)
-5
>>> -4
-5
-5```
>>> x = -4
>>> x
-5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: raw write() returned invalid length 5 (should have been between 0 and 4)
-5
>>> x
-5
-5
>>> repr(x)
'-5'
>>> x
-5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: raw write() returned invalid length 5 (should have been between 0 and 4)
-5
>>> repr(x)
-5
'-5'```
???
last time I wanted to use memmove it was for True and False but the pesky 0 is shorter
!e import ctypes; ctypes.memmove(id(0), id(1), 28)
@marsh void :warning: Your eval job has completed with return code 139 (SIGSEGV).
[No output]
Wew
LOL
It doesn't preserve context through evals though does it :(
!e from ctypes import memmove as move; move(id(4), id(5), 28); move(id(5), id(5), 28); print(4, -4, 5, -5, 2+2, 2+3)
@marsh void :x: Your eval job has completed with return code 139 (SIGSEGV).
5 -4 5 -5 5 5
I mean they have different internal IDs
!e __import__('ctypes').memmove(id(4), id(5), 28); print(-4)
@marsh void :x: Your eval job has completed with return code 139 (SIGSEGV).
-4
oh yeah
!e x = 1
@grave rover :warning: Your eval job has completed with return code 0.
[No output]
!e x
@grave rover :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 'x' is not defined
ic

@whole kiln is there a way to get a persisting session so you can have setup code run once and then keep using some functions from that code over multiple evals
Especially useful testing esoteric stuff that has a pretty long setup
No there is not. It starts a new process for every invocation currently.
If you can think of a way to implement that then you're welcome to create an issue on the repo.
However, we may not want to go ahead with it even if you do have a design, but it will get the ball rolling at the least.
Maybe a last session optional trigger, so when user do !e -last x the bot will find the code used in the last time user did the !e
So py !e x = 10thenpy !e -last print(x)would print 10
We simply need to create a Dict[int, str] to store user id and the code used in the last successful !e
Then, we do not have to change anything
How does that sound @whole kiln
I'd say use -save and -load instead
That works too, but the general idea is that we have the bot stored the code somehow
Because you usually want to reuse the same context
Then we just append new code to it and eval in a new session
To the bot - still separated sessions
To us - looks like an ongoing session
That should actually be easily doable
Are you gonna PR that?
Or should I do it tonight
You should, I should finish my PRs first 
Aight
Perhaps. Sounds like it could all be client side which is nice. I would look into making the arguments proper d.py args instead of parsing a single string, if possible.
Also consider abuse prevention - like appending code to a session a load of times to eat up a lot of memory with the stored code. Will take a while with a 2k character limit but it could happen π€
I suggest you move this to #dev-contrib if you wanna discuss it more
Hmm
well it would still show any previous print statements unless you suppressed them
which isn't difficult to do
but, you know, just sayin
can we do this (with it actually working like intended)?
class EndMe:
def method(self):
self = EndMe()
ressign the current instance to a new one
x = EndMe()
y = x
print(x is y) # True
x.method()
print(x is y) # False``` like that?
or replace the entire object with a new instance?
On an example of a list,
you have a list a created with list()
>>> a = list()
>>> a.extend(range(10))
>>> id_a = id(a)
after calling the method
>>> a.method()
>>> a
[]
>>> id(a) == id_a
False
i can think of one way it might be doable
youd need to mess around with inspect
get the previous frame, use that to access the name of the variable referring to this instance
then there's the matter of reassigning it within that frame while taking into respect locals/globals, which im not entirely sure how to do without an exec
actually come to think of it im not sure how youd do it with an exec either
cause the locals/globals passed into exec wont really make a difference duration compilation i dont think
will need to check
you could use sys._getframe
import re
import inspect
from types import FrameType
name_regex = re.compile(r'([a-zA-Z0-9._]+).reassign_instance\(')
class ReassignInstanceInterface:
def reassign_instance(self, value):
frame_info: inspect.FrameInfo = inspect.stack()[1]
frame: FrameType = frame_info.frame
code_context = frame_info.code_context[0].strip()
name = name_regex.findall(code_context)[0]
frame.f_locals['_temp_value'] = value
exec(f'{name} = _temp_value', frame.f_globals, frame.f_locals)
# print(frame, code_context, name)
a = ReassignInstanceInterface()
a.reassign_instance([])
print(a)
here's a working rudimentary attempt
works (in this instance at least). will need some extra work to take into account some edge cases.
@crystal mica you can impl it, for reference see #677
also @brazen geyser you can find the name of the thing by getting into the frame bytecode
then just check for the LOAD_NAME/LOAD_FAST at the f_lasti index, and lookup in code names/varnames
!e x = 10
@silver prawn :warning: Your eval job has completed with return code 0.
[No output]
ooofed
:)
make a !repl command that automatically does last
Hate these big emojis
@pure dew that should do it? https://github.com/python-discord/bot/issues/676
not quite what imeant
i meant make !repl code a shortcut for !e -last code
reaction repeat is fun tho, my bot does that
wasnt that what yall were talking about?
Sorry, but you may only use this command within #bot-commands, #sir-lancebot-playground, #ot0-psvmβs-eternal-disapproval, #ot1-perplexing-regexing, #ot2-never-nesterβs-nightmare, #414574275865870337, #542272993192050698.
theres a nicer way of doing a repl, but it wont work so well with nsjail
they proposed that as a way to tie into the last executed code snippet
it would append the previous code to your current code
I mean, just edit it and re-run when we get the emoji in place
yea thats what i do for now
theres another bot that keeps an environment between commands tho
thats a pretty cool result
@grave rover consider cases like thing.a().c.d[2].a.reassign_instance(thing)
much easier to leave it to an exec than go through the bytecode and cover all resolution cases yourself
then you just give up at everything and go live in the mountains
raise FuckThisShitException
is abuse of __format__ esoteric enough? https://totally-not.a-sketchy.site/9Eth28h.png
- 24bit TrueColor support in my terminal
- Hex color parsing class
- ANSI escape codes
__format__abuse
here's code if you wanna poke around a bit https://paste.a-sketchy.site/avakigawal.py
only things not included are two exceptions which i cba to paste
cool, thankee
i'll post updates as i go along
im working on a framework for text interfaces with html in the terminal
I am doing ansii escaping though
Is there going to be a Christmas themed #esoteric-python challenge?
AOC
Esoterictize the AoC challenges
>>>mydic = {}
>>>mydic['a'] = []
>>>mydic['a'] += ['abc']
>>>mydic.setdefault('b', []) += ['def']
File "<input>", line 1
SyntaxError: can't assign to function call
>>>mydic.setdefault('c', []).extend(['def'])
>>>mydic
{'a': ['abc'], 'c': ['def']}``` π€
That's esoteric to me, I didn't know you can't use an operator on a value returned from a function
(assignment operator)
Py_SIZE(op) = size;
op->allocated = size;
_PyObject_GC_TRACK(op);
return (PyObject *) op;``` π€ ok do here is our initialization I guess
so .append is almost like set item kek
happy = (lambda a:(lambda b:a(lambda c:b(b)(c)))(lambda b:a(lambda c:b(b)(c))))(lambda g:(lambda m:(lambda f=(lambda y:(lambda x=sum(map(lambda z:int(z)**2,[s for s in str(y)])):x)())(m):m if f==1 else g(f))()))```
Function where you provide a number, if the sum of the digits squared is 1 then it is happy, if not recursively call it until either reaches 1 or goes into recursive hell and throws an error
Maybe someone could make a lambda pretty-printer? With actual lambdas!
lambda pretty printer??
if you were given a string of the source i support you could fuck with the AST
but given a raw function object you'd have to do some inspection π
Pretty printer with lambdas
Pretty printing what?
lambdas
@pure dew no he aint
With lambda lambdas you could just represent each function call and each function definition as a binary tree.
But in python, lambdas support keyword arguments.
Maybe you could replace this:
f = lambda n=123: n * n
print(f())
with this:
g = lambda n: n * n
f = lambda: g(123)
print(f())
and then it will work/
This isn't the channel for this.
If the code is written with lots of lambdas, it could be. Edit: ah
@lime viper assigning to a fucntion call would be a cool challange for this channel
f('x') = '3x+5'
assert f(4) == 17
it's invalid syntax so it wouldn't work that well if you just did it like that
@sick hound there are many ways to defer syntax errors
I have an idea for a collaboration with this channel π
#esoteric-python presents: mixin.py
https://github.com/SpongePowered/Mixin/wiki this but python
eh?
cant you do mixins already with ordinary classes?
seeing as we have multiple inheritance and all
this isn't mixins as you know it
this is bytecode patching at runtime
change parameters of functions you can't change etc
could you give an example?
I'll give an example from my recent project
E.G. You could patch the ImmutableMap class from guava to be mutable
@Mixin(TitleScreen.class)
class TitleScreenMixin extends Screen {
@ModifyArg(method="render(IIF)V",
at=@At(value="INVOKE",
target="Lnet/minecraft/client/gui/screen/TitleScreen;drawString(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;III)V",
ordinal = 0),
index=1)
public String modifyEdition(TextRenderer textRenderer, String version, int x, int y, int color){
if (CustomTitleScreenMod.config.customEditionEnabled) {
this.drawString(textRenderer, CustomTitleScreenMod.config.customEdition, x, y-10, color);
}
return version;
}
}```
What that does is modify the string parameter in this line. In this case it just does something when that function is called, but by returning something other than version I could modify what's passed to the drawString function
Thatβs java though
the idea is "[that] but python"
i just realized a mistake in my codes readability...i didn't use snake case
class BoopBoop():
def BorpBif(BepaBip, BupBup):
BapBif = BepaBip
Bip = ""
BopBip = Bip.join(BapBif)
BepBid = "urgle"
BufBip = (BopBip+" "+BupBup+BepBid)
print(BufBip)
def Bobbup(Blup):
BupBup = Blup
BefBip = {
"BabBab":"a", "BadBab":"b", "BabBap":"c", "BabBad":"d",
"BebBeb":"e", "BedBeb":"f", "BedBep":"g", "BebBed":"h",
"BibBib":"i", "BidBib":"j", "BidBip":"k", "BibBid":"l",
"BobBob":"m", "BodBob":"n", "BodBop":"o", "BobBod":"p",
"BubBub":"q", "BudBub":"r", "BudBup":"s", "BubBud":"t",
"BaabBaab":"u", "BaadBaab":"v", "BaadBaap":"w", "BaabBaad":"x",
"BoobBoob":"y", "BoodBoob":"z", "BoobBoop":" "
}
BepaBip = (BefBip["BoobBoob"],BefBip["BodBop"],BefBip["BaabBaab"],BefBip["BudBub"],BefBip["BoobBoop"],
BefBip["BodBob"],BefBip["BabBab"],BefBip["BobBob"],BefBip["BebBeb"],BefBip["BoobBoop"],BefBip["BibBib"],BefBip["BudBup"])
BoopBoop.BorpBif(BepaBip, BupBup)
def BipBop(BaapBip, Bup):
BupBeep = (BaapBip*Bup)
BepBep = (''.join(sorted(BupBeep)))
Blup = (BepBep[len("ba")]+BepBep[len("Boof")])
BoopBoop.Bobbup(Blup)
def BopBid():
Bup = len("Bap")
BoopBip = "BabBoop>>>"
BaapBip = input(BoopBip)
BoopBoop.BipBop(BaapBip, Bup)
if __name__ == '__main__':
BoopBoop.BopBid()```
what on earth
m,z,c,l,t,s,q,w=1,[0]*9,[[0]*3,[0]*3,[0]*3],lambda:{*map(sum,c),*map(lambda*a:sum(a),*c),sum(z[2:8:2]),sum(z[::4])},lambda i:' OX'[i],"-----".join(["\n{}|{}|{}\n"]*3),"789\n456\n123",lambda:not{-3,3}&l()
while w():a=int(input(q+s.format(*map(t,z[::-1]))+t(m)+" move"))-1;z[a//3*3+2-a%3]=m;c[a//3][a%3]and _;c[a//3][a%3]=m;m*=-1;all(z)and quit("Draw")
quit(t(-m)+" win")```
tic tac toe
@proper vault without running that is that player vs player or player vs com?
i want to make tic tac toe but has an "ai" as in the com looks what its best move is and trys to win
Minimax is the algo
Do you want a hard regex problem, the people of the esoteric land?
I don't want to see the solution of it π I can read the things above but regex is too much
It's not really about the usual regex.
Consider this regular expression language:
?means: 1 or more characters*means: 0 or more characters;*'s can only be located at the start or the end of a pattern.- any other characters is interpreted literally.
Given a list of words (or 2 words, for starters), produce any regular expression of that form maximizing the following function:
U(s) = (number of non-?* characters)*INF - (number of ?*-characters)
This is based on a task given to one of my university classmates in the coursework, and none of us has been able to solve it.
I was able to get the correct answer for some trivial cases:
But it fails for harder ones
Let me describe the algorithm
Given words abx and xab, collect all the patterns produced by shifting one string against the other one (I hope I managed to get the point across):
With abbbbc and axxxxxxxxxc I guess that I need to take two patterns and 'combine' them?
Like ?c x a? -> a?c
But this multiplication also needs to have access to the original words
As a bonus, he (the classmate) will have to do it in C.
seems like a a common subsequence style problem
Yes, that's the shift part.
But the parts can be spread out.
Like this:
Also, what's the optimal compelxity of this problem?
max(n,m)*(2**min(n, m))?
I would consider that an O(1) operation.
You mean... the time doesn't depend on the length of the strings?
That's certainly not true.
Are n and m numbers?
min and max aren't O(1) so that operation certainly isn't aswell.
Wait...
As a software engineer i'd say n**m from your formula.
I wasn't asking about the complexity of computing max(n,m)*(2**min(n, m)).
The computer science guys should be able to give a better answer π
I mean that the complexity of the problem above is O(max(n,m)*(2**min(n, m)))
Right, that makes more sense.
You can eliminate the max multiplication because there's an exponential.
In that case I need to brush up on my O notation.
Is it only addition that's eliminated?
f(x) = O(g(x)) if lim[x -> inf] f(x)/g(x) = const (or something like this) where const > 0.
lim (n*2**n)/(2**n) = n , and n is not constant.
No, I think it's actually big theta
!e ```py
amidakuji = lambda ladders, n=[0], sladders=[]: sorted(range(len(ladders[0])+1), key=lambda r: [i[0] - 1 for i in (sladders.clear(), sladders.extend(["0"*len(ladders),] + ["".join(i) for i in zip(*ladders)] + ["0"*len(ladders),]), [[n[0] for n[0] in [n[0] + 1 if (sladders[n[0]][step] == "1") else (n[0] - 1 if sladders[n[0]-1][step] == "1" else n[0] )]] for n[0] in range(1, len(sladders)) for step in range(len(sladders[0]))][len(sladders[0]) - 1 :: len(sladders[0])])[2]][r])
print(amidakuji([
'001001',
'010000',
'100100',
'001000',
'100101',
'010010',
'101001',
'010100'
]))
#```
@distant wave :white_check_mark: Your eval job has completed with return code 0.
[4, 2, 0, 5, 3, 6, 1]
( This version still has a single bug in two places, which causes it to break on other test sets. See if you can spot it/them )
What's the goal?
what is that channel about ?
okay
any fast way to use an f-string with kwargs? is it automatic?
wdym
print(f"{my_var}")
fun(my_var="Hello")```
Something like this?
'{a}, {b}'.format(**kwargs)
but that's not fun
well if you're asking in #esoteric-python then there are a few terrible esoteric ways to do it :P
that's why im asking ^^
Hmm, possible
for k,v in kwargs.items():
exec(f"{k}={v}")
return f'{my_var}'```
Wait, that would not work
you can use globals().update(kwargs)
>>> def fun(**kwargs):
... globals().update(kwargs)
... print(f'{my_var}')
...
>>> fun(my_var='hello')
hello```
although that could also mess with existing variables in globals()
so maybe don't do that
why not locals
if you do it with locals it won't work
!e
def fun(**kwargs):
exec(';'.join(f"{k}={v} for k,v in kwargs.items()))
return f'{my_var}'
print (fun(my_var=5))
Oops
You can, like this
!e ```py
def fun(**kwargs):
locals().update(kwargs)
print(eval(f"f'{''.join(f'{{{k}}}' for k in kwargs)}'"))
fun(my_var="Hello")
@crystal mica :white_check_mark: Your eval job has completed with return code 0.
Hello
!e
def fun(**kwargs):
exec(';'.join(f"{k}={v}" for k,v in kwargs.items()))
return f'{my_var}'
print (fun(my_var=5))```
ok actually we have a better more esoteric idea
Yep
this channel never ceases to amaze me
You will need the locals().update haha
Man, I have not done esoteric in a while
would it work if we updated locals with a decorator? 
possibly
Perhaps a decorator that makes the function take kwargs and puts all of them in the scope of the function
!e ```py
def even_more_fun(func):
def wrapper(*args, **kwargs):
func.globals.update(kwargs)
return func(*args, **kwargs)
return wrapper
@even_more_fun
def fun(**kwargs):
print(eval(f"f'{''.join(f'{{{k}}}' for k in kwargs)}'"))
fun(my_var="Hello")
@crystal mica :white_check_mark: Your eval job has completed with return code 0.
Hello
amazing
>>> from ctypes import *
>>> class PatchedGlobals(dict):
... def __getitem__(self, item):
... if item == 'kwargs' or item not in self['kwargs']:
... return self.__class__.__base__.__getitem__(self, item)
... return self['kwargs'][item]
...
>>> globals()['kwargs'] = {'a': 1}
>>> (c_longlong*2).from_address(id(globals()))[1] = id(PatchedGlobals)
>>> a
1```

that self.__class__.__base__ is because dict is a global so it would end up recursing forever if we just left it as dict
@sick hound could you have used super()?
well super is a global so no
Could pull from builtins maybe?
Builtins is a global too
!e ```py
def s():
import builtins
print(builtins.super)
s()
@distant wave :white_check_mark: Your eval job has completed with return code 0.
<class 'super'>
is __import__ a global?
Yes, but import is not
it is a builtin, which is subtly different from globals
but import uses __import__
in particular, it is accessed from builtins when you execute an import statement, and an ordinary global __import__ will have no effect
>>> del __builtins__.__import__
>>> import os
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: __import__ not found```
nice
{*()}
set()
Is there a shorter way to create an empty set?
Maybe you can do x-x if you have some set x.
Hmm there's not much room for improvement there set_display ::= "{" (starred_list | comprehension) "}" and you've already given the shortest form of both
does this count
>>> class SetMaker: __pos__ = set
>>> s = SetMaker()
>>> +s
set()
>>>
What is the + for?
it calls __pos__
thanks, learned something new
>>> s = type('',(),{'__pos__':set})()
>>> +s
set()```
Does anyone recall my problem about reverse-engineering glob masks?
I think I have almost solved it.
I solved it for two words, at least.
Given two strings:
asshole
airshoe
find the least general glob pattern that will match both of them.
This:
- find common substrings and remember their position
- construct a graph where by moving with the arrow will make
pos_in_Aandpos_in_Bincrease:
/--> (1,3) --\
(0, 0) +--> (6,6
\--> (2,3) --/
- Use Dijkstra's algorithm to find the optimal path.
- Convert to glob-language.
The algorithm feels very obvious in hindsight, but I had a hard time figuring it now.
I also made an implementation, but the code is kinda shitty.
https://repl.it/@int6h/aridij
>>> from search import search
>>> next(search('collec'))
<module 'collections' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/collections/__init__.py'>
>>> next(search('concent'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> next(search('conc'))
<built-in function concat>
>>> ``` i made something terrible. it looks for functions or modules in the standard library, builtin modules, and any already imported modules whose names contain the string searched for and returns a generator that returns the functions
im probably gonna use it for programming competitions where im not allowed to use the internet
Isn't that basically what help() does?
>>> help('modules collec')
Here is a list of modules whose name or summary contains 'collec'.
If there are any, enter a module name to get more help.
_collections - High performance data structures.
gc - This module provides access to the garbage collector for reference cycles.
etc etc
Hmm it doesn't do functions but it's enough for something built-in π€·ββοΈ
You can download the Python docs, by the way. Then you can use them without internet.
Β―_(γ)_/Β― I needed it mostly for functions, and it actually returns instances of that it finds
i did not know help could search modules
dir() does functions, but whatever you pass it has to be in scope (e.g. import random; dir(random))
print([("foo", "bar")[(lambda a:a) < (lambda b:b)] for i in range(2)])
Obnoxious way to reverse a 2-element iterable in py2
!e print([*range(10)][::-1])
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
!e py print([*range(10)[::-1]])
@marsh void :white_check_mark: Your eval job has completed with return code 0.
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
!e py r = range(10) print(r) print(r[::-1])
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | range(0, 10)
002 | range(9, -1, -1)
should be technically a bit faster than what youβve sent, imo
also you can slice ranges
yeah
i only found that out a couple days ago
Idk I wanna do something interesting like hmm
use ctypes to add ++ operator
content
its probably possible
yeah maybe
no you'd have to rewrite the grammar
get the address of the c func that parses grammer with ctypes and replace it
although that might cause a recursive error
# people
n = n + 1
# more professional people
n += 1
# esoteric-python people
n -= ~0```
n -=- 1
[*'X'*5+'Y'*5]
i wrote something like that yesterday
why did they do that?
cause js is weird
I've done such a horrible thing, I dont know it is ready to present or not but according to my really simple tests it works (it is probably fail in many tests though)
My first purpose was implementing old rejected peps but then a friend of mine inspired me to implement other language features to python with token transformer I've already developed. https://github.com/isidentical/pepgrave
The pep features can be used without any modification to script or the environment except adding an encoding to the top of the file (coding: pepgrave-foo, python your-normal-script.py). It is classic pth inserting hack, when python interpreter starts and loads the site module it finds my pth file and that file contains arbitrary code that registers encoding
was there literally a pep for Roman numerals lmao
neat it has pep313 π
I mean lol
That was kind a starting point to me
and it was so close to be accepted
I really liked the idea when i first saw it
and it was so close to be accepted
π€¨
hint: look at the date
I liked all the usages of them in the pep
1st April?
That library looks very interesting.
indeed. I am very curious about simplified # encoding: <something> trick.
@sick hound could you please make some minimal # encoding hack and ast trick?
assert len(indents) >= 0 wait huh?
oh!
this channel exists!
look at this thing i made years ago https://github.com/linky00/pythonthegathering
i was like 15 don't judge
is there a hacky way to make one of these https://docs.python.org/3/library/array.html using an mmap block as its underlying buffer?
@brazen geyser does it need to be that module specifically? you can probably get similar results with numpy, if all you need to do is map a file into memory as an array with element type other than byte
ideally yea
it's easy peasy with numpy,
you can pass a buffer as an argument into array constructor
oh wait this is esoteric python
but im working on a shared memory library centered around mmap
and would like to keep dependencies at a minimum
my current solution for mmap backed arrays is to use a memoryview of the block
what about ctypes
but memoryview's implementation seem to be incomplete
im not sure how to wrangle ctypes π
to be clear, i don't mean using ctypes to mangle an array.array object, i mean using a ctypes pointer object instead
yea gotcha
if all you really need to do is be able to work with typed data inside the mmapped block
then ctypes seems like a mostly perfect solution
would i have to implement all array related functionality on top of the pointer?
or does ctypes provide that for you?
it provides slicing and i think indexing
it won't do limit checking though
unless a ctypes array object will work, which i'm not sure about
i dont know how to use ctypes for this tbh.
does struct exist in other implementations though?
how would i make a pointer based on the mmap block's address?
π€
ctypes.cast(the address, ctypes.POINTER(whatever type e.g. ctypes.c_float))
that i don't know
wait there's a better way
see the accepted answer with ctypes from_buffer
oh btw
>>> a = bytearray(b'asdfghjk')
>>> (ctypes.c_float*2).from_buffer(a)[0] = 0
>>> (ctypes.c_float*2).from_buffer(a)[1] = 0xaaaaaaaa
>>> a
bytearray(b'\x00\x00\x00\x00\xab\xaa*O')```
is !eval executed in a function or in global scope?
I mean do I use locals() or globals()
so you can make a ctypes array object (which will do bounds checking) backed directly by your buffer object [i.e. the mmapped file]
i'm not sure whether that'll work better or worse for you than memoryview though
what problem did youh ave with memoryview?
NotImplementedError: multi-dimensional sub-views are not implemented
various instances of this
ah
for some reason it's left unfinished
well ctypes has multi-dimensional arrays at least
you need like ((ctypes.c_float*2)*2) and it generates a type called c_float_Array_2_Array_2
hmm
i suspect memoryview might be faster for most operations so maybe a hybrid approach might be good
use the ctypes pointer for the stuff thats not implemented in memoryview for now
rely on memoryview for everything else
is there a helper function somewhere thatll get the corresponding ctype for a struct format?
i don't think so no
rip
maybe just use memoryview and have a helper class to translate multidimensional indices to single-dimensional
multidimensional indices work with numpy-esque syntax
i get the feeling memoryview is the more approved way to do this kind of thing
for some reason you just cant get subviews of only one dimension
e.g. if memoryview is of shape (2, 4), view[0] fails.
that's what i'm saying, make your own multi-dimensional array class on top of one-dimensional memory views
you can access individual multi-dimensional indices in a memoryview already, using a tuple like you would in a numpy array
i don't see how that's relevant to what i said
obviously the multi-dimensional support is incomplete, even if individual element access works, and you've already said what's there is not suitable for your purposes
so I don't see why you keep pushing back on my suggestion
well for starters, i have no idea how to implement a multidimensional subview using a single dimensional memoryview
and originally, based on maybe just use memoryview and have a helper class to translate multidimensional indices to single-dimensional it seemed to me that you believed memoryview had no support for multidimensionality
it doesn't really matter what support it has if you've said it doesn't have enough support for you
and, sorry, i assumed you'd be able to figure out how to implement the multidimensional stuff and I wouldn't need to explain in more detail
and i don't have time now, i need to go
sorry
it's all good, and thanks for helping me progress with this :D
anyway, i do need to go, bye
i can grok out how to calculate a multidimensional index in a single dimensional array
but have never really had to think about making subviews and shit like that. uncharted territory for me.
cya
@brazen geyser I'm back, do you want to take a look at that
hey @calm rampart i tried it out with ctypes and it works well enough for my purposes
thanks though
@marsh void I dont have it for AST because if you can parse it with AST you can probably inject something at runtime. Just call some function named __main() and then module = import("__main__"), tree = Tree.from_file(module.__file__), tree = custom_transformer.compile_and_transform(tree), exec(tree, module.__dict__) I am not sure if even this works (wrote from phone) but i remember something like that works.
If you want to do token transformation then yes, you're going to need that encoding magic. I have a little demo from this summer, EuroPython. https://github.com/isidentical-archive/tiefighter/blob/master/tiefighter.py
@marsh void yea, untokenizer.py is the worst place you can look at. It was 2 am and I was tired when I initially implemented it. https://www.youtube.com/watch?v=TOwjqJMeoWQ
@sick hound looks pretty neat, a bit complex I would say, though. Really feeling like my second PyPI library would be messing around with this, haha! 
If you have any questions, just ping me through discord pm. I would like to answer them.
python 3.8 or 3.9 (i forget which) has native ast unparsing
in earlier versions you can just move the source file out from the Tools dir and use it normally too
3.9? 
i think it was 3.9 that it it native
yeah 3.9
The.. Pre-release?
Or I missed something?
It's in development right now
Okay, right
and yea, it was 3.9 where it got exposed
Yes, it is pretty new actually https://github.com/python/cpython/pull/17302
https://bugs.python.org/issue38870
β οΈ Note that this PR only exposes the function in the ast module and does not improve on the base code to avoid creating a gigantic PR when fixing cosmetic chang...
my fully flake8 compliant joke solution to the code jam.
"""."""
def f(s: str) -> __import__('datetime').datetime:
"""."""
return __import__('datetime').datetime(*map(int, __import__('re').split(':|T|-', s)))
oh nice
Modern art π
lol
too bad it's WRONG ```py
f('2019-1-20')
datetime.datetime(2019, 1, 20, 0, 0)```:^)
oh oops
"""."""
I don't think that's what pep8 and flake8 had in mind π
"""."""
def f(s: str) -> (d:=(i:=__import__)('datetime').datetime):
"""."""
return d(*map(int, i('re').split(':|T|-', s)))``` @grizzled cloak made it a bit shorter
does it still pass flake8?
why is the example above wrong
No idea
it would have to be 01
!e
from datetime import datetime as dt
date = dt(2020, 01, 01)```
@thin trout :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
You can't say 01.
In the past, they were supported, but made the number octal, like C.
That was understandably confusing, so was removed altogether.
In my opinion it should normally parse
@grizzled cloak I made this mess: (\d\d\d\d)-?(\d\d)-?(\d\d)(T(\d\d)(:?(\d\d)(:?(\d\d)(\.(\d{1,6}))?)?)?(Z|(\+|-)(\d\d)(:?(\d\d))?)?)?

re.split might work nice but the problem is when you do time zones and stuff
plus your idea won't work with advanced stuff (truncated formats)
int('01') is legal if you didnβt know though @thin trout
@wind maple what do you think about my RE monster? 

Fatal Python error: non-string found in code slot
Python runtime state: initialized
Current thread 0x00007f80651f7740 (most recent call first):
File "/home/mart/git/mixin/code_utils.py", line 9 in new_code
File "/home/mart/git/mixin/code_utils.py", line 68 in merge_code
File "/home/mart/git/mixin/mixin.py", line 21 in apply
File "/home/mart/git/mixin/mixin.py", line 44 in decorator
File "/home/mart/git/mixin/test.py", line 11 in <module>
```this is a new one
Which Python version is that?
3.8
not sure what caused it or how I fixed it
probably an issue with CodeType
btw, does anyone want to help me?
working on a meme π
(based on https://github.com/SpongePowered/Mixin/wiki)
@grave rover can you give a short reproducer?
Is it possible to have type(x) is x where x is defined in pure python? A built in example of x is type.
!e ```py
class A:
def new(cls):
return cls
a = A()
print(type(a) is a)
hm.
!e ```py
class A:
def new(cls):
return cls
a = A()
a.class = a
print(type(a) is a)
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 5, in <module>
003 | TypeError: __class__ assignment only supported for heap types or ModuleType subclasses
!e ```py
class A:
def new(cls):
return A
a = A()
a.class = a
print(type(a) is a)
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 5, in <module>
003 | TypeError: __class__ assignment only supported for heap types or ModuleType subclasses
isn't that a heap type though..
Could probably do something with forbiddenfruit
Someone here would know how to do it?
is is an identity check, so probably not
static PyObject *
cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w)
{
int res = 0;
switch (op) {
case PyCmp_IS:
res = (v == w);
break;
...
it checks if the objects are the same PyObject, so there's no way to do is checks
__class__ is difficult if not impossible to curse without crashing the interpreter
You also cant curse __call__ of type
!e ```py
a = lambda x: a(x)
class A: pass
A.new = a
A()
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | File "<string>", line 1, in <lambda>
004 | File "<string>", line 1, in <lambda>
005 | File "<string>", line 1, in <lambda>
006 | [Previous line repeated 995 more times]
007 | RecursionError: maximum recursion depth exceeded
not gonna post the whole thing yet, but here's a teaser for my one line solution
>>> parse_iso8601("19940528T00:52:36.445")
datetime.datetime(1994, 5, 28, 0, 52, 36, 445)
i don't have proper error handling yet, so this is the shortest format it'll sucessfully parse for now
@thin trout I remember your comment about this and I'll show it to you when I'm done if you want
Oh if you can that would be great!
regex? xD
Did you know:
CPython prints out a recursion error if your call stack gets full even if it necessarily isn't recursion
@crystal mica yea, 200+ chars
@pure dew mine is like 100 chars but I allowed 2001-0101 which I think should be allowed
Yea the spec says the separators are optional
YYYY-MM-DD, YYYY-MMDD, and YYYYMMDD are all the same
same with colons in time
I thought that YYYY-MMDD should be rejected
could be
I need to fix my regex lol
it supports things like YYYY-MMDDTHH:MMSS.ssss+hh:mm
idk lol
group_map = {
0: 'year',
1: 'month',
2: 'day',
4: 'hour',
6: 'minute',
8: 'second',
10: 'microsecond',
11: 'z',
12: 'sign',
13: 'tz_hours',
15: 'tz_minutes'
}```
@pure dew Β―_(γ)_/Β―
Just do regex naming haha
idk why I didnβt do it in the first place
maybe because it will take much more chars lol
I'm around 200 with names, but it parse almost everything
The basic form?
It doesn't do it atm?
Hehe, mine make sure everything is in the right place :)
Can we not post solutions to the qualifier?
well you still have to work around what regex parses
thatβs where real python skill is shown
Please do not share or post (partial) solutions to the qualifier.
It's meant to be an individual challenge and parsing is the biggest chunk of it.
We're interested in how people, individually, solve the qualifier
Are we allowed to post #esoteric-python solutions (Eg: dumb oneliners / lambdas)?
I'd rather keep us from posting solutions for an important part of the qualifier (the initial parsing of the string) and let people tackle this problem on their own. We want to see what kind of strategies they come up with themselves.
I'd like people to come up with strategies for solving this as individually as possible. Discussing or asking for help with the techniques you're using in a more general, non-specific way is obviously okay, since it's normal to do research when programming solutions. Just sharing strategies, (partial) solutions, and things like that goes a bit against the spirit of trying to solve a programming challenge individually.
TIL that numbers from -5 to 256 are always pointed at by references, while other numbers are stored in memory
a, b = 1, 1
while a is b:
a += 1
b += 1
# Will continue when a and b are 257
could be useful to hide execution paths?
Iirc thats for better performance
for k in dir(__builtins__):
if k not in ("False", "True", "None", "exec"):
exec(f"del __builtins__.{k}")
del __builtins__.exec
How do I delete more stuff
I remember I made this awful thing to replace all the things in _builtins_ with an empty string
a=__builtins__.__dict__
list(map(lambda x:a.update({x:''}),a))```
(it breaks everything)
interestingly, exceptions still get thrown with proper names. You just cannot catch them. Maybe a context would work. But you may not define classes
also, why not a=__builtins__.__dict__;a.update(dict.fromkeys(a, ''))
I wasn't trying to golf it too much
I'm pretty sure it breaks everything before the exceptions get replaced
so that's why they have proper name
Well I got my qualifier done
@thin trout It's a 1020 char line, 231 of which is pure regex
oops no thats not right
It's a 2048 character line, now with zero side affects
It's purely functional
2048? Oh yeah baby!
Yea it's one lambda, totally self contained
Once the qualifier is finished I want to see it please!
A pure python artwork haha
Anyone interested in the jam need a team member or want to make a team with me?
Oh
you can add people you wish to have in a team, though @thin trout
cough lemon#0001 cough
cough tito and tshirtman cough
Cough entire kivy team cough
big cough
For sure I did not expect that
What have you done haha
LOL
I don't even remember what I did.
yβall like to dump the core
oh no not one of those in pythonπ¨
Are you using surfarray?
Used to be so easy to segfault that and I'm not sure it ever got fixed ;-;
No, I was just trying to do a very simple test app :)
We're learning C at uni, so a sigsegv is very scary for me...
My first reaction was to use valgrind, but then I remembered I was not writing C
Segmentation fault 
yes you can and you should
The thing about tombstones is they'll last much longer than computer systems that segfault. Beside Cobol, that is.
hahaha
Some time ago I made an esolang in python. It was a stack-based language made as a scripting language for my little game.
But I didn't realize the full capabilities of what I had done...
There are some very simple operations:
a = 1;
(a .println);
You can put these operations inside blocks. Blocks can be treated like any other variables.
x = {
a = 1;
(a .println);
};
y = x;
.x; // execute the code block
.y; // same thing
You can print them:
({x=1; y=1;} .as_src .println);
(the as_src function converts a piece of code to a string -- the string will contain the source code that will result exactly in that code object)
You can split a codeblock into individual statements:
({x=1;y=2;z=3;} .codesplit
{(.as_src .println $N)} .foreach);
Or, as naturally follows, concatenate them:
({x=1} {y=2} .codecat .as_src .println);
And here is a cool thing: instead of using a python decorator, you can just add a bunch of functions together!
log_in = {("in: " .print .copy .println $N)};
log_out = {("out: " .print .copy .println $N)};
adder = {(.add $N)};
(
0 [1, 2, 3]
(log_in adder .codecat)
.foreach
.println
);
(
0 [4, 21, 37]
(
{} [log_in, adder, log_out] codecat .foreach
)
.foreach
.println
);
This is the output:
in: 1
in: 2
in: 3
6
in: 4
out: 4
in: 21
out: 25
in: 37
out: 62
62
If anyone is interested, I will post the source code after a bit of refactoring.
Also, because every stack expression (everything in round brackets) operates on a global stack, you get reduce for free using foreach.
so (0 (1..12) add .foreach .println) is how you would print the sum of numbers 1 through 12.
I guess that code blocks form a monoid (operation: .codecat, neutral element: {}).
I really need refactoring there. I'll say just this:
get_value
is actually a very important function...
Any expression can be a statement in my language.
Code blocks can actually be used to create some data structures!
lst = {1; {2; {3; {}}}};
llsplit = {
(.copy) =>
(.codesplit .bloat ()<0> .llsplit $N)
else
()
};
llbloat = {
($N .swap .llsplit .grab {(()<0> $N)} .foreach $N)
};
lltonormal = {
($N .swap .llbloat .grab $N)
};
(lst .lltonormal .println);
This piece of code converts a 'linked list' (a code block that has two statements: a value and the sublist) into a 'normal list'.
Output: [1, 2, 3]
llsplit pushes code blocks {1}, {2} and {3} onto the stack.
Then llbloat takes 1, 2 and 3 from the little code blocks.
Then lltonormal collects these elements into a normal list.
When you think about it... this language kinda forces extreme decomposition. Because if you don't decompose everything into extremely small functions, you won't understand your code after a few minutes. This is caused by the fact that in order to understand what the hell is going on in a stack expression, you need to keep the picture of the global stack (or at least its topmost bit) in your head. And you can't hold more than 5-9 items at once. Therefore, you have to connect the bits that you can understand with unseen contracts.
Unlike some functional languages which only support immutability, this language only supports mutability, just like assembly language.
And it also screws with your mind because the stack expressions work in postfix mode, while we are used to prefix (function call) and infix (mathematical operations) notations.
Even worse, infix assignments and postfix stacks are mixed!
If some day I will make functions for working with assignments and stack expressions as first-class objects, it will be possible to make associative arrays like this:
my_dict = {
john = "alice";
bob = "charlie";
something = 1;
};
And then some crazy-ass catalogue of functions will deconstruct this code block into pairs of keys and values. Or maybe they will just be able to find the value given its key.
Or maybe they will create some special environment and run the code block inside it. Then they will get the value of a variable whose name is given as the key.
You should do a full write-up on this. Or well copy this into a readme or something!
Makes me want to finish my mixin library ngl
That's an intriguing language. Reminds me of Lisp. A lot of Lisp programs use other programs as data.
I think it's a good idea to make predicates for telling what kind of statement something is and functions for breaking down and building statements, because that would let you write programs to write code for you.
π import sys
π with sys.stdin:
β’β’ pass
β’β’
π with sys.stdin:
β’β’ pass
β’β’
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
Apparently you can close stdin and stdout by just calling .close() on them
oh wow
you can also close stderr
is there a way to make it impossible to import sys or use any of the things in it?
after importing it before
you could delete it all
ah, wait, you can just reimport then
you could make a dummy file sys.py which would get imported first
@glacial rampart i dont like ur ps1
is there a way to make it impossible to import sys or use any of the things in it?
The nuclear option is to clear builtins:
π __builtins__.clear() π import sys Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: __import__ not found
But then you can't import anything else either :p
Couldn't you do something like __builtins__.__dict__['__import__'] now that I think about it
!e ```py
builtins = None
import sys
@distant wave :warning: Your eval job has completed with return code 0.
[No output]
Ew, repl behaves differently
>>> __builtins__ = None
>>> import sys
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: __import__ not found
oooh, fun
>>> import bts
Traceback (most recent call last):
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/Users/bast/throwaway/bts.py", line 6, in <module>
ImportError: __import__ not found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap>", line 321, in __exit__
NameError: name 'any' is not defined
>>>
>>> __builtins__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen importlib._bootstrap>", line 271, in _module_repr
NameError: name 'getattr' is not defined
# bts.py
try:
__builtins__.__dict__.clear()
except:
__builtins__.clear()
del __builtins__
import sys
!e ```py
builtins.dict.clear()
print(builtins.dict)
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | NameError: name 'print' is not defined
!e ```py
import sys
s = str
builtins.dict.clear()
sys.stdout.write(s(builtins.dict))
@distant wave :white_check_mark: Your eval job has completed with return code 0.
{}
!e ```py
import sys
d, s = dir, str
builtins.dict.clear()
sys.stdout.write(s(d(builtins)))
@distant wave :white_check_mark: Your eval job has completed with return code 0.
[]
!e ```py
import sys
d, s = dir, str
builtins.dict.clear()
sys.stdout.write(s(builtins.class.dict))
@distant wave :white_check_mark: Your eval job has completed with return code 0.
{'__repr__': <slot wrapper '__repr__' of 'module' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'module' objects>, '__setattr__': <slot wrapper '__setattr__' of 'module' objects>, '__delattr__': <slot wrapper '__delattr__' of 'module' objects>, '__init__': <slot wrapper '__init__' of 'module' objects>, '__new__': <built-in method __new__ of type object at 0x7f368256faa0>, '__dir__': <method '__dir__' of 'module' objects>, '__dict__': <member '__dict__' of 'module' objects>, '__doc__': 'Create a module object.\n\nThe name must be a string; the optional doc argument can have any type.'}
!e ```py
builtins.dict.clear()
raise [i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BaseException"][0].subclasses()2
@distant wave :warning: Your eval job has completed with return code 0.
[No output]
huh?
!e ```py
import sys
s = str
builtins.dict.clear()
sys.stdout.write(s([i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BaseException"][0].subclasses()2))
@distant wave :warning: Your eval job has completed with return code 0.
[No output]
i-interesting
That.. should not be a possible result..
Yet that's how it works even on my system?
I will pretend I didnt see any of these
!e ```py
print([i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BaseException"][0].subclasses()[2])
@distant wave :white_check_mark: Your eval job has completed with return code 0.
<class 'SystemExit'>
I guess printing systemexit prints a newline for some reason, and that's getting stripped
!e ```py
builtins.dict.clear()
raise [i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BaseException"][0].subclasses()3
@distant wave :x: Your eval job has completed with return code 130 (SIGINT).
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | KeyboardInterrupt
I have an idea, but apparently I suck and did a syntax error, and I'm not on my computer, I'm too lazy to fix it
srcimport = __import__
__import__ = lambda x: srcimport(x) if x != 'sys' else raise ImportError('Nope!)
import itertools
import sys```
Oh fuck
I don't think you can raise in lambdas, can you?
!e
srcimport = __import__
__import__ = lambda x: srcimport(x) if x != 'sys' else raise ImportError('Nope!')
import itertools
import sys```
@thin trout :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | __import__ = lambda x: srcimport(x) if x != 'sys' else raise ImportError('Nope!')
003 | ^
004 | SyntaxError: invalid syntax
Yeah it doesn't seems to like it
!e
(lambda x: raise ImportError(x))('Do I really suck?')```
@thin trout :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | (lambda x: raise ImportError(x))('Do I really suck?')
003 | ^
004 | SyntaxError: invalid syntax
That sucks
!e py a = lambda: (_ for _ in ()).throw(ValueError('Hi from lambda')) a()
@crystal mica :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | File "<string>", line 1, in <lambda>
004 | File "<string>", line 1, in <genexpr>
005 | ValueError: Hi from lambda
Lol
>>> __builtins__.__dict__['__import__'] = lambda *a: print(a)
>>> import sys
('sys', {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__import__': <function <lambda> at 0x040E8348>, 'sys': <module 'sys' (built-in)>}, {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__import__': <function <lambda> at 0x040E8348>, 'sys': <module 'sys' (built-in)>}, None, 0)
>>> import math
('math', {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__import__': <function <lambda> at 0x040E8348>, 'sys': None}, {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__import__': <function <lambda> at 0x040E8348>, 'sys': None}, None, 0)
π€
You know what?
!e
srcimport = __import__
__import__ = lambda x: srcimport(x) if x != 'sys' else 0 / 0
import itertools
import sys```
@thin trout :warning: Your eval job has completed with return code 0.
[No output]
O.o
do __builtins__.__dict__['__import__'] instead of __import__ maybe
!e
srcimport = __import__
__import__ = lambda x: srcimport(x) if x[0] != 'sys' else 0 / 0
import itertools
import sys```
@thin trout :warning: Your eval job has completed with return code 0.
[No output]
Gonna try
!e
srcimport = __builtins__.__dict__['__import__']
__builtins__.__dict__['__import__'] = lambda x: srcimport(x) if x != 'sys' else 0 / 0
import itertools
import sys```
@thin trout :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | TypeError: <lambda>() takes 1 positional argument but 5 were given
!e ```py
[i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BuiltinImporter"][0].find_module('sys').load_module('sys').exit(115)
@distant wave :warning: Your eval job has completed with return code 115.
[No output]
!e ```py
builtins.dict.clear()
[i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BuiltinImporter"][0].find_module('sys').load_module('sys').exit(115)
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | File "<frozen importlib._bootstrap>", line 743, in find_module
004 | File "<frozen importlib._bootstrap>", line 730, in find_spec
005 | File "<frozen importlib._bootstrap>", line 408, in spec_from_loader
006 | NameError: name 'hasattr' is not defined
!e
srcimport = __builtins__.__dict__['__import__']
__builtins__.__dict__['__import__'] = lambda *x: srcimport(x) if x[0] != 'sys' else 0 / 0
import itertools
import sys```
@thin trout :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 2, in <lambda>
004 | TypeError: __import__() argument 1 must be str, not tuple
You will need to unpack it in srcimport()
Ooh
!e
srcimport = __builtins__.__dict__['__import__']
__builtins__.__dict__['__import__'] = lambda *x: srcimport(*x) if x[0] != 'sys' else 0 / 0
import itertools
import sys```
@thin trout :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | File "<string>", line 2, in <lambda>
004 | ZeroDivisionError: division by zero
π
is there some way to make it so you can't overwrite __import__ after that
maybe some ctypes magic followed by making it so you can't import ctypes
Why are you dividing by 0? Cant you just raise a error
oof
Oh, it's k...
!e
import operator
import random
# Generate dummy lists
extensions = {}
common_exts = [".txt", ".tar.gz", ".tgz", ".trans.txt", ".flac"]
for ext in common_exts:
extensions[ext] = random.choices("f", k=random.randrange(1, 100))
# Unpack a dict of lists into a list of tuples
analysis = [(ext, len(extensions[ext])) for ext in extensions]
# Use extension volume analysis to determine candidates for in-out data pairs
# Note: Aka, just sort the damn thing
analysis.sort(key=operator.itemgetter(1), reverse=True)
for ext, volume in analysis:
print(ext, "size:", volume)
@gentle knoll :white_check_mark: Your eval job has completed with return code 0.
001 | .txt size: 67
002 | .flac size: 60
003 | .tar.gz size: 42
004 | .trans.txt size: 25
005 | .tgz size: 19
Noice.
@grizzled cloak you can't raise inside lambda sadly
You can with some tricks
!e py srcimport = __builtins__.__dict__['__import__'] __builtins__.__dict__['__import__'] = lambda *x: srcimport(*x) if x[0] != 'sys' else (_ for _ in ()).throw(DeprecationWarning("You can't do that!")) import itertools import sys
@crystal mica :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | File "<string>", line 2, in <lambda>
004 | File "<string>", line 2, in <genexpr>
005 | DeprecationWarning: You can't do that!
Like that @thin trout
Hmm interesting
!e py srcimport = __builtins__.__dict__['__import__'] __builtins__.__dict__['__import__'] = lambda *x: srcimport(*x) if x[0] != 'sys' else (_ for _ in ()).throw(DeprecationWarning(f"You cant just import {x}! What is wrong with you!")) import itertools import sys
@crystal mica :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | File "<string>", line 2, in <lambda>
004 | File "<string>", line 2, in <genexpr>
005 | DeprecationWarning: You cant just import ('sys', {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'srcimport': <built-in function __import__>, 'itertools': <module 'itertools' (built-in)>}, {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'srcimport': <built-in function __import__>, 'itertools': <module 'itertools' (built-in)>}, None, 0)! What is wrong with you!
LOL
Okay it should be x[0]
!e py srcimport = __builtins__.__dict__['__import__'] __builtins__.__dict__['__import__'] = lambda *x: srcimport(*x) if x[0] != 'sys' else (_ for _ in ()).throw(DeprecationWarning(f"You cant just import {x[0]}! What is wrong with you!")) import itertools import sys
@crystal mica :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | File "<string>", line 2, in <lambda>
004 | File "<string>", line 2, in <genexpr>
005 | DeprecationWarning: You cant just import sys! What is wrong with you!
There we go
That's a lot of information lol
Perfect haha
You call .throw on what? An empty set?
A set comprehension?
Some kind of random python dummy object?
!e
print(type((_ for _ in ())))
@thin trout :white_check_mark: Your eval job has completed with return code 0.
<class 'generator'>
I did it
A generator ohh
From erased builtins to imports
!e ```py
builtins.dict.clear()
LookupError = [v for v in
[i for i in builtins.class.mro[-1].subclasses() if i.name == "BaseException"][0]
.subclasses()[0].subclasses() if v.name == "LookupError"][0]
AttributeError = [v for v in
[i for i in builtins.class.mro[-1].subclasses() if i.name == "BaseException"][0]
.subclasses()[0].subclasses() if v.name == "AttributeError"][0]
KeyError = LookupError.subclasses()[1]
def hasattr(obj, name):
try:
obj.getitem(name)
return True
except LookupError:
return False
except AttributeError:
return name in obj.dict
builtins.dict['hasattr'] = hasattr
builtins.dict['KeyError'] = KeyError
[i for i in builtins.class.dict.class.mro[-1].subclasses() if i.name == "BuiltinImporter"][0].find_module('sys').load_module('sys').exit(115)
@distant wave :warning: Your eval job has completed with return code 115.
[No output]
I wonder if you can do any dumb stuff with __raise__
!e ```py
import sys
print(sys.path)
@distant wave :white_check_mark: Your eval job has completed with return code 0.
['/snekbox/.venv/lib/python38.zip', '/snekbox/.venv/lib/python3.8', '/snekbox/.venv/lib/python3.8/lib-dynload', '/usr/local/lib/python3.8', '/snekbox/.venv/lib/python3.8/site-packages']
@distant wave :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<frozen importlib._bootstrap_external>", line 679, in spec_from_file_location
003 | File "<frozen importlib._bootstrap_external>", line 769, in is_package
004 | File "<frozen importlib._bootstrap_external>", line 70, in _path_split
005 | NameError: name 'len' is not defined
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 45, in <module>
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/cumoforigu
( Gonna go spam in #bot-commands now >.> )
It looks like you can't actually bootstrap back to loading files easily--importlib utilizes exec() under the hood, and thus I don't think I can actually recover a pointer to exec() once builtins has been cleared, so there's no loading files without writing your own python compiler--at which point it's a fruitless endeavor
Working example:
!e ```py
builtins.dict.clear()
def subclass_walk(a, path):
for item in path:
a = [i for i in a.subclasses() if i.name == item][0]
return a
object = builtins.class.mro[-1]
LookupError = subclass_walk(object, ["BaseException", "Exception", "LookupError"])
bd = builtins.dict
bd['KeyError'] = subclass_walk(LookupError, ["KeyError"])
bd['AttributeError'] = subclass_walk(object, ["BaseException", "Exception", "AttributeError"])
bd['super'] = subclass_walk(object, ["super"])
bd['type'] = object.class
bd['tuple'] = subclass_walk(object, ["tuple"])
bd['str'] = subclass_walk(object, ["str"])
bd['int'] = subclass_walk(object, ["int"])
bd['memoryview'] = subclass_walk(object, ["memoryview"])
un = object()
def shim_len(iterable):
i = 0
for _ in iterable: i += 1
return i
def shim_hasattr(obj, name):
try:
shim_getattr(obj, name)
return True
except AttributeError:
return False
def shim_getattr(obj, name, default=un):
try:
return object.getattribute(obj, name)
except AttributeError:
try:
return object.getattr(obj, name, default)
except AttributeError:
if default != un:
return default
raise
def shim_isinst(o, t):
return t in o.class.mro
bd['hasattr'] = shim_hasattr
bd['getattr'] = shim_getattr
bd['len'] = shim_len
bd['isinstance'] = shim_isinst
del subclass_walk(object, ["BuiltinImporter"]).find_module('sys').load_module('sys').modules['builtins']
builtins.dict.update(subclass_walk(object, ["BuiltinImporter"]).find_module('builtins').load_module('builtins').dict)
print(1)
subclass_walk(object, ["BuiltinImporter"]).find_module('sys').load_module('sys').exit(115)
#subclass_walk(object, ["FileLoader", "SourceFileLoader"])('importlib', '/snekbox/.venv/lib/python3.8/importlib/init.py').load_module().reload(builtins)
@distant wave :x: Your eval job has completed with return code 115.
1
A bit crufty, but I'm too tired to clean it up
I have this ()+0, I don't think you can go under 4
3 is possible
How? Almost all object declarations are two chars long
op + almost any type
-()
-() does work yep
Can't do it with 2
you can try by doing a combinations of every valid character and evaling it
I imagine you could do (+/)_ in the repl but that needs something before it and can't be used in normal files
yeah we tried brute-forcing it and got +_ and -_
But.. _ needs to be defined, right?
You don't need to explicitly deifne it in the repl, outside of it yeah and the 3 char are shorter
_ is automatically defined in the repl? Interesting
it's the last result
>>> 2+3
5
>>> _
5
but you gotta have something before you can get the _
Oh, interesting
1@2 also works
A while ago I made something to let you expand the capabilities of lambdas
A lambda that looks like this
myfunc = func(lambda v: ( #define function as ANONYMOUS function set to variable myfunc
setattr(v, x = 0), #set x to 0
(yield from during(lambda v: v.x < 6, lambda v: ( #loop while x < 6 with a yield inside the loop
setattr(v, x = v.x + 1), #increment x by 1
(yield v.x) #yield x
)))
))```
Could be equal to a regular function like this
def myfunc2(): #define function as NAMED function set to name myfunc2
x = 0 #set x to 0
while x < 6: #loop while x < 6 with a yield inside the loop
x += 1 #increment x by 1
yield x #yield x```
I think that fits #esoteric-python
youβre doing really great stuff! is it on GitHub though? really interested in realization! @hollow patrol
yield x #yield x
there's such a thing as too much commenting, even for esoteric python π
@calm rampart true
but i put it there so i could more easily compare each line
with their uses
@marsh void no, but i could put it there if it interests you
the setattr kwarg thing is clever, i almost want to propose that for actual python
yeah it seems very cool @hollow patrol would be glad if youβd put it there
ik
i agree
that project is lambdatools
that's one of my two options i made for lambdas
the other thing i made is called 'anony'

which is much more hideous
but it lets you step through the function
count = function ('count') (
svar('output', []),
iterate('x', range(var('count'))) (
var('output').append(var('x'))
),
result(var('output'))
)```
that's anony for anyone interested
ill put it on git
oh right
here's how you'd return with lambdatools
func2 = func('x, y', lambda v: (
print(v.x, v.y),
result(v.x)
))
x = func2(3, 5)
print(x)
>>> 3```
it'll go on git
Can you also write anony in anony?
Y-combinator?
That's "advanced recursion".
The thing I'm making just makes it easier
It automatically gives you the function as a variable
factorial = func('x', lambda v, f: ( #define function as ANONYMOUS function taking in itself
print(">>>", v.x),
when(lambda v: v.x == 1, lambda v:(
result(1)
)),
result(v.x * f(v.x - 1))
))```
Like this
And probably not, anony is limited
Oh, also I found the better anony
Here you go
count3times = function() [
iterate('i', [1, 2, 3]) [
print(v('i'))
]
]
count4times = function () [
repeat(4) [
print('This will be printed four times in a row.')
]
]
funcWithArgs = function('x', 'y', 'z') [
print(v('x')),
print(v('y')),
print(v('z'))
]```
I have seen a similar thing in the codebase of a project on my work(internship)place, but in JS. They would make an object like this:
const d = {
createStuff: ({user, password}) => {user, password},
checkStuff: ({user, password}) => (password == '' ? {error: 'wrong password'} : {user, password}),
doStuff: ({user, password}) => ...
};
realD = somehowConvert(d);
result = realD(loginObject);
With a bit longer functions and, of course, different names.
Interesting
It can help if you want to name small steps of a process that's going on inside a function.
Yeah
Also, you can change this more easily on the fly.
anony and lambdatools are my attempts to make Python anonymous functions more like JS anonymous functions
Sadly python has limitations for stuff like this
it doesn't matter if you write your whole program with lambdas
that's what i did for my joke solution to the codejam qualifier
Regular Lambdas are hideous if you make them complicated
Lambdatools/Anony Lambdas are better, but still quite ugly
Actual Functions are the best, but can't be unnamed π¦
I'm going to override the builtin type object
So that you can use kwargs as the __dict__
def _(something, some_thing):
someThing()
show it
also
im going to make async lambdas next
def nsync(f):
@functools.wraps(f)
async def wrapper(*args, **kwargs):
for i in f(*args, **kwargs):
await i
return wrapper```
Hopefully this works
Actually wait no
def nsync(f):
@functools.wraps(f)
async def wrapper(*args, **kwargs):
try:
while True:
i = next(f)
f.send(await i)
except StopIteration as e:
return e.args[0]
return wrapper```
There we go
Tried implementing a similar thing, looks promising...


