#esoteric-python
1 messages · Page 27 of 1
also like union types are really awkward
until they introduced the | in 3.10
But before that you had to do like Union[Type1, Type2]
dont forget this awesome feature 💀
which is so fucking awkward
HAHAHAHAH
i swear one day ill learn cpp and make a godot branch for myself that will support all of this
me when I completely neuter the python language and call it "python-like"
lmfao honestly, that would probably be easier than trying to convince them to change this themselves
i mean you dont have to convince cuz its full open source
probally will be enough to implement it yourselves and get enough positive comments on github to get it accepted cuz im sure people will like it because there are already a lot of issues regarding this
hmm
that's fair
how does gdscript even work though, does it just emulate python, or does it actually run an interpreter?
its an entirely different language, its only syntaxly similar to python
that’s bizarre to me because Python has utilities to parse and lex python code… it’s so easy to build a transpiler
I don't imagine it's trivial to bridge together unrelated languages no
syntax is the least of your concerns because you need to reduce to an ast regardless
*generate some sort of bytecode regardless
ast isn't really needed
yeah python has utilities that let you create an AST
and then modify it in Python, and then you can execute it
I made a Python-MongoDB aggregation transpiler this way
It just maps AST nodes to strings and stuff
I'm saying like why didn't they just use Python as the scripting language, and then transpile it to some IR
you definitely shouldn't be generating byte-code...that API is explicitly not stable and can break on any python version. the ast module is much better
the ast module also now has an "unparse" method that lets you translate back from a Python ast to Python code, so the reverse is also pretty easy
we're talking about python that uses an ast
of course an ast would be better
wait which python impl doesn't use an AST?
i think there's none
oh ok haha i was confused because as I understood it basically every language that isn't byte-code or assembly has an ast
wren doesn't afaik
what does it use instead? the website says it uses a one-pass compiler, which still requires an AST I believe
it directly generates bytecode from tokens
oh yeah I'm reading about it now pretty cool
i wanna do that for my programming language as well
hi
can you make an onexit command without fucking with gc cache
btw @tepid matrix, i took it on just as a personal challenge to try and shorten that code down. it could probably be trimmed down to a one-liner by removing whitespace and doing := stuff, but it only really managed to get it effectively one line of code shorter than before: ```py
def convert_bytes_2(file):
# this'll error if the size is >1024GB, either add more sizes
# or use min() to limit the size of the magnitude
size = os.stat(file).st_size
magnitude = (size - 1).bit_length() // 10
unit = ["bytes", "KB", "MB", "GB"][magnitude]
return f"{size} {unit}" if unit == "bytes" else f"{size/1024**magnitude:.1f} {unit}"
i would, uhh, not recommend using this 😄
thank you
not shortened enough
The one liner would probably be something likepy convert_bytes_2=lambda file:f'{(size:=os.status(file).st_size)} {(unit:=["bytes","KB","MB","GB"][magnitude:=(size-1).bit_length()//10])}'if unit=="bytes"else f'{size/1024**magnitude:.1f} {unit}'194
And you can move that if/else to list[boolean]
true, true
though i've now discovered a bit of an issue - i don't think the bit_length trick actually works
Which I think is roughlypy convert_bytes_2=lambda file:[f"{(size:=os.status(file).st_size)/1024**(magnitude:=(size-1).bit_length()//10)}",f"{size} {(unit:=['bytes','KB','MB','GB'][magnitude])}"][unit=="bytes"]182
i think it can be fixed by swapping it to (size.bit_length()-1)//10
aye yeah, that seems to do the trick
are we keeping the variable names the same
I was, yeah
fair
changing them all to one-letter names i get ```py
convert_bytes_2=lambda f:[s:=os.stat(f).st_size,m:=(s.bit_length()-1)//10,u:=["bytes","KB","MB","GB"][m],[f"{s} {u}",f"{s/1024**m:.1f} {u}"][m>0]][-1]
i need test cases
my test cases were just me finding random files and plugging their filepaths into the function :P
!e
import os
with open("0", "wb") as f:
f.write(b"x" * 1024)
convert_bytes_2=lambda f:[s:=os.stat(f).st_size,m:=(s.bit_length()-1)//10,u:=["bytes","KB","MB","GB"][m],[f"{s} {u}",f"{s/1024**m:.1f} {u}"][m>0]][-1]
print(convert_bytes_2("0"))
....do you think the B in all of the unit abbreviations could also be simplified down? 🤨
@languid hare :white_check_mark: Your 3.11 eval job has completed with return code 0.
1.0 KB
hmmm
150 -> 123 ```py
convert_bytes_2=lambda f:(m:=~-(s:=os.stat(f).st_size).bit_length()//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
i considered the list thingy but it was longer when tested
daaaamn
and here i was thinking i was being clever combining the f-strings 😔 ```py
convert_bytes_2=lambda f:[s:=os.stat(f).st_size,m:=(s.bit_length()-1)//10,u:=["bytes","K","M","G"][m],f"{s:{'.1f'(m>0)}} {u}{'B'(m>0)}"][-1]
142 chars
f strings can be a friend or an enemy
being able to also insert the format code using inner {} looks and feels so odd
123 -> 122 ```py
convert_bytes_2=lambda f:(m:=(len(bin(s:=os.stat(f).st_size))-3)//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
includeimport os to be fair (132) ```py
import os
convert_bytes_2=lambda f:(m:=(len(bin(s:=os.stat(f).st_size))-3)//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
ohhhh, i see the and and or trickery now
hrmm, if we weren't including imports, then i would've said that log might've been a good replacement to the bit counting
is os stat chosen over len open read for any reason?
ok 132 -> 121 ```py
convert_bytes_2=lambda f:(m:=(len(bin(s:=len(open(f).read())))-3)//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
wouldn't you also have to specify its in binary mode? since otherwise you're risking decode errors / multi-byte chars messing things up
^
os.stat(f).st_size
# VS
len(open(f,'rb').read())
ah true ```py
import os;os.stat(f).st_size
len(open(f,'rb').read())
ye, unfortunately you can't skip that :P
convert_bytes_2=lambda f:(m:=(len(bin(s:=len(open(f,"rb").read())))-3)//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
121 + fix = 126
what about
len(open(f,'rb').read())
# vs
open(f,'a').tell()
ooh
tell doesn't decode also, so it won't fail for binaries
very nice
convert_bytes_2=lambda f:(m:=(len(bin(s:=open(f,'a').tell()))-3)//10)and f'{s/1024**m:.1f} %sB'%'KMG'[m-1]or'%i bytes'%s
120
!e py print(*[ [IdCall(IdArgs(1)),IdCall(IdArgs(object))] for(IdArgs)in[[]] for(IdCall)in[( [ (sum) for(sum)in[0] for(byte)in(bytes) for(sum)in[(sum<<8)+(byte&255)] ][-1] for(obj)in(IdArgs) for(initrepr)in['{.\x5f\x5finit\x5f\x5f}'.format(obj)] for(newrepr)in['{.\x5f\x5fnew\x5f\x5f}'.format(obj)] for(hex)in[((initrepr)if('0x')in(initrepr)else(newrepr)).split('x')[-1].strip('>')] for(bytes)in[b''.fromhex(hex.rjust(16,'0'))] ).send] for(IdArgs)in[IdArgs.append] ][0]) print(id(1), id(object)) fully functional id(...) with no functions, walruses, dunders or builtins
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 140487274824328 140487274783808
002 | 140487274824328 140487274783808
!e but what about
class Foo:
pass
f = Foo()
for x in dir(f):
try:
setattr(f, x, "0x0")
except (TypeError, AttributeError):
pass
print(*[
[IdCall(IdArgs(f))]
for(IdArgs)in[[]]
for(IdCall)in[(
[
(sum)
for(sum)in[0]
for(byte)in(bytes)
for(sum)in[(sum<<8)+(byte&255)]
][-1]
for(obj)in(IdArgs)
for(initrepr)in['{.\x5f\x5finit\x5f\x5f}'.format(obj)]
for(newrepr)in['{.\x5f\x5fnew\x5f\x5f}'.format(obj)]
for(hex)in[((initrepr)if('0x')in(initrepr)else(newrepr)).split('x')[-1].strip('>')]
for(bytes)in[b''.fromhex(hex.rjust(16,'0'))]
).send]
for(IdArgs)in[IdArgs.append]
][0])
print(id(f))
@dry mirage :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 0
002 | 139903235162000
well yea it will break if you violate normal assumptions
check out the pinned post! i'm running a competition for intentionally bad python code
what defines "intentionally bad"?
We like programs that:
are unique and interesting (solving old problems in a new way is just as good as a new problem solved in an old way).
OR
are unique or novel in their obfuscation style
make us laugh and/or throw up 🙂 (humor really helps!)
because this is a Python competition, there will also be consideration for clever uses of the Python interpreter internals.
From pyobfusc.com/#rules
https://gist.github.com/juliusgeo/1da759d07af0b447a78d0ccb14162c57 this is one of my examples of what would be considered an ideal submission
or https://gist.github.com/juliusgeo/969c722b2152e53e4f6bb94ca2696c7a if you like number theory hah
it's also very inspired by the https://www.ioccc.org/ so you can check out their past years for good examples of C programs
International Obfuscated C Code Contest
https://www.ioccc.org/2012/endoh1/hint.html this is my favorite IOCCC submission of all time I think. I also emailed the guy who made it and he was super nice.
I also didn't answer the original question, in this case intentionally bad means code that is obfuscated to a high degree on purpose, or made to fit an ascii shape on purpose.
or some combination of the two
holy fucking shit
that actually makes me want to cry
well if you want you can write C++ instead of gdscript
ye thats right
it just goes from tokens to bytecode directly
https://github.com/wren-lang/wren/blob/main/src/vm/wren_compiler.c
that was 2 days ago
Is it possible to create print() with no functions, walruses, dunders or bultins?
Good challenge idea, I'll work on that later tonight
i have most of it written out, the tricky part is getting a reference to stdout
do you have a way to import?
not without overkill esoteric code
if you can import, you can use os.open
the only way I have found to import requires a memory corruption bug
fun
and at that point i can just leak the address of print and use it directly
hm
that'd still be using builtins though
but! if you can do that, then can you get the address of _io.TextIOBase or whatever it's called?
if yes then you can probably create a new file object which uses the file descriptor for stdout
you can leak the address via str.format so it would not be using the builtin directly. but yea you could grab that class as well
Memory corruption bug?
There are some bugs that you can use even with the limited scope given above but they are overkill imo
without builtins? not sure
if you cant use sys, you can just open 0 as w and write your message to there
print_fake=lambda*x:open(0,"w").write(" ".join([str(y)for y in x])+"\n")
problem is that that closes the output stream once the open gets gc'd
nevermind seems to just break the repl
repl closes instantly after running the func
Does this satisfy you
def print(*args, sep=' ', end='\n', flush=True, file=open(1, "w")):
file.write(sep.join(map(str, args)))
if flush:
file.flush()
It has a function (def print) and it uses a built-in function (open) and built-in methods (write & flush) but it works. You could probably turn this into a lambda if you put a little thought into it, but there is no way to use IO without built-in functions
Close, you need to open 1, not 0
0 = stdin
1 = stdout
2 = stderr
god fucking damnit
You are using map and str, which are built-in names
map and str are easy to get rid of (comprehension), but open is not
is the stdlib included as builtins
You can use frame tricks to gey access to some frame with builtins, then get open from there
you'd have to figure out a way to import them without using __import__
oh yea did you end up trying the HTB challenge I made?
which
i dont think ive tried it before
or at least, i dont remember trying it before
oh oops, I meant to ping you when I released it
its possible that you did and i forgot to check it later
im a very forgetful person
eh it happens, you should give it a shot tho
im doing that now
oh interesting
i havent tested this yet but my first impression/idea is that ||it prints the object from the address, which would call .__repr__ so if i make an object at the address which has a .__repr__ that has the bytecode to open and read the flag and return that then i can get the flag||
im gonna go test that brb
well. turns out its a bit more involved than it sounds
and im out of time
so im gonna do this later tonight
import
- not a function
- not a walrus
- not a dunder
- is not a builtin (function)
internally
are we not counting that then? if not then a lot of stuff becomes really easy
if we're gonna count that then we're also gonna have to count f-strings (they use format() and str() internally)
mhm
wait do they? i thought they used .__format__ and .__str__/.__repr__ directly rather than calling the builtins
if that's true then they're internally using dunders
a.b usually calls object.__getattribute__(a, 'b'), which is also a builtin function
When I originally posed this as a challenge environment it included clearing out the builtins module so import would not work
strangely I couldn't get any output when typing anything to the server, it'd just print a newline
not sure if it was a network issue or something, might try again later
local one seems fine, just the htb server
python/cpython#103487 sad news
no more implicitly using integer ~ in booleans in 3.12+
I can hardly imagine any intended use for ~some_bool, so this error should not annoy any rightful users.
lol
nooo
That is odd
I'll look into it
at least we get a one character bool inversion tho
?
wait
oh
idk why i thought they were replacing it with like ~True == False and ~False == True
unfortunately no, not already does that
the code for the testcases has a list of all the surviving numbers
so you decumulate it and convert to string
oh I just generated it myself
I saw noob in off topic talking about how having the list in code took up too much room
😞
I was watching this video https://www.youtube.com/watch?v=t863QfAOmlY , and they end with running this program without an explanation, but creates an ascii art animation of "TheEnd" written out one letter at a time. Any ideas how this works? It doesn't look like valid python syntax to me.
Python is a great language, with a few... exploits. While a lot of implementation details make it easier to work with, they also lead to quirks - quirks which can be exploited for fun (and profit?). Whether it's variables, match statements, type hinting, imports, or even just trying to fit everything on one line, this talk has more than a few sl...
the # ... coding: 1 ... makes it use a custom encoding 1.py which the speaker installed ahead of time
Wow, nice, I never would've found that.
so bools are no longer strict subclasses of int

ah right, that does violate the LSP a little
!e
import math
print(''.join(map(lambda i:chr(round(abs(math.sin(ord(i)))*25+97)),'The Zen of Python, by Tim Peters:\nExplicit is better than implicit\nI forgot how this goes')))
@pearl socket :white_check_mark: Your 3.11 eval job has completed with return code 0.
silowlbowzozzgiwbaoozosyuozlgluyzodpwxyzygoyyoolggluogijboyuwxyzygorozwuqwgoiwjogiyyoqwly
https://docs.python.org/3.12/whatsnew/3.12.html#deprecated
The bitwise inversion operator (
~) on bool is deprecated. It will throw an error in Python 3.14. Usenotfor logical negation of bools instead. In the rare case that you really need the bitwise inversion of the underlyingint, convert to int explicitly with~int(x).
devastating blow to the esoteric pythoners
late much?
#esoteric-python message you're 29 hours late
Yeah, still a subclass but the ~ operator is overwritten
scrolling up 10 messages is too much work smh 🙄 ||/j||
@manic ember :white_check_mark: Your 3.11 eval job has completed with return code 0.
42
how does that work?
@manic ember :white_check_mark: Your 3.11 eval job has completed with return code 0.
True
https://lwn.net/Articles/876280/ found this
I guess that's one reason to .isdigit() instead of .isdecimal()
Best way is to int() with try except
str.isdigit()```
Return `True` if all characters in the string are digits and there is at least one character, `False` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the property value Numeric\_Type=Digit or Numeric\_Type=Decimal.
isnumeric > isdigit > isdecimal
!eval ```py
print("৪୨".isnumeric())
@ornate cliff :white_check_mark: Your 3.11 eval job has completed with return code 0.
True
whichever one is more appropriate in the respective context
@manic ember :white_check_mark: Your 3.11 eval job has completed with return code 0.
True
wtf
>>> help(str.isdigit)
Help on method_descriptor:
isdigit(self, /)
Return True if the string is a digit string, False otherwise.
A string is a digit string if all characters in the string are digits and there
is at least one character in the string.
it should say that it includes non-Arabic numerals
come on help() deserves love
@manic ember :white_check_mark: Your 3.11 eval job has completed with return code 0.
True
ohh I thought he was talking about which methods are better 😂🤦♂️
[0-9] is more readable tho
but it's regex anyway so who cares about readability anyway
why not just accept Unicode decimals?
they work in int()
apparently u get free github copilot if u have contributed to open source repos? it’s pretty sick—so much better to use for coding than chat gpt
i’ve been using it for the past like 4 hours lmfao
Thats pretty neat, but i dont see how it fits this channel
I was using it to write esoteric python 😉
but good point I forgot to read the channel name haha
Waaait, are there other channels?
Huh you don't get free copilot for that?
I don't have an image of the message it said when I signed up but people on reddit said they also got the same thing

Oh I found it in the docs:
But what kind of open-source projects it refers to?
I was also trying to find that and I just found it: https://github.com/pricing#faq-copilot
Under the heading "I work on open source projects, can....."
It still doesn't really clarify what it means by "the most popular" though
I'm pretty sure the reason I got it is because I've contributed a ton to PyMongo
If you email bill gates with those links he'll probs give it to u right away
!e
from array import array as a
brs = lambda arr: (arr := a('I', arr),[(templ:=a("I"),tempr:=a("I"),[(tempr if (1<<b)&i else templ).append(i) for i in arr],arr := templ + tempr) for b in range(max(arr).bit_length())],arr.tolist())[2]
from random import shuffle
test_arr = list(range(10))
print(test_arr)
shuffle(test_arr)
print(test_arr)
print(brs(test_arr))
binary radix search in ~2 lines of python
where the hell did my output disappear to
!e
brs = lambda k:([(l:=[],r:=[],[(r if (1<<b)&i else l).append(i) for i in k],k := l + r) for b in range(max(k).bit_length())],k)[1]
from random import shuffle
test_arr = list(range(10))
print(test_arr)
shuffle(test_arr)
print(test_arr)
print(brs(test_arr))
!e
import math
def p(a:eval("\x66\x6c\x6f\x61\x74")):
b=[0,chr,.5,ord,1,print,1.5,int,2,bool,2.5,str,3,hasattr,3.5,u,4,m]
for i in range(len(b)):
c=str(type(b[i]))
if "builtin"in c or"type"in c or"function"in c:
if b[i]==a:return b[i+1]
else:continue
if b[i]*2==a:return b[i+1]
def u(a:eval("\x74\x75\x70\x6c\x65"),b:eval("\x69\x6e\x74")):return((abs(-a+b)//abs(a^-b)+1)*a)^b
def l(a:eval("\x73\x74\x72"),b:eval("\x66\x6c\x6f\x61\x74"),c:eval("\x74\x75\x70\x6c\x65")):
if a>b+6:return (p(7))(16,c)^(p(7))(b,1)^1
else:return (p(7))(15,c)^(p(7))(18,a)^1
def m(a:eval("\x69\x6e\x74"),*b:eval("\x73\x74\x72")):(a.__call__(w(b)))
def w(a:eval("\x66\x6c\x6f\x61\x74")):
if 3>l(10,20,30):return-a
else:return a[0]
m(p(2),"".join(list(map(chr,(p(3)(p(chr)*144),p(3)(p(u)*25.25),((math.floor(91/5/5-24*5/6*5+32-53*4+60*7-81*2/6/3-12+14+34+50*5*8+95+81))^2374),((math.floor(14/5*3+97*1+28-96*2-15-29-13/4/7+79-42-8-45+43*7-29-18*9*6/7))^98),((math.floor(17+51/7-12*5*4-81*3+86/9/6*4/9+18+72*8))^232),((math.floor(11*7+36/9+43*6+99/5-32-2-63*4/7-42/5/3*5-38+4+18+83/6+22/6*4/3+76-97*6/8))^374),((math.floor(84*6+44+2/9*8*1+62+94*3-62-99-78-61*9-9-69/4+3*8*4+36*1-55-15+99*5+47-10-96+13))^557),((math.floor(108/6*8/6-1*2+34/3*3-83/9+2*1/5/6/2/5-83-39))^-62),((math.floor(68*1-58-59-34/5+84/4/2-70/3/4-57*3/6-74+75/4+21))^-39),((math.floor(96/4+98+99+8+59-76/3+20+56+15+57*8-67-42+83/7))^679),((math.floor(99*2+42*8-59-53+62+34-52+7/8-96/6*9+9))^313),((math.floor(94-1-81*7/4/4-85/4/9*7-23/6-75/5+52-17-38-35/2*6-3-78-2-66/3+29/5+16+67/8/4*7))^-247),((math.floor(94+10+48+69*1-85-35*5-63+80+42+56/6))^121),((math.floor(16+95+31+94-61-81+29/2/2+20-11/9*6-89-98/6-8-11-96+38+33))^-3))))).replace(chr(((math.floor(68*8-32/9-32+52*3-1/7*6*1*8/6/5+28+99+22))^835))+chr(((math.floor(18*5*4+99*4*5+55+75+17-55/5/7/2))^2517))+chr(((math.floor(7-46+12+38*7/3-78*2-13/7/2-64))^-234)),chr((math.floor(1+44-53-87+64*2*6*2*8-81*4+60/3*7/9-81-24/8+69*9-12/5+18))^12469)))
@sick hound :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello World!
!e
print(*list(map(lambda l:"".join([chr(l[:i+1].count("+")-l[:i+1].count("-")) for i in range(len(l)) if l[i]=='.']), "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++.".split())), sep="\n")
@zinc niche :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | amogus amogus
002 | sorry
offbrand mini brainfork compiler in one line, counter resets to 0 between lines (separated by spaces), and . is used to print the character at that key code, also is horribly inefficient because instead of a running total, it just counts ALL the plus's and minus's up to the current index for each character printed, so if anyone could figure out how to have a running total in one line, that would be cool
!epy inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++." print(*["".join(chr(n) for n in [0] for c in i for n in [n + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()],sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | amogus amogus
002 | sorry
uses nested inline for loops to perform the inc/decrementing of the counter
Could remove the initializer for n by replacing the lookup for n in the later loop with locals().get('n',0)
!e ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
print(*["".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()],sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | amogus amogus
002 | sorry
'.+'.find(c)
found out you can use expressions in type annotations so i had some fun
is_wrapped_in: lambda *_: __import__("asyncio").to_thread(
lambda: (
_[1]
.__mul__(True << True)
.__eq__(_[0].__class__.strip(_[0])[False :: -True + _[0].__len__()])
)
) = lambda *_: __import__("asyncio").run(__annotations__["is_wrapped_in"](*_))
Clever use of the -1 error value
you don't need to use dunder methods here unless that is a restriction of the problem I think
you could use mul() and == etc
for the imports you do need to use __import__ but other methods that aren't based on keywords I'm pretty sure can be kept as the normal func call
oh wait I just read that this in type annotations
disregard everything I said lol
(comprehension) vs. [comprehension]
saves on memory
in this case it wouldn't really save on memory that much
and the overhead of starting and stopping the frame with a generator comp might slow it down a bit (assumption, i haven't benchmarked)
actually looking at the source code using a generator would actually use more memory print(*arg) uses CALL_FUNCTION_EX which eventually calls PySequence_Tuple(arg) which for generators would hit the generator yield overhead and for lists would result in a linear memcpy (plus the earlier overhead of the list comp) so the speed would probably be about the same
!timeit py inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++." print(*["".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()],sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 179 usec per loop
hmm
!timeit py inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++." print(*("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 180 usec per loop
so it would use more memory?
by a fraction, the listcomp for this code would not get so large that it would be an issue
probably by the same fraction that the generator is slower lol
the list comp one is def getting a boost from the linear memcpy since that is probably compiled to a vector copy so it would be super fast
huh it actually uses a for loop https://github.com/python/cpython/blob/main/Objects/tupleobject.c#L382-L386
Objects/tupleobject.c lines 382 to 386
PyObject **dst = tuple->ob_item;
for (Py_ssize_t i = 0; i < n; i++) {
PyObject *item = src[i];
dst[i] = Py_NewRef(item);
}```
eh still tight for loop is def going to be faster than the generator overhead
i think you should not call print while you measuring time
there needs to be some function call otherwise the generator would not be unpacked
maybe just lambda *args:None
!timeit ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
"\n".join((*("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),))
@fleet bridge :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 183 usec per loop
well, it is not significant
looks like .join had more overhead actually
probably timeit patches stdout with dummy .write
probably
!timeit ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
print = lambda a,**k: None
print(("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),sep='\n')
@fleet bridge :warning: Your 3.11 timeit job has completed with return code 0.
[No output]
!ti ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
_ = *("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),
@quartz wave :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 181 usec per loop
!ti ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
_ = *["".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()],
@quartz wave :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 182 usec per loop
what
where is output
what were u expecting
i shadowed print and output disappeared
is it using __main__.print?
this would hit UNPACK_EX not CALL_FUNCTION_EX
good point
yes
name lookup (LOAD_NAME) is always locals -> globals -> builtins
!timeit ```py
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
_print = print
print = lambda a,**k: None
print(("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),sep='\n')
print = _print
for LOAD_GLOBAL it's globals -> builtins
@fleet bridge :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.11/timeit.py", line 326, in main
003 | number, _ = t.autorange(callback)
004 | ^^^^^^^^^^^^^^^^^^^^^
005 | File "/usr/local/lib/python3.11/timeit.py", line 224, in autorange
006 | time_taken = self.timeit(number)
007 | ^^^^^^^^^^^^^^^^^^^
008 | File "/usr/local/lib/python3.11/timeit.py", line 178, in timeit
009 | timing = self.inner(it, self.timer)
010 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
011 | File "<timeit-src>", line 45, in inner
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/rasizecalu.txt?noredirect
it is creating function from my code, so everything is happening in local scope
but why result disappeared when i shadowed print? it was shadowed only in local scope of the function, not in the global scope, where code for printing should be
!timeit py inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++." foo = lambda *a,**k: None foo(*("".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()),sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 185 usec per loop
huh
!timeit py inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++." foo = lambda *a,**k: None foo(*["".join(chr(n) for c in i for n in [locals().get('n',0) + {'-':-1,'+':1,'.':0}[c]] if c == '.') for i in inp.split()],sep='\n')
@rugged sparrow :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 179 usec per loop
what are you confused about
!e ```py
def f():
intense work
print = lambda *_: ...
print('print is shadowed, this is not printed')
some timer shuff
f()
some timer shuff
print('X loops, best of 5: X usec per loop -- this should be printed')
@fleet bridge :white_check_mark: Your 3.11 eval job has completed with return code 0.
X loops, best of 5: X usec per loop -- this should be printed
there local variable shadowed builtin variable in global scope
print is a global variable in that code
!timeit ```py
print = None
@rugged sparrow :white_check_mark: Your 3.11 timeit job has completed with return code 0.
001 | Exception ignored in atexit callback: <function inner.<locals>.print_last_line at 0x7f3105bcbce0>
002 | Traceback (most recent call last):
003 | File "<timeit-src>", line 36, in print_last_line
004 | TypeError: 'NoneType' object is not callable
what is going on inside generated code...
timeit is probably evaling the code like this: eval(src, globals())
yes it does
actually
!timeit ```py
invalid$
@rugged sparrow :x: Your 3.11 timeit job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<frozen runpy>", line 198, in _run_module_as_main
003 | File "<frozen runpy>", line 88, in _run_code
004 | File "/usr/local/lib/python3.11/timeit.py", line 376, in <module>
005 | sys.exit(main())
006 | ^^^^^^
007 | File "/usr/local/lib/python3.11/timeit.py", line 315, in main
008 | t = Timer(stmt, setup, timer)
009 | ^^^^^^^^^^^^^^^^^^^^^^^^^
010 | File "/usr/local/lib/python3.11/timeit.py", line 123, in __init__
011 | compile(stmtprefix + stmt, dummy_src_name, "exec")
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ijapofihas.txt?noredirect
it exec()s the source
https://github.com/python/cpython/blob/main/Lib/timeit.py#L69-L78
i dont see how print = ... can change process of printing result, which is obviously happening outside of the generated function
Lib/timeit.py lines 69 to 78
template = """
def inner(_it, _timer{init}):
{setup}
_t0 = _timer()
for _i in _it:
{stmt}
pass
_t1 = _timer()
return _t1 - _t0
"""```
!timeit ```py
raise Exception(globals())
@rugged sparrow :x: Your 3.11 timeit job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.11/timeit.py", line 326, in main
003 | number, _ = t.autorange(callback)
004 | ^^^^^^^^^^^^^^^^^^^^^
005 | File "/usr/local/lib/python3.11/timeit.py", line 224, in autorange
006 | time_taken = self.timeit(number)
007 | ^^^^^^^^^^^^^^^^^^^
008 | File "/usr/local/lib/python3.11/timeit.py", line 178, in timeit
009 | timing = self.inner(it, self.timer)
010 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
011 | File "<timeit-src>", line 44, in inner
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/yuvusuwaka.txt?noredirect
@fleet bridge if you look at that pastebin you can see that the globals for the evaled statement is the timeit module globals. so when you set print it shadows in those globals
wait it's set in a function though
!timeit
foo = lambda *a, **k: None
foo(*["".join(chr(n := n + ord(c) - 43) for c in i if (c == '.' or (n := locals().get('n', 0) + ord(c) - 43) or True)) for i in inp.split()], sep='\n')
@wise void :white_check_mark: Your 3.11 timeit job has completed with return code 0.
2000 loops, best of 5: 188 usec per loop
assignment in function assigns to local ns, not to the global ns
oh wait
good to know how this works 🙂
youre right what
.
!timeit py raise Exception(locals())
@rugged sparrow :x: Your 3.11 timeit job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.11/timeit.py", line 326, in main
003 | number, _ = t.autorange(callback)
004 | ^^^^^^^^^^^^^^^^^^^^^
005 | File "/usr/local/lib/python3.11/timeit.py", line 224, in autorange
006 | time_taken = self.timeit(number)
007 | ^^^^^^^^^^^^^^^^^^^
008 | File "/usr/local/lib/python3.11/timeit.py", line 178, in timeit
009 | timing = self.inner(it, self.timer)
010 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
011 | File "<timeit-src>", line 44, in inner
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/dixofetiqa.txt?noredirect
>>> timeit.main(['print=lambda*_:...;print(123)'])
2000000 loops, best of 5: 106 nsec per loop
``` i cannot reproduce it locally
what's print_last_line()
out of curious what was your bit of code meant to accomplish, have me curious
!timeit ```py
import inspect
raise Exception(inspect.getsource(print_last_line))
its a half implementation of BF
why is so much stuff in locals?
locally i get this: ```py
timeit.main(['import pprint;pprint.pp(locals());1/0'])
{'_it': repeat(None, 0),
'_timer': <built-in function perf_counter>,
'_t0': 405473.071889,
'_i': None,
'pprint': <module 'pprint' from 'D:\Programs\Python\311\Lib\pprint.py'>}
...traceback
BF?
bot/exts/utils/snekbox/_cog.py line 37
TIMEIT_SETUP_WRAPPER = """```
ah yea that'll do it
ok, lets see how cursed this is,
@wise void :white_check_mark: Your 3.11 timeit job has completed with return code 0.
1000 loops, best of 5: 211 usec per loop
I deserve to burn for making python code as hard to read as brainfuck 😄
but somehow it makes sense for an interpreter of it,
!timeit
m, pt, ipt, out, i, ls = [0] * 30000, 0, 0, "", 0, []
while i < len(p):
c = p[i]
if c in '+-': m[pt] = (m[pt] + (1 if c == '+' else -1)) % 256
elif c in '<>': pt = (pt + (1 if c == '>' else -1)) % len(m)
elif c == '.': out += chr(m[pt])
elif c == ',': m[pt], ipt = (ord(inpd[ipt]), ipt + 1) if ipt < len(inpd) else (m[pt], ipt)
elif c == '[': i = (i + p[i:].index(']')) if m[pt] == 0 else (ls.append(i) or i)
elif c == ']': i = (ls.pop() - 1) if m[pt] != 0 else i
i += 1
return out
inp = "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--.-----------------------------------------------------------------------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++.++.--------.++++++++++++++.--. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----.+++..+++++++."
run_brainfuck(inp)```
@wise void :white_check_mark: Your 3.11 timeit job has completed with return code 0.
1000 loops, best of 5: 207 usec per loop
One Liners when someone asked them to actually write normal code
I saw an increasingly muddled list comprehension, so felt I would have a go at seeing how far it can be taken
if you want it as normal code I'll expand it back out
Why not in line the entire function
idk but it just brainfuck
I wanted it atleast somewhat readable 😄
Just try to compile it in brainfuck
ok rude
but also true
y'all gotta take the expression pill
walrus operators+expressions means infinite possibilities
from random import shuffle, sample
binradixsort=lambda l:([(le:=[],ri:=[],[(ri if(1<<b)&i else le).append(i)for i in l],l:=le+ri)for b in range(max(l).bit_length())],l)[1]
bogosort=lambda l:next(dropwhile(lambda l:not all(starmap(operator.le,zip(l,islice(l,1,None)))),map(lambda x:sample(x,len(x)),repeat(l))))
bubblesort=lambda l:[[[l.insert(i,l.pop(i+1))if(l[i]>l[i+1])else () for i in range(len(l)-1)] for _ in range(len(l)**2)], l[:]][1]
cocktailsort=lambda l:[[[l.insert(i,l.pop(i+1))if(l[i]>l[i+1])else l.insert(r,l.pop(r-1))if(l[r]<l[r-1])else()for i,r in zip(range(len(l)-1), range(len(l)-1,0,-1))]for _ in range(len(l)**2)],l[:]][1]```
also not to self promo but I made a tool that will automatically reflow code that is just expressions: https://github.com/juliusgeo/pyflate (the source code is also solely expressions, so can be reflowed by itself)
what are walrus poperators
when you are using expressions you can't use typical statements such as arr[i], arr[j]=arr[j], arr[i], instead you have to phrase them in terms of the only assignment operator available in expressions which is :=
and it kinda looks like a walrus, which is why it's called that
an equivalent expression would be something like arr.insert(i, arr.pop(j))
the best usage tho is in while loops, like lets say you're calling a function read that returns some buffer you could do ```
while (input:=read()):
# do something
rather than
input = read()
while input:
input = read()
# do something
i see
it is a lot less ergonomic than traditional assignments in a lot of cases
but if you're an insane person like me and you want to write all your programs exclusively in list comprehensions it's super useful
it can also lead to some very fun optimisations when using generators 🙂
this is very true, but I've also been trying to chase optimizations in a few of my list comprehensions and I"m not sure if the walruses actually are the same in byte-code
like I wonder if using a walrus in a listcomp is faster or slower than using some builtin from itertools
for me its more being able to start processing stuff while its still being read in, if it outruns the generator, then it just swings off to do something else for a while
very handy for rate limited API's
oh that is true for when you're relying a lot on I/O
I've mainly been implementing integer sorting algorithms tho
so it's very compute heavy
I assume your read time is not 0? depending on the algorithm you can sometimes begin sorting even with partial data, leading to less time overall
in comparison to most operations in Python, reading an element from an array is super cheap imo
(also depends on the amount of data, I know :D, I'm just used to the worst case of slow API's and billions of records)
oh hahah that's true
if I was using billions of records I would use like
pyarrow or something
but then you have to define a schema
or let it guess for you 😦
from my own benchmarking though, I think that list comprehensions are not always the answer if you're searching for performant code
I just like it because I can make one-liners
correct, list comprehension is still iteration, sometimes double iteration, it comes down to what your doing to pick the best tool, hashmaps are horrible for small chunks of sequencial data 🙂
for some cases though it can be faster
because the python interpreter can save parts of it and then execute the actual iteration in C-space
also I recently learned about the array module which gave me a decent speedup for sorting stuff
esoteric python and its consequences have been a disaster for the human species
!epy print([*globals()][5][3].upper()+[*globals()][1][3])
@arctic skiff :white_check_mark: Your 3.11 eval job has completed with return code 0.
No
!e
code
!eval [python_version] <code, ...>
Can also use: e
Run Python code and get the results.
This command supports multiple lines of code, including formatted code blocks. Code can be re-evaluated by editing the original message within 10 seconds and clicking the reaction that subsequently appears.
The starting working directory /home, is a writeable temporary file system. Files created, excluding names with leading underscores, will be uploaded in the response.
If multiple codeblocks are in a message, all of them will be joined and evaluated, ignoring the text outside them.
By default, your code is run on Python 3.11. A python_version arg of 3.10 can also be specified.
We've done our best to make this sandboxed, but do let us know if you manage to find an issue with it!
!eval print type („90“)
@royal plover :x: Your 3.11 eval job has completed with return code 1.
001 | File "/home/main.py", line 1
002 | print type („90“)
003 | ^
004 | SyntaxError: invalid character '„' (U+201E)
#bot-commands
i know the unabomber would love esoteric python if he wasn't stuck in max security prison 😦
what even is the reason for [*x]
why not just x
No reason
Though you can't int index on dicts
[*dict] puts dict keys in a list
He would declare war
he might even bomb something 😳
to be fair if you wanted to achieve his goal of resetting humanity back to the stone age writing absurdly unmaintainable code would probably help in the long run
!e ```py
,(,t),,,,(,a)=zip([0]*6,globals())
print(a[3].upper()+t[3])
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
No
!e ```py
,(,t),,,,(,a)=[*globals()][:6]
print(a[3].upper()+t[3])
@vast wave :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 1, in <module>
003 | _,(_,t),_,_,_,(_,a)=[*globals()][:6]
004 | ^^^^^
005 | ValueError: too many values to unpack (expected 2)
the fuck
ok
!e ```py
print(''.join(map(lambda x:x[3],map(next,([g:={},filter(lambda x:(0,)*-~-(g.update(i=g.get(x:='i',0)+1)!=g[x]%4-1!=1),globals())]*2)[1::2])))[::-1].capitalize())
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
No
can you stop pinging me when you try to run code
the last few were failed attempts ok
don't mind them
no i do mind them
personally i do not like being pinged for no reason and then not finding out what the message i was pinged on was
once is fine, twice maybe
but 4 full times now?
stop ffs
kk
Whats t and _
they are defined there
in this case, _ is being used to say "we don't care about this variable"
horrible idea: something which causes any unbound variable names to be treated like they actually contain a string equalling their variable name
WHY
!e I actually already have code to do this lol ```py
from ctypes import py_object
import builtins
class fakeglobals(dict):
slots = ()
def missing(self, key, b=builtins, h=hasattr, g=getattr):
if h(b, key):
return g(b, key)
return key
py_object.from_address(id(globals()) + 8).value = fakeglobals
print(undefined_name)
print(hello, world)
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | undefined_name
002 | hello world
Science isn't about why, it's about why not!
that does globals though. is it possible to do for a local namespace? iirc there was something with frame tracing being able to update the local frame namespace but idk, my memory is really bad
if a name is accessed but not assigned to in a local scope it is treated as a global, so the above would cover that case. for the case where a local is accessed and then assigned you would need to use some frame tracer
...
You must've run it twice or something. Because the recursion issue shows after the class definition which shouldn't happen if the globals isn't hooked.
this is... awful
Not even the most cursed thing I have sent here
what is
i mean it is written with indentation and no weird lambda expressions so not that cursed overall
the level of cursedness is not determined by how unformatted and shit the code looks, it's a matter of what it does
!e
py_object = getattr(__import__("ctypes"), "py_object")
builtins=__import__("builtins")
class fakeglobals(dict):
__slots__ = ()
__missing__ = lambda key, b=builtins, h=hasattr, g=getattr: g(b, key) if h(b, key) else key
py_object.from_address(id(globals()) + 8).value = fakeglobals
print(undefined_name)
print(hello, world)
i fucked it
there are multiple axes of cursedness
you can both be cursed by doing something surprising with normal looking code, or by doing something normal with surprising looking code
oh wait you can also do
py_object = getattr(__import__("ctypes"), "py_object")
builtins=__import__("builtins")
class fakeglobals(dict):
__slots__ = ()
__missing__ = lambda key, b=builtins: gettattr(b, key, key)
py_object.from_address(id(globals()) + 8).value = fakeglobals
print(undefined_name)
print(hello, world)
!e ```py
import('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'slots':(),'missing':lambda k,b=import('builtins'):b.getattr(b,key,key)})
print(undefined_name)
print(hello, world)
damnit
just remove the b. int he getattr call
oh i know what's wrong
!e ```py
import('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'slots':(),'missing':lambda k,b=import('builtins'):b.getattr(b,k,k)})
print(undefined_name)
print(hello, world)
@quartz wave :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 2, in <module>
003 | print(undefined_name)
004 | ^^^^^
005 | File "/home/main.py", line 1, in <lambda>
006 | __import__('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'__slots__':(),'__missing__':lambda k,b=__import__('builtins'):b.getattr(b,k,k)})
007 | ^^^^^^^^^
008 | AttributeError: 'str' object has no attribute 'getattr'
i don't
you gotta remove the b. you don't call getattr as an instance method
it's global and you pass in the object as the first arg
no it's builtins
!e
__import__('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'__slots__':(),'__missing__':lambda k,b=__import__('builtins'):getattr(b,k,k)})
print(undefined_name)
print(hello, world)
@keen thicket :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 2, in <module>
003 | print(undefined_name)
004 | ^^^^^
005 | File "/home/main.py", line 1, in <lambda>
006 | __import__('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'__slots__':(),'__missing__':lambda k,b=__import__('builtins'):getattr(b,k,k)})
007 | ^^^^^^^
008 | File "/home/main.py", line 1, in <lambda>
009 | __import__('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'__slots__':(),'__missing__':lambda k,b=__import__('builtins'):getattr(b,k,k)})
010 | ^^^^^^^
011 | File "/home/main.py", line 1, in <lambda>
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/yuwinoquwu.txt?noredirect
see
oh there's something else lol
yeah
I'm not sure if you can pass in builtins like that
as an arg to the lambda func
oh i know what's wrong
__import__("ctypes").py_object.from_address(id(globals())+8).value=type("",(dict,),{"__slots__":(),"__missing__":lambda s,k,b=__builtins__,g=getattr:g(b,k,k)})
print(undefined_name)
print(hello, world)
!e ```py
import('ctypes').py_object.from_address(id(globals())+8).value=type('',(dict,),{'slots':(),'missing':lambda _,k,b=import('builtins'):b.getattr(b,k,k)})
print(undefined_name)
print(hello, world)
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | undefined_name
002 | hello world
finally
@vast wave probably some of my more abstract memory corruption stuff
Py_BEGIN_ALLOW_THREADS goes hard
for some reason it works, but it turns my script into a repl....
for i in __builtins__.__dict__.keys():
print(i)
copyright
credits
license
help
>>>
i=__import__;i("ctypes").py_object.from_address(id(globals())+8).value=type("",(dict,),{"__slots__":(),"__missing__":lambda s,k,b=i("builtins"),g=getattr:g(b,k,k)})
``` here's one that doesn't use `__builtins__`, but is still shorter
import ctypes as c,builtins as b;c.py_object.from_address(id(globals())+8).value=type("",(dict,),{"__slots__":(),"__missing__":lambda s,k,b=b,g=getattr:g(b,k,k)})
true
removing the alias b=b, ```py
import ctypes as c,builtins as b;c.py_object.from_address(id(globals())+8).value=type("",(dict,),{"slots":(),"missing":lambda s,k,g=getattr:g(b,k,k)})
does not work
!e I more mean stuff like this ```py
from functools import partial # note this only works with C version of functools
from array import array
HEAP_ITEM_SIZE = 102
def make_pair():
# heap grooming
# returns tuple, bytearray pair where array exists directly after end of tuple
fill = bytes((HEAP_ITEM_SIZE // 2) * tuple.itemsize)
r = range(HEAP_ITEM_SIZE // 2) # do these now so that we need less allocs later
old = [] # store failures to increase memory pressure
while True:
t = tuple(r)
b = array('b', fill) # use array instead of bytearray so we don't have to guess buffer location
b_addr, _ = b.buffer_info()
if id(t) + t.sizeof() == b_addr:
return t, b
old.append((t, b))
p = partial(id)
bytearray_mem = memoryview(bytearray(bytearray.basicsize)).cast('P')
bytearray_mem[0] = 1 # refcount
bytearray_mem[1] = id(bytearray) # ob_type
bytearray_mem[2] = (2 ** (tuple.itemsize * 8) - 1) // 2 # ob_size
bytearray_mem = bytearray_mem.tobytes()
class Fake:
slots = ['value']
def repr(self):
raise Exception(memoryview(self.value))
Fake_mem = memoryview(bytearray(Fake.basicsize)).cast('P')
Fake_mem[0] = 1 # refcount
Fake_mem[1] = id(Fake) # ob_type
Fake_mem[2] = id(bytearray_mem) + bytes.basicsize - 1
Fake_mem = Fake_mem.tobytes()
class WeirdRepr:
def repr(self):
global b # otherwise it is freed after function and that causes more problems
t, b = make_pair()
p.setstate((id, t, {}, {}))
mem = memoryview(b).cast('P')
for i in range(len(mem)):
mem[i] = id(Fake_mem) + bytes.basicsize - 1
return 'Wack'
p.setstate((id, (WeirdRepr(),) * HEAP_ITEM_SIZE, {}, {}))
try:
repr(p)
except Exception as e:
mem = e.args[0]
print(mem, len(mem))
import ctypes as c,builtins as b;c.py_object.from_address(id(globals())+8).value=type("",(dict,),{"__slots__":(),"__missing__":lambda s,k,b=b:b.g(b,k,k)})
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
<memory at 0x7f557dc58ac0> 9223372036854775807
yeah you need the alias for globals because lambdas are expressions
!e ```py
import ctypes as c,builtins as b;c.py_object.from_address(id(globals())+8).value=type("",(dict,),{"slots":(),"missing":lambda s,k,g=getattr:g(b,k,k)})
print(undefined_name)
print(hello, world)
@vast wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | undefined_name
002 | hello world
it does clearly work
oh thats smart to use getattr's default arg
ok
in __main__, __builtins__ is the builtins module
in other stuff, it's builtins.__dict__
ah that's good to know
@vast wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | print([0x1or x for x in"a"*9])
003 | [1, 1, 1, 1, 1, 1, 1, 1, 1]
fortunately that "future release" hasn't come yet
not even 3.12 has it removed
!e
from einspect import impl, orig
@impl(list)
def __len__(self):
self.append(4)
return orig(list).__len__(self)
a = [1, 2, 3]
print(len(a))
print(a)
@low lynx :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 4
002 | [1, 2, 3, 4]
003 | Exception ignored in: <module 'threading' from '/usr/local/lib/python3.11/threading.py'>
004 | Traceback (most recent call last):
005 | File "/usr/local/lib/python3.11/threading.py", line 1583, in _shutdown
006 | lock.acquire()
007 | ^^^^^^^^^^^^
008 | AttributeError: 'int' object has no attribute 'acquire'
@dry mirage what's with this
!e ```py
from einspect import impl, orig
@impl(list)
def len(self):
self.append(4)
return orig(list).len(self)
a = []
not a
print(a)
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | [4]
002 | Exception ignored in: <module 'threading' from '/usr/local/lib/python3.11/threading.py'>
003 | Traceback (most recent call last):
004 | File "/usr/local/lib/python3.11/threading.py", line 1583, in _shutdown
005 | lock.acquire()
006 | ^^^^^^^^^^^^
007 | AttributeError: 'int' object has no attribute 'acquire'
boolean checks require a len() call
what does that have to do with the error
i felt im so dumb here ;-;
Lib/threading.py lines 1597 to 1598
if not locks:
break```
right before a for lock in locks: loop
not isn't listed in that list
also a few others but not is the most useful/most common one iirc
it's not specific keywords, it's changing the parsing of int literals to error as soon as it's incorrect rather than the current fallback logic
then why does it list specific keywords
right
with this i meant that not is the most commonly used keyword discounting all the ones listed
currently the SyntaxWarning for literals seems to only include those specific ones, but I think when the actual deprecation happens it will include all invalid decimal literals since this mainly seems to be a compiler optimization thing
in a future release it will be changed to a SyntaxError
as that's written, it would only raise the error for those specific keywords
which i dont think is what they meant
how does it optimise the compiler? i would think that checking for the case of an integer literal directly before a keyword would be more expensive than just accepting it and moving on
unless having that somehow enables some other optimisation?
0not in x is valid syntax
count your days
give it like 2 years, it'll be gone
today I realized you can use nonlocal in a class ```>>> def f(x):
... class Y:
... nonlocal x
... x = 2
... return x
...
f(1)
2
That makes sense because class bodies are technically just functions. Very funky tho
remove_dupes = lambda listr : list(set(map(str.lower,listr))).__reversed__()
Is there a way i can shorten/golf this to be better?
[*x] instead of list(x)
k
and {*x} for sets too
yeah
dang
and change listr to a 1 letter name
[::-1]?
remove_dupes = lambda l : [*{*map(str.lower,l)}][::-1]
why do you have the list.__reversed__ after pulling from the set?
because fsr it flips it
sets are unordered so in theory __reversed__ would be nondeterministic in this case
if you want to dedupe while preserving order you can do dict.fromkeys
where?
instead of the set
!d dict.fromkeys
classmethod fromkeys(iterable[, value])```
Create a new dictionary with keys from *iterable* and values set to *value*.
[`fromkeys()`](https://docs.python.org/3/library/stdtypes.html#dict.fromkeys "dict.fromkeys") is a class method that returns a new dictionary. *value* defaults to `None`. All of the values refer to just a single instance, so it generally doesn’t make sense for *value* to be a mutable object such as an empty list. To get distinct values, use a [dict comprehension](https://docs.python.org/3/reference/expressions.html#dict) instead.
remove_dupes=lambda l:[*dict.fromkeys(map(str.lower,l))]
remove_dupes = lambda l:[*{k.lower(): 0 for k in l}]
remove_dupes = lambda l:[*{k.lower():()for k in l}]``` can drop a space using an empty tuple (or other collection)
ew
remove_dupes=lambda l:[*{k.lower():0for k in l}]
where exactly are the duplacates being removed?
when the dict is being made
you should join us for advent of golf in december
so we have py remove_dupes = lambda l:[*{k.lower():()for k in l}] # will always work, preserves order remove_dupes = lambda l:[*{k.lower():0for k in l}] # will work for the time being, preserves order remove_dupes = lambda l:[*{*map(str.lower,l)}] # will always work, does not preserve order
hello code golfers. how do i find the next char in a string without going outside its index
could you give more context?
-(index+1) could work
which is equal to the char in index 0
oh yea
works for my code but probably not for all use cases
how long is the string?
ohh i get what you mean
from 1 to 10
I mean, if you have the length, -~current-length works
and this because i feel the need to write awful code: py remove_dupes = lambda l:[k for s in [[]] for k in l for k in [k.lower()] if k not in s for s[len(l):] in [[k]]] it works using only list comprehensions, no sets, dicts, or (*) unpacking operator
not really golfing at that point, just writing it in a weirder way
huh i just noticed both of your solutions don't work somehow
the program converts roman to integer
LVIII returns 54 with std's solution and golfing's returns 56
and the answer is 58
lol
full code?
s = input("s:")
core = {
'I': 0,
'V': 1,
'X': 2,
'L': 3,
'C': 4,
'D': 5,
'M': 6
}
values = [1, 5, 10, 50, 100, 500, 1000]
def value(s):
return values[(core.get(s))], core.get(s)
print(values)
out = 0
for index in range(0, len(s)):
x = lambda _char: values[(core.get(_char))]
char = x(s[index])
Next = x(s[index+1-len(s)])
if char < Next:
out -=char
else:
out+=char
print(out)
maybe i can add 0 to the end of s
!e ```py
s = 'abc'
i = 2
C, C2, *_ = [*s[i:i+2],None]
print(C, C2)
``` this will either put a character in C2 or None in C2 if at the end of a string
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
c None
can i make it return 0?
yea just swap None out with '0'
# breaking down
C, C2, *_ = [*s[i:i+2], <default>]
C, C2, *_ # this is the unpacking assignment
# 2 definite args, C and C2 and `*_` to capture the rest of the iterable
s[i:i+2] # this slices the string, getting up to 2 characters starting at index `i`
C, C2, *_ = [*s[i:i+2], <default>]
# the * here ^ unpacks the up to 2 characters into this list.
# ex: [*'ab', 1] -> ['a', 'b', 1]
# if there is only one character then `<default>` is stored in `C2`, otherwise `<default>` ends up in `_` as a single element tuple```
was explaining the whole thing, lots of typing
oh my thank you so much
t=0
p=1e5
for c in input():v=[5,10,50,100,500,1000,1]['VXLCDM'.find(c)];t+=[1,-1][p<v]*v;p=v
print(t)
man wtf
!e
t=0
p=1e5
for c in input():v=[5,10,50,100,500,1000,1]['LVIII'.find(c)];t+=[1,-1][p<v]*v;p=v
print(t)
@limpid ember :x: Your 3.11 eval job has completed with return code 1.
:warning: Note: input is not supported by the bot :warning:
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 3, in <module>
003 | for c in input():v=[5,10,50,100,500,1000,1]['LVIII'.find(c)];t+=[1,-1][p<v]*v;p=v
004 | ^^^^^^^
005 | EOFError: EOF when reading a line
oops
!e ```py
t=0
p=1e5
for c in "LVIII":v=[5,10,50,100,500,1000,1]['VXLCDM'.find(c)];t+=[1,-1][p<v]*v;p=v
print(t)
@gleaming linden :white_check_mark: Your 3.11 eval job has completed with return code 0.
58
my brain
!e ```py
t=0
p=1e5
for c in "MXCIV":v=[5,10,50,100,500,1000,1]['VXLCDM'.find(c)];t+=[1,-1][p<v]*v;p=v
print(t)
@gleaming linden :white_check_mark: Your 3.11 eval job has completed with return code 0.
906
oh wait
shouldn't it be 1094?
!e ```py
t=0
p=1e5
for c in "MXCIV":v=[5,10,50,100,500,1000,1]['VXLCDM'.find(c)];t+=v-2p(p<v);p=v
print(t)
@gleaming linden :white_check_mark: Your 3.11 eval job has completed with return code 0.
1094.0
why is it a float now
even tho this should be doing the same thing
oh, p's initial value is a float
is p suppossed to be 10000.0?
any value >1000
s = input("s:")
core = {
'I': 0,
'V': 1,
'X': 2,
'L': 3,
'C': 4,
'D': 5,
'M': 6,
}
values = [1, 5, 10, 50, 100, 500, 1000]
def value(s):
return values[(core.get(s))], core.get(s)
print(values)
out = 0
for index in range(0, len(s)):
x = lambda _char,*_: values[(core.get(_char))]
char,Next,*_= [x(*s[index:index+2]),0]
if char < Next:
out -=char
else:
out+=char
print(out)
core = {
'I': 0,
'V': 1,
'X': 2,
'L': 3,
'C': 4,
'D': 5,
'M': 6
}
values = [1, 5, 10, 50, 100, 500, 1000]
print(values)
out = 0
for index in range(0, len(s)):
x = lambda _char: values[(core.get(_char))]
char = x(s[index])
try:
Next=x(s[index+1])
except:
Next=0
if char < Next:
out -=char
else:
out+=char
return(out)
print(romanToInt("MXCIV"))
don't bother with calculating the next char
old code
add it anyway, but subtract 2*previous if the next char is bigger
what does the semi colon do
separate statements
rather than \n?
a;b
# is equivalent to
a
b
but in a for loop you need indentation so ; is shorter
for ...:a;b
# saves 1c over
for ...:
a
b
t=0
p=1000
for c in input():v=[5,10,50,100,500,1000,1]['VXLCDM'.find(c)];t+=v-2*p*(p<v);p=v
print(t)
``` 97c
save a char with -1 from .find
I already did
oh
ye ye i fixed the link
pyth is also interesting https://esolangs.org/wiki/Pyth
it took me a while to figure out why I isn't there lol
thank you for your help golfers
what is this hellscape
def sanitize(string:str):
num = '0123456789+'
abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz'
sym = ' #@,;.:-=%!?*äöüß'
OK = num+abc+sym
last = ''
word = ''
nr = 0
for char in string:
if char not in OK: continue
elif char in num: word += char
elif char in abc:
if char != last:
word += char
nr = 0
elif nr < 3:
word += char
nr += 1
elif last != char: word += char
last = char
return word```
This code is quite ugly. It performs a simple task, maybe you can even one-line this.
It is just used for string sanitization for user-inputs.
All identical characters within "num" may be used without limit.
-> "1111111" = "1111111"
All identical characters within "abc" are allowed 3 times in a row.
-> "aaaa" = "aaa"
-> "aaaabbbb" = "aaabbb"
All identical characters within "sym" must not follow each other.
-> "@@" = "@"
-> "!!!!!!!!!!!!!!!!!!!" = "!"
this seems like a regexable thing
import re
sanitize=lambda s:re.sub('(.)\\1*',lambda m:m.group(1)*...,s)
```this is what I have so far
Note that num and abc are not just what their variable name hint at.
Num are all numbers AND '+'
Abc are all letters AND '/'
import re
k=dict.fromkeys
t=k('0123456789+',9999)|k('ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz',3)|k(' #@,;.:-=%!?*äöüß',1)
sanitize=lambda s:re.sub('(.)\\1*',lambda m:m.group(0)[:t.get(m.group(1),0)],s)
``` does this work?
!e
import re
k=dict.fromkeys
t=k('0123456789+',9999)|k('ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz',3)|k(' #@,;.:-=%!?*äöüß',1)
sanitize=lambda s:re.sub('(.)\\1*',lambda m:m.group(0)[:t.get(m.group(1),0)],s)
print(sanitize('1111111aaaabbbb !!!!!!!!!!!!!!!!!!!'))
@solar tulip :white_check_mark: Your 3.11 eval job has completed with return code 0.
1111111aaabbb !
yes, it works.
What does t=k(a,b) do?
!d dict.fromkeys
classmethod fromkeys(iterable[, value])```
Create a new dictionary with keys from *iterable* and values set to *value*.
[`fromkeys()`](https://docs.python.org/3/library/stdtypes.html#dict.fromkeys "dict.fromkeys") is a class method that returns a new dictionary. *value* defaults to `None`. All of the values refer to just a single instance, so it generally doesn’t make sense for *value* to be a mutable object such as an empty list. To get distinct values, use a [dict comprehension](https://docs.python.org/3/reference/expressions.html#dict) instead.
!e
import re
k=dict.fromkeys
t=k('0123456789+',9999)|k('ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz',3)|k(' #@,;.:-=%!?*äöüß',1)
sanitize=lambda s:re.sub('(.)\\1*',lambda m:m.group(0)[:t.get(m.group(1),0)],s)
print(t)
@solar tulip :white_check_mark: Your 3.11 eval job has completed with return code 0.
{'0': 9999, '1': 9999, '2': 9999, '3': 9999, '4': 9999, '5': 9999, '6': 9999, '7': 9999, '8': 9999, '9': 9999, '+': 9999, 'A': 3, 'B': 3, 'C': 3, 'D': 3, 'E': 3, 'F': 3, 'G': 3, 'H': 3, 'I': 3, 'J': 3, 'K': 3, 'L': 3, 'M': 3, 'N': 3, 'O': 3, 'P': 3, 'Q': 3, 'R': 3, 'S': 3, 'T': 3, 'U': 3, 'V': 3, 'W': 3, 'X': 3, 'Y': 3, 'Z': 3, '/': 3, 'a': 3, 'b': 3, 'c': 3, 'd': 3, 'e': 3, 'f': 3, 'g': 3, 'h': 3, 'i': 3, 'j': 3, 'k': 3, 'l': 3, 'm': 3, 'n': 3, 'o': 3, 'p': 3, 'q': 3, 'r': 3, 's': 3, 't': 3, 'u': 3, 'v': 3, 'w': 3, 'x': 3, 'y': 3, 'z': 3, ' ': 1, '#': 1, '@': 1, ',': 1, ';': 1, '.': 1, ':': 1, '-': 1, '=': 1, '%': 1, '!': 1, '?': 1, '*': 1, 'ä': 1, 'ö': 1, 'ü': 1, 'ß': 1}
r"(([A-z/])|([0-9+])|([insert symbols]))\1*"
```something like this, and then determine the max length based on which group is present
Ah, I see.
I think with this there is also an easier solution without even using re.
Maybe
def sanitize(s):
r=""
for c in s:
if c in"ABC..."and r[-3:]!=c*3:
r+=c
...
return r
Wait, that can be a lambda
Yes, true
sanitize=lambda s:(r:="",[r+=c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c)for c in s],r)[2]
Can you test it? I'm not bothered to make the whole thing on mobile lol
!e
sanitize=lambda s:(r:="",[r+=c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c)for c in s],r)[2]
print(sanitize('1111111aaaabbbb ❀ !!!!!!!!!!!!!!!!!!!'))
@solar tulip :x: Your 3.11 eval job has completed with return code 1.
001 | /home/main.py:1: SyntaxWarning: invalid decimal literal
002 | sanitize=lambda s:(r:="",[r+=c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c)for c in s],r)[2]
003 | File "/home/main.py", line 1
004 | sanitize=lambda s:(r:="",[r+=c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c)for c in s],r)[2]
005 | ^^
006 | SyntaxError: invalid syntax
Oh, right
sanitize=lambda s:(r:="",[(r:=r+c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c))for c in s],r)[2]
!e ```py
sanitize=lambda s:(r:="",[(r:=r+c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c))for c in s],r)[2]
print(sanitize('2222AAAAAABB #####111111ππ'))
@gleaming linden :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid decimal literal
002 | sanitize=lambda s:(r:="",[(r:=r+c*(c in"ABC..."and r[-3:]!=c*3or c in"0123..."or c in" #@..."and r[-1]!=c))for c in s],r)[2]
003 | 2222AAABB #111111
Niiice
for name in data.keys():
for area in data[name].keys():
for user in data[name][area].keys():
if data[name][area][user] == 'HANS': found_ID = name```
I feel like there should be a shorter way to do this.
found_ID = next(user for name in data for area in data[name] for user in data[name][area] if data[name][area][user] == 'HANS')
``` try this
Awesome 👍
iirc dict order is implementation defined
No, it's guaranteed since 3.7
It's an impl detail in 3.6 and then they realised people were gonna use it either way
I'm pretty sure it was put into 3.6 with the understanding that insertion ordering was likely to become part of the language, but they didn't want to commit to that just then in case there were unexpected problems.
dict.__iter__ goes over keys already
what if no data[name][area][user] equals HANS?
also this saves 12+ chars ignoring that issue, and not renaming variables
found_ID=next(user for name in data for area in data[name].values()for user in area.values()if user=='HANS')
you can just use the second arg for next to give a default return value
then it works even if no HANS value
til
of course you could save 21 more chars by using one-letter variables
||```py
found_ID=next(u for n in data for a in data[n].values()for u in a.values()if u=='HANS')
correct me if im wrong but that would just return HANS not the found_ID
found_ID=next(n for n in data for a in data[n].values()for u in a.values()if'HANS'==u)
sotru
thanks
it was to compare to previous, not to fix bug
ah
er wat?
I only copied what someone else wrote
wait actually yeah lol
it should be name for name in ...
bugged
i think this works ```py
sanitize=lambda s:''.join(c*(r[-3:]!=c*3>'@'<c<'['or'/'<c<':'or'+'==c or r[-1]!=c in' #@,;.:-=%!?*äöüß')for c in s)
nvm
!e ```py
sanitize=lambda s,r="":[r:=r+c*(r[-3:]!=c*3>'@'<c<'['or'/'<c<':'or'+'==c or r[-1:]!=c in' #@,;.:-=%!?*äöüß')for c in s][-1]
print(sanitize('2222AAAAAABB #####111111ππ'))
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
2222AAABB #111111
ok this works now
it's funny that you have to add a specific case for the german B-S hybrid
i didn't add that
oh sorry haha i meant "you" in the general sense. I think it's funny that it's one of the specific characters anyone has to include
it's called "Eszett" which means "SZ" (the letters).
likely from this old form of the letter "s" I'm guessing https://www.unlockyourhistory.com/post/2019/05/31/the-mystery-of-the-old-s-explained
it's pronounced like a hard ss
eh, soft s?
honestly the words hard and soft are ambiguous
ahh yeah i used to take german so i knew it was pronounced that way but I had no idea what the spelling was hahaha
it is pronounced like [s]
isn’t it more like a long s?
the length doesn't differ at all
bc it’s 2 ses
it may be used to mark a difference in the vowel sound before
the G in Golfing stand for German, so this is definitely on-topic
🤓
the golfing in golfing stands for Scotland (the land of the best golfers on earth) so this is on topic:
I googled best scottish golfers 1800s to get this pic btw
Don't know what this has to do with esoteric Python, but ß is a ligature of the long s and a z.
my question might fit here best, otherwise please redirect me:
I'm trying to find function calls with isinstance(node,ast.Call) but I'm not finding... method calls? e.g. self.foo() is there a special type for those?
Or maybe I was and that was what the attribute error was...
Method calls wouldn't be special at all, they're just an attribute access + a call.
!e
import ast
print(ast.dump(ast.parse("self.foo()")))
@languid hare :white_check_mark: Your 3.11 eval job has completed with return code 0.
Module(body=[Expr(value=Call(func=Attribute(value=Name(id='self', ctx=Load()), attr='foo', ctx=Load()), args=[], keywords=[]))], type_ignores=[])
mhm
hm
ok, comparing to a regular function makes clear what's going on.
print(ast.dump(ast.parse("foo()")))
Module(body=[Expr(value=Call(func=Name(id='foo', ctx=Load()), args=[], keywords=[]))], type_ignores=[])
I was trying to access node.func.id but that doesn't work the same way.
Thanks!
i wonder why is it [Expr(value=Call(func=Name(id='foo', ctx=Load()), args=[], keywords=[]))] and not a [Call(func=Name(id='foo', ctx=Load()), args=[], keywords=[])] ?
i think Module expects body to be a list of "statements" and Call is not a statement, so it is wrapped into Expr to make it statement-like for consistency
Yes, it's an expression statement
heya
I wrote this horribly long one-liner:
return points.index(list(i for i in points if (i[0]==x or i[1]==y)==True)[list(abs(x-i[0])+abs(y-i[1]) for i in points if (i[0]==x or i[1]==y)==True).index(sorted(list(abs(x-i[0])+abs(y-i[1]) for i in points if (i[0]==x or i[1]==y)==True))[0])]) if list(i for i in points if (i[0]==x or i[1]==y)==True) else -1```
for this leetcode problem: https://leetcode.com/problems/find-nearest-point-that-has-the-same-x-or-y-coordinate/
Any ideas how I can shorten this further? I really only know how to use list comprehension confidently so anything would help lmao
Can you solve this real interview question? Find Nearest Point That Has the Same X or Y Coordinate - You are given two integers, x and y, which represent your current location on a Cartesian grid: (x, y). You are also given an array points where each points[i] = [ai, bi] represents that a point exists at (ai, bi). A point is valid if it shares t...
return((cmp:=lambda i,x=x,y=y:any((i[0]==x,i[1]==y))),points.index(list(filter(cmp,points))[[abs(x-i[0])+abs(y-i[1])for i in points if(i[0]==x or i[1]==y)==True].index(sorted(abs(x-i[0])+abs(y-i[1])for i in points if cmp(i))[0])])if[i for i in points if cmp(i)]else-1)[1]
what's cmp?
40 bytes shaved off 🙂
cmp is a lambda function
that we then use in all the places where you're checking the same condition
if (i[0] == x or i[1] == y) == True)
# turns into
cmp(i)
ooh wait I see another quick change u could make
oh i didn't know := was a thing
yeah it was added in python 3.8, super useful for doing one-liners
makes list comprehensions turing complete
yeah and all is the same but for ands
it's especially nice if you're comparing two iters piecewise
@violet pollen ```python
return((cmp:=lambda i,x=x,y=y:any((i[0]==x,i[1]==y))),points.index(list(filter(cmp,points))[[abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)].index(min(abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)))])if[i for i in points if cmp(i)]else-1)[1]
246 bytes 🙂
you could also save a few more by renaming variables
why are we just doing return
count the function header
this is very cool, thank you
i is always a list inside the points list
and is len(i) always 2?
yep
this should work then ```python
return((cmp:=lambda i,x=x,y=y:len({*i}&{x,y})),points.index(list(filter(cmp,points))[[abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)].index(min(abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)))])if[i for i in points if cmp(i)]else-1)[1]
shorter cmp
actually the len call isn't needed i don't think
since empty sets should be falsey
this should work then ```python
return((cmp:=lambda i,x=x,y=y:{*i}&{x,y}),points.index(list(filter(cmp,points))[[abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)].index(min(abs(x-i[0])+abs(y-i[1])for i in points if cmp(i)))])if[i for i in points if cmp(i)]else-1)[1]
set intersection
returns a set of every element from each of the sets that's also in the other set
161 ```py
class Solution:
def nearestValidPoint(_,x,y,p):
t,i=3e4,-1
for j,(a,b)in enumerate(p):
a,b=abs(a-x),abs(b-y)
if 0in{a,b}and a+b<t:t,i=a+b,j
return i
if we're talking about absolute golfing
pretty sure this is valid
class Solution:
def nearestValidPoint(_,x,y,p):
t,i=3e4,-1
for j,(a,b)in enumerate(p):
a,b=abs(a-x),abs(b-y);if 0in{a,b}and a+b<t:t,i=a+b,j
return i
it's not
it was never that way
im pretty sure it was
well ya learn something new everyday
if always had a block so it always was a compound statement
and I don't even know what that later one is
so it was never a valid thing to place after a semicolon
huh
ig my memory is just being mean to me today
dist is not defined
ok
class Solution:nearestValidPoint=lambda s,x,y,p:min([(dist((x,y),c),i)for i,c in enumerate(p)if x==c[0]or y==c[1]]or[[0,-1]])[1]
might be the shortest solution
nvm there's a shorter one
class Solution:nearestValidPoint=lambda s,x,y,p:min([(dist((x,y),c),i)for i,c in enumerate(p)if x==c[0]or y==c[1]]or[[-1]])[-1]
do they create an instance of Solution or do they just use as namespace to store the function?
if it's just a namespace then the self arg isn't needed
they create an instance
yeah
class Solution:nearestValidPoint=lambda s,x,y,p:print(s)
<__main__.Solution object at 0x7f0d7787b730>
aw
what's the or for, inside the min()
are the points all integers?
not sure but i think i found a shortening
if x==c[0]or y==c[1] -> if x-c[0]&y-c[1]^1
if i remember the operator precedence correctly
then the results of that should be equivalent
if the points are all integers
actually that fails
if x==c[0]or y==c[1] -> if x-c[0]&y-c[1]==0
this works though
(still assuming they're integers)
no it does not
i already tried that
no?
yeah
fails with c == [5, 18]
and x == 7 and y == 11
it should be False, not True
i don't know why i remember that though
ah
its cause the true bits are all spaced out
so the & returns 0
i forgot bits can be spaced out 😔
Hey I'm new to python programming, can any explain me how it is used for gaming?
maybe not the right channel for normal programming
exactly
maybe try asking in #game-development or create a help thread #❓|how-to-get-help
what is it with people asking for help in the most cursed channel here
this is a regular thing
is this channel the most active channel among all channels in this category?
No, #discord-bots is by far
And maybe #algos-and-data-structs
things like that make me want to ask a legit question, too
how do i access original func through the new one's closure? ```py
def func(a, b):
print("[1]", a, b)
def func(a, b=func):
if a: b(a, b)
print("[2]", a, b)
func(True)
print(func)```
func.__defaults__[0]?
l3v is right
i always confuse kw only args and the ones that can either kw or pos
😔
anything after * or *args uses .__kwdefaults__
remember that
!e TIL ```py
def func(x=5, *, b=2, c):
^ non-default keyword argument follows default keyword argument
...
print('no syntax errors')
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
no syntax errors
makes sense 🤔
because there is no order to interfere with accessing c
ye
there's also / for pos only args
ik this is late but wouldnt type() be better for golfing
we do
!e ```py
f = lambda x: (lambda f: f(x(x)))(lambda x: f(x(x)))
f(f)```
@magic wraith :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 3, in <module>
003 | f(f)
004 | File "/home/main.py", line 1, in <lambda>
005 | f = lambda x: (lambda f: f(x(x)))(lambda x: f(x(x)))
006 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
007 | File "/home/main.py", line 1, in <lambda>
008 | f = lambda x: (lambda f: f(x(x)))(lambda x: f(x(x)))
009 | ^^^^
010 | File "/home/main.py", line 1, in <lambda>
011 | f = lambda x: (lambda f: f(x(x)))(lambda x: f(x(x)))
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/rolutoqita.txt?noredirect
oh hey lambda calc, excellent, i just asked a Q about recursion in lambda in the help channel btw
;ω;
!e
1 = 3
2 = 10
print(1-2)```
@teal cape :x: Your 3.11 eval job has completed with return code 1.
001 | File "/home/main.py", line 1
002 | 1 = 3
003 | ^
004 | SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?
!e
2 == 10
print(1-2)```
@teal cape :white_check_mark: Your 3.11 eval job has completed with return code 0.
-1
idon work D:
you can't [directly] assign to a literal value
and == is a comparison, not an assignment
!e ```py
from einspect import view
x,y=1,2
one, two = view(x), view(x)
one.value = 3
two.value = 10
print(1-2)
@tough willow :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 6, in <module>
003 | two.value = 10
004 | ^^^^^^^^^
005 | File "/snekbox/user_base/lib/python3.11/site-packages/einspect/views/view_int.py", line 46, in value
006 | self.digits[:new_size] = new_val.ob_digit
007 | ^^^^^^^^^^^^^^^^
008 | File "/snekbox/user_base/lib/python3.11/site-packages/einspect/structs/py_long.py", line 44, in ob_digit
009 | return (c_uint32 * size).from_address(items_addr) # type: ignore
010 | ~~~~~~~~~^~~~~~
011 | OverflowError: cannot fit 'int' into an index-sized integer
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/zizecohapi.txt?noredirect
Won't work on literals and int is already immutable class
ghost ping?
hello
Hello
i got ghost pinged again
shouldn't it show who did it in your notifications?
It doesn't show up if the message was deleted (which is what a ghost ping is in the first place)
Unless you mean mobile push notifications, which I didn't get because I was logged in on my pc
yeah meant notification externally
like desktop notification or mobile push notification
use a message logger
!e ```py
import base64 as b
import zlib
exec(zlib.decompress(b.a85decode(b'GhRjND/\,^&H88.@I[c#g,'7UKdK\B9p>8Yp5L6=4s-o]O@6?^;"ltC^2@u>m8>1kND9D(SAsPCO=*&dQJm'Y1jFiNQJJE=3U%mZu"Ci:?nII@+$fL8M,4)X=Ii5@AB%?)"iqga95;[4R/>D4lF).3IC2#75AstE59.#=+N"[DC\\]e&3[>!\\IZA%9f!k,)Q#g4J@AYBB&*Zs3:RT1i9>V"=LThTt)"e_hnH1No:8\'3rSEbc^8eGP*\'/S=(/D4g=1="&l;-a%QQK8:LJ^5.Qh:^F:Z=Vds/Mdi7oBGpm0nh,A+5bu=>7^BK'Psr7hL0PQ0,>"m&^Q"pIPB6@k-^%9eg!<8O]]>jBMeW^jPdaa".5ZG^CfUBPX1%b6<#$2a[3C+AkWS8R2nr%bf-p#b4A;Gi]kZUr#5#X#s^"Ja$Xh[I;Nn4EEra5,M2T"]!.Wn^H+:23'l-0um&Pmu"7AhC/bNBMP/g?1TGH2ho0hneV5$&Co<JR$TLal-W&e\U+sHV<6n=hqW;8KHOMlRB\R9!b;;p2<RuY@6?::usu@CN9F-3R]n'8P2\/:,XQKk6.MLdt@9DZU;V);8Tlhn8>/bE+Ra;B9et_)@hFTuK1RP;bG0fp,pD_[6l(rU;Li1QA.UB%d!i;!0(nHkDuJ1,LR(r\8KVQ[Lg?9Y=:0t::,P"PJMVQik:=7\1D;@.tn3:C^nP20@YCUsTD1gB$e0Qd7gW4I\LrHJkPD'@]-MSOkbT'eNKh4G#U@[XT%GjDNh7r[n#tDXa!n3ojE'^HDF&gQNHs=rH3K1Qle3+F.6/is=8U(i@R&t[(E8HUEDVjQT6+!-_Ci1-Un;#Z/ALfB=RFnQ>"&Hh&7@=5raeikW/&61!hi0=TLZX8&W)c`),')A(#VF(o5ku:n)FHV&q"Z)f]V;B_>24^U"I%7#"16n8eXj+b2?M(^T&iJ5-@*c"@HS4i8U%kS".pqkjjK@.66JL-K\q-V4')))
a = Assembler()
nc = a.consts_create_or_get
i = a.insn
i("LOAD_CONST", nc(5))
i("STORE_NAME", a.names_create_or_get("1"))
i("LOAD_CONST", nc(10))
i("STORE_NAME", a.names_create_or_get("2"))
i("PUSH_NULL")
i("LOAD_NAME", a.names_create_or_get("print"))
i("LOAD_NAME", a.names_create_or_get("1"))
i("LOAD_NAME", a.names_create_or_get("2"))
i("BINARY_OP", 0) # +
i("PRECALL", 1)
i("CALL", 1)
i("POP_TOP")
i("LOAD_CONST", nc(None))
i("RETURN_VALUE")
co = (a.pack_code_object())
exec(co)
print(f"Marshal b64 string is: {import('base64').b64encode(import('marshal').dumps(co))}")
@vast wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 15
002 | Marshal b64 string is: b'4wAAAAAAAAAAAAAAAB4AAAAAAAAA8ygAAABkAFoAZAFaAQIAZQJlAGUBegAAAKYBAACrAQAAAAAAAAAAAQBkAlMAKQPpBQAAAOkKAAAATikD2gEx2gEy2gVwcmludKkA8wAAAADaAHIJAAAAcgkAAAAAAAAAcggAAAByCAAAAA=='
1 = 5
2 = 10
print(1 + 2)
the big a85 blob you're seeing there is a golfed to death version of an assembler i wrote, so it fits within the 2000 minus something bytes limit
math.ceil(a/8) -> -(-a//8)
try mine
it's lacking a few things but it works
where
i think it goes like this ```
print(BytecodeParser(<function or code object>).decompile_stmt())
you think?
ok it does
>>> c=BytecodeParser(co)
>>> while t:=c.decompile_stmt():print(t)
...
1 = 5
2 = 10
print()
return None
``` i need to fix the last part
oh nvm it's the class that's the problem
fixed
More illegal things going on here
!e
match "random value, idk":
case undefined if False:
print(f"'undefined' got defined (= {undefined!r})")
case something_else:
print(f"'undefined' wasn't defined (= {undefined!r})")
@versed eagle :white_check_mark: Your 3.11 eval job has completed with return code 0.
'undefined' wasn't defined (= 'random value, idk')
python has silly name binding
What does !r do?
repr
necessary such that the condition can do stuff with undefined
ye
the binding happens before the condition check and then it's never unbound
it's just an unintuitive behaviour/silly lil thingy i discovered and thought would be found interesting by others
Unbinding would be a new concept for Python. What value should foo have here?
foo = "bar"
match "bar":
case foo if False:
pass
i think i phrased it wrong
As far as I know, the only place where something like this this exists now is the just-merged inlining of comprehensions
i meant, go out of scope
Right, but still. These foos are in the same scope
which is part of the unintuitive behaviour

