#esoteric-python
1 messages · Page 5 of 1
@rapid sparrow managed to fix if statements (with and without else clauses)
can you review the PR cause i have to sleep now
given a list of floats, return the indices of the 3 largest
i could write something for this, but i gotta do something meanwhile
with_indexes = [(f, i) for i, f in enumerate(the_floats)]; with_indexes.sort(); return [i for f, i in with_indexes[:3]]
this question wasn't esoteric 🙂
well, i wanted a one liner
so it had the potential
np.array([i[1] for i in sorted(enumerate(arr), key=lambda x: x[1], reverse=True)[:num]])came up with something already anyway
one-liners are overrated, and it's easy to make anything into a one-liner.
I have been summoned
h😀😀😀
reduce max-and-shift using a 3-length queue initialized with -Infinity
death.py? i wonder what that does
[i for i, f in sorted(enumerate(floats), key=lambda t:t[1])][::-1][:3]
although sometimes a blue screen of death
If you run it, your computer probably won't blow up
i have 2370M cpu, Win 10, 8G ram, intel hd graphics 3000
ok
opposite of the conventional more ram=less time
a = "."
for a in range(30)
a += a
file = open("file.txt","a")
for b in range(1000):
file.write(a)
file.close()
I think your computer would like it
Disclaimer: Don't run
I think my computer will raise a TypeError
now it raises SyntaxError, then it will raise TypeError 🙂 details are hard!
that gives me a type error ;-;
it could also damage your hard drive
yum, 1000 delicious GiB for my ssd if i'm not mistaken
it could damage your drive if it's 25 years old and in heavy use
well, yes
1000 GB is nothing
it sounds like you're able to have 2, maybe 3 triple a titles installed at the same time, well done
wdym
i have just one drive that has just 140 GB
i meant 1000 GB is nothing if you want to damage the drive
true, it's repeated write cycles and not one wide write that hurts for ssds, i'm not sure what would be harmful for hdds though, aside from dropping them on the floor
dropping them on the floor then stepping on them
print = open('3d_engine/objs/faced_suzanne.obj', 'r').readlines()
from itertools import chain
import turtle as open
open.tracer(0, 0)
for input in tuple(tuple(tuple([list(map(float,_[2:].split()))for _ in print if _[:2]=='v '][dict])for dict in len)for len in[[int(dict.split("/")[0])-1 for dict in len]for len in[_[2:].split()for _ in print if _[:2]=='f ']]):open.penup();open.goto((input[0][0]*-200*1/2**(1/2)-input[0][2]*(10*2**(1/2))**2*1/2**(1/2),(input[0][0]*-200*1/2**(1/2)+input[0][2]*(10*2**(1/2))**2*1/2**(1/2)+input[0][1]*40**2/8*2**(1/2))/3**(1/2)));open.pendown();[open.goto((_[0]*-200*1/2**(1/2)-_[2]*(10*2**(1/2))**2*1/2**(1/2),(_[0]*-200*1/2**(1/2)+_[2]*(10*2**(1/2))**2*1/2**(1/2)+_[1]*40**2/8*2**(1/2))/3**(1/2)))for _ in input]
open.hideturtle()
open.update()
open.exitonclick()
visualize .obj files wireframe in isometric view
using turtle
why do you redefine print
i wanted to see if i could push that limit
and then import turtle as open
same reason
kinda weird
Damn good job
Looks really good
thanks
!e
f'{(hw:="++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.")}{(bf:=lambda prgm:print(((pc:=0),(ti:=0),(t:=[0]*30000),(rs:=[]),(o:=""),(*(((char:=prgm[pc]),(((ti:=ti+1),(pc:=pc+1))if char==">"else(((ti:=ti-1),(pc:=pc+1))if char=="<"else(((t.__setitem__(ti,(t[ti]+1)&0xFF)),(pc:=pc+1))if char=="+"else(((t.__setitem__(ti,(t[ti]-1)&0xFF)),(pc:=pc+1))if char=="-"else(((o:=o+chr(t[ti])),(pc:=pc+1))if char=="."else(((t.__setitem__(ti,ord(input())%0xFF)),(pc:=pc+1))if char==","else(((rs.append(pc),(pc:=pc+1))if t[ti]!=0 else((bc:=1),(*(((pc:=pc+1),((bc:=bc+1)if prgm[pc]=="["else(bc:=bc-1)if prgm[pc]=="]"else...),(pc:=pc+1))for _ in iter(lambda:bool(bc),False)),)))if char=="["else((pc:=rs.pop())if char=="]"else...)))))))))for _ in iter(lambda:pc<len(prgm),False)),))[-1][-1][-1][0]))}{(bf(hw))}'
@sick hound :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello World!
one line brainf*** hello world i guess
"but you could use globals().__setitem__ instead of walrus!!" i enjoy walrus operator.
the funny operator
I also like the ^_^ operator
I wanted to say that this is the invalid syntax, but then I realized...
Heyo
another golfing challange
Miller Rabin test (it checks if the given number is prime
!e
import random
def miller_rabin(n, k):
if int(repr(n)[-1]) % 2 == 0:
return False
else:
d = n - 1
s = 0
while d % 2 == 0:
d = d // 2
s += 1
for i in range(k):
r = random.randint(1, n - 1)
for j in range(s):
x = pow(r, d * 2**j, n)
if ((j == 0 and x == 1)
or (x == n - 1)):
break
elif (j == s - 1):
return False
return True
print(miller_rabin(11,7))
@finite blaze :white_check_mark: Your 3.11 eval job has completed with return code 0.
True
repr() to str()- one character less
import random
def miller_rabin(n, k):
if~n&1:return False
d=n-1;s=0
while~d&1:s+=1;d//=2
while k:
k-=1;r=random.randint(1,n-1)
for j in range(s):
x=pow(r,d<<j,n)
if x==n-1or j==0and x==1:break
elif j==s-1:return False
return True
assert miller_rabin(11,7)
```haven't done code golf in a while, but this should be equivalent
lots of room for improvement still
mr= lambda t:[n:=12,k:=7,r:=(0 if int(repr(n)[-1])%2==0 else 1)]and None
I wonder how can I return r from this lambda?
and rshould be fine afaict
check if number is even, honestly don't remember if it's the best way to do that
n&1 checks if last bit is 1, that is is number odd, and ~n inverts all bits
i am doing int(str(n)[-1])%2==0 cuz I was thinking that it might be faster than n % 2==0 if the number is realllllyyyy big
it won't be
oke
allocating the buffer for the string will be far slow than any amount of bigint math
No, too bad there are no while comprehensions..
you can do a listcomp over a iter(lambda: cond, False)
so i guess i'll just do a for loop instead
mr= lambda t:[n:=11,k:=7,r:=(False if ~n&1 else d:=n-1,s:=0, [d=d//2,s+=1]for _ in iter(~d&1, False))]and r
so it is telling me that d is not defined
[d=d//2,s+=1] here
but everything is okay with s+=1
what does t do?
I think you might even be able to remove the space in j==s-1 for
Like you did with the ~n&1 else
yes, this cheap syntax highlighting makes that less obvious
It takes too long to run, there's an infinite loop somewhere
[-1]
assert(m:=lambda n,k:0if~n&1else(lambda d,s,R,k=[k]:([(s:=s+1,d:=d>>1)for _ in iter(lambda:d&1,1)],not any([(k.__setitem__(0,k[0]-1),r:=R(1,n-1),any([j==s-1for j in range(s)if not((x:=pow(r,d<<j,n))==n-1or j==0and x==1)]))[-1]for _ in iter(lambda:k,[0])]))[-1])(n-1,0,__import__('random').randint))(11,7)
mildly tested
not((x:=pow(r,d<<j,n))==n-1or j==0and x==1)
``` might be ```py
~(((x:=pow(r,d<<j,n))==n-1)|(j==0)&(x==1))
those are only bitwise though, replacing stuff that compares to zero
what?
!e ```py
if not 2:print('derp')
if~2:print('derp')
@floral meteor :white_check_mark: Your 3.11 eval job has completed with return code 0.
derp
the arguments are boolean
just because something is in general not equivalent doesn't mean it's not useful here
I just read it properly and you are right the arguments are boolean
this is so weird but i cant stop watching it
the channel?
This channel is for the mad scientists of python
@fleet bridge :white_check_mark: Your 3.11 eval job has completed with return code 0.
slice('X', (slice(10, 20, 30),), {'__module__': '__main__', '__qualname__': 'X'})
I dont understand...
- Get metaclass: type(base) [it is class slice in this case]
- Call metaclass: slice(clsname, bases, ns)
Is it how it works?
It is very very weird and counterintuitive
lmao you made the cursed slice class
It isnt a class
It is instance of builtin slice
I will try to break mypy using this behavior
Is this way of using class statement documented?
yes
Also works with map and zip
combined with (c)python scientists (people who know the internals)
But I can't seem to use X for an instance o f slice.
wdym by that?
after I say:
class X(slice(10, 20, 30)): ...
I cannot seem to use X for anything, except printing
I cannot call/instantiate an X i cannot use it for an already instantiated slice, what good is it?
so like you're saying you wanna use an example/test for something else other than testing?
I mean it would be lovely to use class X(slice(something)):...
in place of x=slice(something)
So that when I need to do an inordinate number of
for y in Y[something]:
I can do
for y in Y[X] instead.
but class X(slice(something)):... is so much more essoteric than x=slice(something) so that would be better, but it doesn't seem to work that way, so I'm trying to understand how it is working.
that's because it's different
class X(slice(...)) is equivalent to
X = slice(class name, bases tuple, namespace)
got it.
and since slice(...) appears inside the bases, it's part of the tuple xd
!e ```py
x = list(range(100))
class Z(slice(3,6,1)): ...
print(x[Z.stop[0]])
@vague cairn :white_check_mark: Your 3.11 eval job has completed with return code 0.
[3, 4, 5]
The Forbidden Slice
!e ```py
@lambda :print(list(range(100))[.stop[0]])
class Z(slice(3,6,1)):...
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
[3, 4, 5]
same thing
Much better, yes.
!e```py
#Or I think this is what I'm looking for:
@lambda :.stop[0]
class Z(slice(3,6,1)):...
#and much later...
print([_ for _ in range(100)[Z] ])
@vague cairn :white_check_mark: Your 3.11 eval job has completed with return code 0.
[3, 4, 5]
_ for _ in can be replaced by *
i broke the rpython type annotator https://media.discordapp.net/attachments/702883266998566976/1015433619537416213/unknown.png
noice
90% of my blue screens of death happen when I'm running a python script I've written
A game of snake? unfortunately Windows has stopped due to HYPERVISOR_ERROR.
Pretty matrix rain? Nope, irql decides to be not_less_than_or_equal
hehehehehehe
one line .env parser, can someone do better? :P
parse_env=lambda:(f:=open(".env","r"),{(t:=l.split("="))[0].strip():t[1].strip()for l in f.read().splitlines()},f.close())[1]
For once, you could just not close the file.
not really
parse_env=lambda:{(t:=l.split("="))[0].strip():t[1].strip()for l in open('.env')}
f is only visible from within the lambda, so it will anyways get garbage collected
though it does leak the file
didn't know you could iterate directly from a file objet
why would it?
in CPython it won't, but I am pretty sure the file stays open even if the iterator ends
Right, okay, not guaranteed by the language, that's true.
parse_env=lambda:dict(map(str.strip,l.split("="))for l in open('.env'))
fiwe descwiptow weak 
@mellow salmon :white_check_mark: Your 3.11 eval job has completed with return code 0.
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
parse_env=lambda:dict(map(lambda s:map(str.strip,s.split('=')),open('.env')))
parse_env=lambda:dict(map(lambda s:s.split('='),open('.env'))) # without stripping
!e
import os
files = [f for f in os.listdir(os.cwdb) if os.path.isfile(f)]
print(f"Files\n{files}")
print(os.listdir(os.cwdb))
@soft vapor :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | AttributeError: module 'os' has no attribute 'cwd'
!e
import os
path = os.getcwdb() + "/config"
files = [f for f in os.listdir(path) if os.path.isfile(f)]
print(f"Files\n{files}")
print(os.listdir(path))
@soft vapor :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | Files
002 | []
003 | [b'requirements', b'config', b'user_base']
!e
import os
path = os.getcwdb() + b"/config/snekbox.cgf"
#files = [f for f in os.listdir(path) if os.path.isfile(f)]
#print(f"Files\n{files}")
#print(os.listdir(path))
file = open(path, "r")
print(file.read())
@soft vapor :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | Files
002 | []
003 | [b'snekbox.cfg', b'gunicorn.conf.py', b'__pycache__']
!e
import os
path = os.getcwdb() + b"/config/snekbox.cgf"
#files = [f for f in os.listdir(path) if os.path.isfile(f)]
#print(f"Files\n{files}")
#print(os.listdir(path))
file = open(path, "r")
print(file.read())
@soft vapor :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | FileNotFoundError: [Errno 2] No such file or directory: b'/snekbox/config/snekbox.cgf'
!e
print(open("/snekbox/config/snekbox.cfg").read())
@potent flare :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | name: "snekbox"
002 | description: "Execute Python"
003 |
004 | mode: ONCE
005 | hostname: "snekbox"
006 | cwd: "/snekbox"
007 |
008 | time_limit: 6
009 |
010 | keep_env: false
011 | envar: "LANG=en_US.UTF-8"
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/zecixosozu.txt?noredirect
!e
import os
print(os.listdir("/snekbox/user_base/lib/python3.11/site-packages"))
@potent flare :white_check_mark: Your 3.11 eval job has completed with return code 0.
['sniffio-1.2.0.dist-info', 'sympy', 'dateutil', 'pendulum', 'pytzdata', 'toml', 'async_generator-1.10.dist-info', 'beautifulsoup4-4.11.1.dist-info', 'python_dateutil-2.8.2.dist-info', 'pendulum-2.1.2.dist-info', 'arrow', 'idna', 'numpy', 'PyYAML-6.0.dist-info', 'six-1.16.0.dist-info', 'trio-0.21.0.dist-info', 'fishhook', '_yaml', 'arrow-1.2.2.dist-info', '__pycache__', 'anyio', 'numpy-1.23.1.dist-info', 'bs4', 'fuzzywuzzy-0.18.0.dist-info', 'pytz', 'sympy-1.10.1.dist-info', 'outcome', 'mpmath', 'sniffio', 'attrs-22.1.0.dist-info', 'pandas', 'outcome-1.2.0.dist-info', 'pytz-2022.2.dist-info', 'anyio-3.6.1.dist-info', 'typing_extensions-4.3.0.dist-info', 'pytzdata-2020.1.dist-info', 'async_generator', 'networkx', 'attr', 'soupsieve', 'sortedcontainers-2.4.0.dist-info', 'fuzzywuzzy', 'sortedcontainers', 'isympy.py', 'forbiddenfruit-0.1.4.dist-info', 'more_itertools-8.14.0.dist-info', 'more_itertools', 'idna-3.3.dist-info', 'toml-0.10.2.dist-info', 'lark', 'fishhook-0.1.4.dist-info', 'lar
... (truncated - too long)
Full output: https://paste.pythondiscord.com/manowuwuda.txt?noredirect
that's a lot
!e
import os
print(sorted([x for x in os.listdir("/snekbox/user_base/lib/python3.11/site-packages") if ".dist-info" not in x]))
@last locust :white_check_mark: Your 3.11 eval job has completed with return code 0.
['__pycache__', '_yaml', 'anyio', 'arrow', 'async_generator', 'attr', 'attrs', 'bs4', 'dateutil', 'fishhook', 'forbiddenfruit', 'fuzzywuzzy', 'idna', 'isympy.py', 'lark', 'more_itertools', 'mpmath', 'multidict', 'networkx', 'numpy', 'outcome', 'pandas', 'pendulum', 'pytz', 'pytzdata', 'six.py', 'sniffio', 'sortedcontainers', 'soupsieve', 'sympy', 'toml', 'trio', 'typing_extensions.py', 'tzdata', 'yaml', 'yarl']
!e
import fuzzywuzzy
help(fuzzywuzzy)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | NameError: name 'help' is not defined
¯_(ツ)_/¯
fuzzywuzzy is a library for fuzzy matching text IIRC
Why did my Gboard have an auto complete suggestion for it
!e
import fishhook
@versed eagle :warning: Your 3.11 eval job has completed with return code 0.
[No output]
Hi, I'm trying to compute a property of a class which depends on the classes __mro__ I tried doing something like this
class Foo(Bar):
x = __mro__[::-1]
but I get x = __mro__[::-1]
NameError: name '__mro__' is not defined
Is there a way to do something like this? at what point are things like __mro__ actually defined / available on classes?
No, they are class attributes, but not available during class definition.
Class decorator would be the easiest way
!e
def orm_as_x(cls):
cls.x = cls.__mro__[::-1]
return cls
class Foo:0
@orm_as_x
class Bar(Foo):0
print(Bar.x)
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
(<class 'object'>, <class '__main__.Foo'>, <class '__main__.Bar'>)
You can do it inside the class definition as well, with a self-replacing descriptor, but if this is enough, I'd use this ^
no, it's just pre-installed packages with snekbox
You can also use a metaclass or __init_subclass__ but the methods above are preferable.
n = 128;
Graphics3D[Table[Point[{x, y, BitXor[x, y]}], {x, 0, n - 1}, {y, 0, n - 1}]]
``` code for wolfram mathematica
view from top
n = 128;
Image[Table[BitXor[x, y]/n, {x, 0, n - 1}, {y, 0, n - 1}]]
``` code to generate 2d images
here you can see relative speed of euclidean algorithm for computing gcd(x, y)
white = slower, black = faster
set of coprime integers
white = x and y are coprime
black = not coprime
riemann function plot
f(x) = 1/q if x = p/q (and p and q are coprime)
f(x) = 0 if x is irrational
every line = binary representation of 1/x number (x is line number)
black = digit 0, white = digit 1
- count number of 1's in binary representation of x and y
#x > #y - white
#x == #y - grey
#x < #y - black
same, but white for == and black otherwise
for all rational numbers p/q (p and q are coprime) draw point (p/q, q)
i have wolfram mathematica code for all of these pictures
if you want, i can share it
Hey @fleet bridge!
It looks like you tried to attach file type(s) that we do not allow (.bmp). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a, .csv, .json.
Feel free to ask in #community-meta if you think this is a mistake.
another picture without explanation
yes, ik what it is
but it used to be that fishhook wasnt in the 3.11 packages
so to use it you had to do !e 3.10
ah ok, just confused with the wording
sorry!
my grammar is bad when im tired
Wow, nice
'Tis sad that Wolfram Mathematica isn't free
you can use online interpreter, it is free
and you can get 1 week (or 1 month, i dont remember) trial for desktop wolfram mathematica
these pictures are interesting, but what do they have to do with esoteric Python?
Hello
import sys;a,b=sys.stdin.read().split();a,b=int(a),int(b);print(min(a,b),max(a,b))```
Is there any way anyone can find to shorten this
by even one character
not sure why you need to handle input separated by arbitary whitespace (instead of just space separated, or just newline separated), but:
a,b=open(0).read().split();print(min(c:=int(a),d:=int(b)),max(c,d))
print(*sorted(map(int,open(0).read().split())))
holy smokes
and if you ignore the loose input format from the original code and just assume 2 ints separated by newline:
print(*sorted(map(int,open(0))))
for a total of 32 bytes
(for reference, original code is 83 bytes)
I think I corrupted my python installation lmao
If the current directory is desktop, the terminal host crashes with ntstatus division by zero when attempting to run python.
huh
thank you! I had to change the format bc of how we have to submit the solution but that was really helpful!
Never admit to the question being homework when asking for help, because people are less likely to help.
!e to whoever asked how to make hello world with type, here you go ```py
d = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
from opcode import opmap
globals().update(opmap)
print_hello_world = type(f:=lambda:0)(type(f.code)(0, 0, 0, 0, 2, 1, bytes([
RESUME, 0,
PUSH_NULL, 0,
LOAD_CONST, 1,
LOAD_CONST, 0,
IMPORT_NAME, 0,
LOAD_ATTR, 1,
*[CACHE, 0]*d[LOAD_ATTR],
PRECALL, 0,
CACHE, 0,
CALL, 0,
*[CACHE, 0]*d[CALL],
POP_TOP, 0,
LOAD_CONST, 0,
RETURN_VALUE, 0,
]), (None, 0), ("hello", "main"), (), name, "<manual-code>",
f"{name}.<manual-code>", 1, b"", b""), globals())
print_hello_world()
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello world!
you cant open an int, has to be a string
0 is for stdin? That works
>>> print(open(0, "r"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: open: path should be string, bytes or os.PathLike, not int
I do not get that error
!e print(open(0))
@languid night :white_check_mark: Your 3.11 eval job has completed with return code 0.
<_io.TextIOWrapper name=0 mode='r' encoding='utf-8'>
from python docs:
(talking about open arguments)
file is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped. (If a file descriptor is given, it is closed when the returned I/O object is closed unless closefd is set to False.)
pathlike object:
An object representing a file system path. A path-like object is either a str or bytes object representing a path, or an object implementing the os.PathLike protocol. An object that supports the os.PathLike protocol can be converted to a str or bytes file system path by calling the os.fspath() function; os.fsdecode() and os.fsencode() can be used to guarantee a str or bytes result instead, respectively. Introduced by PEP 519.
doesn't say int is valid
weird
@languid night :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | OSError: [Errno 9] Bad file descriptor
It can accept FDs 0-2
ik what they are lmao
So you should understand opening 0 is referring to stdin
I'm not sure why it doesn't work for you
it accepts more than 0-2 they just need to be open
In [9]: sock = socket.socket()
In [12]: open(sock.fileno())
Out[12]: <_io.TextIOWrapper name=12 mode='r' encoding='UTF-8'>
sorry i wasn't there for a bit, i had to go
it might be a version thing then?
my sys.version is this: 3.11.0rc1 (main, Aug 8 2022, 18:31:54) [GCC 9.4.0]
Whats the point in passing in mode, even though default is “r” already? Or just common practice
intent is more understandable
turned out my python was messed up
instead of calling __builtins__.open, it was calling os.open, which has different requirements for whats passed to it
¯_(ツ)_/¯
user@host:~$ python3
Python 3.11.0rc1 (main, Aug 8 2022, 18:31:54) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> open(0)
<_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>
>>> import os; os.open(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: open() missing required argument 'flags' (pos 2)
>>> import os; os.open(0, "r")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: open: path should be string, bytes or os.PathLike, not int
so what i was getting was a completely different thingy
so at least that got fixed
given an array of floating point numbers (any length) return a tuple (ordered greatest to least based on the floating point number) of the index of the item and the floating point number. i.e ```py
def func():...
arr = (0.1, 0.2, 0.05, 0.5, 0.3, 0.8)
print(func(arr))# should output ((0.8, 5), (0.5, 3), (0.3, 4)) ....```
can anyone make a func like that (golfed as much as possible)
lambda x:sorted(zip(x,range(len(x))),reverse=1))
thanks
!e
import inspect
print(inspect.stack())
@dry mirage :white_check_mark: Your 3.11 eval job has completed with return code 0.
[FrameInfo(frame=<frame at 0x7fbb336f45c0, file '<string>', line 3, code <module>>, filename='<string>', lineno=3, function='<module>', code_context=None, index=None, positions=Positions(lineno=3, end_lineno=3, col_offset=6, end_col_offset=21))]
!e
import inspect
print(5)
x = inspect.stack()[-1]
print(x)
print(x.code_context)
@dry mirage :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 5
002 | FrameInfo(frame=<frame at 0x7f62742ac680, file '<string>', line 6, code <module>>, filename='<string>', lineno=5, function='<module>', code_context=None, index=None, positions=Positions(lineno=5, end_lineno=5, col_offset=4, end_col_offset=19))
003 | None
curious, why no code context in -c
Well done, I was thinking:
lambda x:[a,b for b,a in sorted(enumerate(x),key=lambda y:y[1]),reversed=1)] which isn't nearly as good.
and lambda x:sorted(map(reversed,enumerate(x)),reverse=1) hasn't worked since python2
Hi friends,
How are you?
By the way, I would like to make a birthday wish for my best friend tomorrow, it's her birthday. So I would like to wish her birthday using pyhton (turtle package or any other package)
Would you like to help me?
lambda x:sorted(zip(x,range(len(x))))[::-1]
golfeder
Do you ever write code that seems normal but is in fact terrifying?
def inner(fn: Callable[[T, U], V]) -> InfixOperator[T, U, V]:
ctx = context(fn)
if ctx == FunctionContext.Local:
raise TypeError(
f"Custom operator '{op}' for '{fn.__qualname__}' cannot be defined in a local scope"
)
operator = InfixOperator(op, flipped, fn)
if ctx == FunctionContext.Global:
if BUILTIN_OPERATORS.get(op) is not None:
raise TypeError(
f"Builtin operator '{op}' for '{fn.__qualname__}' cannot be defined in a global scope\n"
"Module-scoped operators must not be the same as built-in ones"
)
_bind_to(sys.modules[fn.__module__], operator)
return operator
BUILTIN_OPERATORS.get(op) is not None
you know in exists, right?
lambda x:sorted(zip(x,range(9**99)))[::-1]```
[print(i)for i in range(101)if(lambda n,p=1:[p:=0for i in range(2,n)if n%i<1]*0 or n>1&p>0)(i)]
made this 95 character prime generaator
very pog
82 ```py
[print(i)for i in range(101)if(lambda n:n>1>any(1for i in range(2,n)if n%i<1))(i)]
78 ```py
[print(i)for i in range(101)if(lambda n:n>1>any(n%i<1for i in range(2,n)))(i)]
65 ```py
[print(n)for n in range(101)if n>1>any(n%i<1for i in range(2,n))]
what the fuck
61
[print(n)for n in range(2,101)if all(n%i for i in range(2,n))]
!e 79 (not winning, but style points)
[print(i)for i in range(2,101)if not __import__("re").match(r"(11+)\1+$","1"*i)]
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 2
002 | 3
003 | 5
004 | 7
005 | 11
006 | 13
007 | 17
008 | 19
009 | 23
010 | 29
011 | 31
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/obezasikod.txt?noredirect
its shorter to do:
import re;[print(i)for i in range(2,101)if not re.match(r"(11+)\1+$","1"*i)]
i like the regex, its not every day that you see regex get used for anything except trying to relearn regex for the 18th time
It's my all-time favorite regex, because famously checking for primal length is impossible with a regular language :)
yeah, you can't fit a backref that holds an unbounded string into a finite automaton
but that is super cool
Ok, yeah, you definitely get style points.
also 61
x=2
while 999>x:0<all(x%i for i in range(2,x))==print(x);x+=1
also 61, but finishes with style
def f(x):all(x%y for y in range(2,x))and print(x);f(x+1)
f(2)
55
x=2
while 101>x:103**~-x%x+107**~-x%x==2==print(x);x+=1
54 ```py
x=2
while 101>x:103**~-x%x+107**~-x%x<3==print(x);x+=1
in that case this works too
50
x=2
while 101>x:4**~-x%x+3**~-x%x<3==print(x);x+=1
back to working on this cursed project, this time actually being somewhat productive and keeping code clean
(this outputs (1, 2, 9999))
Types are now also easier to define: ```py
class PyTupleObject(PyVarObject):
def init(self, addr: int):
super().init(addr)
self.array("ob_item", lambda _addr: Pointer(_addr, PyObject), self.ob_size) # since ob_size is a property that can be read, this array is of dynamic size :D
Strings are a pain because their structs aren't 100% consistent
maybe maybe maybe
that looks really similar to my native_ctypes project from a while back
i did a lot more screwery with metaclasses tho ```py
class TupleObj(PyVarObject):
ob_item: field(lambda inst:py_object*inst.ob_size)
```py
>>> from native_ctypes import *
>>> x = (0,1,2)
>>> t = TupleObj.from_address(id(x))
>>> print(t)
TupleObj({'ob_refcnt': 1, 'ob_base': <class 'tuple'>, 'ob_size': 3, 'ob_item': [0, 1, 2]})
>>> t.ob_item
(py_object*3)([0, 1, 2])
>>> t.ob_item[0] = 1
>>> x
(1, 1, 2)
>>> ```
!e 3.10
x = 1 +3
+4
print(x)
@serene stratus :white_check_mark: Your 3.10 eval job has completed with return code 0.
4
I think we were working on it around the same time; You also made a getmem impl but that one didn't work for me anymore
Ah yea I never got around to making the getmem impl swappable
How did you end up implementing your repr? I'm torn between yours and mine ```py
my_tuple_repr.struct_str()
struct PyTupleObject {
Py_ssize_t ob_refcnt;
struct PyTypeObject* ob_type;
Py_ssize_t ob_size;
struct PyObject*[3] ob_item;
}
my_tuple_repr.repr()
PyTupleObject(
ob_refcnt=3,
ob_type=PyTypeObject(
ob_refcnt=229,
ob_type=PyTypeObject(
ob_refcnt=87,
ob_type=...,
ob_size=0,
tp_name='type',
...
),
ob_size=0,
tp_name=*'tuple',
...
),
ob_size=3,
ob_item=[
..., # small bug in recursion detection, whoops
*PyObject(
ob_refcnt=830,
ob_type=*PyTypeObject(...),
)
PyObject(
ob_refcnt=2,
ob_type=...
)
]
)```
Hey does anyone know a good way of creating a package registry in python
(I need it for my esolang)
my objects have a pretty repr, my structures don't yet, I need to implement that still
ended up making a config flag to shorten PyTypeObjects ```py
PyTupleObject(
ob_refcnt=3,
ob_type=*<type 'tuple'>,
ob_size=3,
ob_item=[
PyObject(ob_refcnt=1692, ob_type=<type 'int'>),
PyObject(ob_refcnt=830, ob_type=<type 'int'>),
PyObject(ob_refcnt=2, ob_type=<type 'int'>)
]
)
esoteric python is either filled with code gore or filled with people showing the progress they made on a project that has been attempted before
yup
though tbf I'm mostly just rewriting what to my knowledge was the first version of this
anyone have nice license system for python scripts ?
allow toggling pretty print: 
what do you mean? In terms of software licensing or license distribution/verification similar to Jetbrains or what
there is an hidden null terminator haha
See related issue: https://github.com/python/cpython/issues/96670
cool
TIL the __repr__ function on tuples supports recursion despite the fact that that shouldn't ever be a concern in normal situations
Tuples' __str__ and __repr__ call their objects' __repr__ I think
!e
class X:
def __repr__(self):
return f'<{self.v}>'
a = X()
u = a,
a.v = u
print(repr(u))
``` it can come into play (though if you don't use the tuple you do just get a RecursionError)
@proper vault :white_check_mark: Your 3.11 eval job has completed with return code 0.
(<(...)>,)
I see
Repr does, hash doesn't
!e ```py
from ctypes import *
x = (0,)
py_object.from_address(id(x)+tuple.basicsize).value = x
print(x)
print(hash(x))```
@rugged sparrow :x: Your 3.11 eval job has completed with return code 139 (SIGSEGV).
((...),)
@rugged sparrow did you ever figure out strings? (Currently on 3.9.7 but implementing strings the way they're defined doesn't seem to work)
I think I did once, but it was in the repl just messing around so it's lost forever lmao. I can take a look in about 30
Lol
I used to have it but my old repo is down cuz the craptop hosting it died and I have no clue how I ever did it
The biggest problem seems to be the bitfield; I don't get consistent results
I wonder if I messed up in alignment somewhere
Because that's the only thing I'm not checking for
yea i dont think i bothered to implement bitfields yet
oh no my design doesn't have a good way to handle aligns
(another thing i didnt bother to add)
why is the actual text this far away
I think my MEMORY.seek isn't working reliably
oh wait I see
thank you contextmanagers
yea thats why i prefer my getmem(addr, size, fmt='c') that just returns a memoryview with the given format and size
yeah it was just that I was seeking again in a function call :P
now to figure out how to turn a bytes object containing a wchar_t array into a byte array
oh wait I can just use utf-16 can't I
the only painful part now is figuring out sizeof(wchar_t) from python, ideally without use of ctypes
You could divide the length of the bytes by the length of the string right?
the problem is that wstr_length is the only value I have as reference
anyways, memhax for 3.9 is now on pypi for all to enjoy
no link to a repo there?
Is that an anime background in your IDE?
How is that useful
idk I mostly just enjoy the color scheme it adds
16 bits, 2 bytes
if you're using only windows then that's the value
i don't think "figuring out the size" implies hard coding
well probably not
try:
import array
array.array('u', ['\U00010000'])
except TypeError:
sizeof_wchar_t = 2
else:
sizeof_wchar_t = 4
that's one way to figure out
Is it possible to use .out files from cpp as imports in python scripts?
Technically yes, by compiling it as a shared library (remember to use extern "C" { ... }) and renaming it to something like libname.linux-x86_64-cpython-310, then importing it with import libname should work. But you'd rather stick with setuptools for the sake of simplicity and avoiding dealing with compiler options. Here's the official python documentation for that: https://docs.python.org/3/extending/extending.html#writing-extensions-in-c
class CursedInt(int):
def __init__(self, num: int):
self.c = 0
super().__init__()
def __neg__(self):
self.c += 1
self.c %= 2
if self.c:
return super().__neg__()
return -(self - 1)
x = CursedInt(10)
assert -x == -10
assert --x == 9
this is one of the most basic ones 😔
overengineered imo
the trick here is just to use a \0 lmfao
aka null terminator
!e ```py
from fishhook import hook, orig
from sys import _getframe
from opcode import opmap, opname
EXTENDED_ARG = opmap["EXTENDED_ARG"]
def get_arg(codestring, idx):
arg = codestring[idx + 1]
try:
if codestring[idx - 2] is EXTENDED_ARG:
arg |= codestring[idx - 1] << 8
if codestring[idx - 4] is EXTENDED_ARG:
arg |= codestring[idx - 3] << 16
if codestring[idx - 6] is EXTENDED_ARG:
arg |= codestring[idx - 5] << 24
except IndexError:
pass
return arg
@hook(int)
def neg(self, UNARY_NEGATIVE=opmap["UNARY_NEGATIVE"],
NAME_OPS={"LOAD_NAME": ("co_names", lambda x: x),
"LOAD_GLOBAL": ("co_names", lambda x: x >> 1),
"LOAD_FAST": ("co_varnames", lambda x: x),
"LOAD_CLOSURE": ("co_varnames", lambda x: x),
"LOAD_DEREF": ("co_varnames", lambda x: x),
"LOAD_CLASSDEREF": ("co_varnames", lambda x: x)}):
f = _getframe(1)
code = f.f_code
co_code = code.co_code[:f.f_lasti]
if co_code[-2] is UNARY_NEGATIVE is not (instr := co_code[-4]):
if tup := NAME_OPS.get(opname[instr]):
attr, func = tup
name = getattr(code, attr)[func(get_arg(co_code, -4))]
f.f_locals[name] = res = f.f_locals[name] - 1
return res
else:
return orig(self) - 1
return orig(self)
x = 5
print(--x, x)
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
4 4
@soft prairie better
it actually changes the variable
now make x-- 🔫
can't it's on the other PC
if you want to test it out, clone and build
https://github.com/thatbirdguythatuknownot/cpython/tree/modified-again
@tiny knot try now ```py
(i:=import,w:=(255,)*3,P:=i("pygame"),L:=i("pygame.locals",1,1,'a'),d:=P.draw.rect,V:=P.Vector2,R:=i("random").randint,S:=P.display.set_mode((600,)*2),C:=P.time.Clock(),sp:=V(10,10),sb:=[],di:=V(10,0),n:=lambda:globals().update(fo=V(R(0,59)*10,R(0,59)*10)),n(),[(sb:=sb[1:]+[V(sp)],sp.iadd(di),(sb:=[],sp.update(10,10))if sp in sb or not 0<=sp.x<=600>=sp.y>=0else None,(sb:=[V(-10,-10)]+sb,n())if sp==fo else None,S.fill((0,)*3),d(S,(255,0,0),(fo.x,fo.y,10,10)),d(S,w,(sp.x,sp.y,10,10)),[d(S,w,(p.x,p.y,10,10))for p in sb],[1/0if ev.type==L.QUIT else di.update({L.K_w:(0,-10),L.K_s:(0,10),L.K_a:(-10,0),L.K_d:(10,0)}.get(ev.key,di))if ev.type==L.KEYDOWN else None for ev in P.event.get()],P.display.update(),C.tick(10))for _ in iter(int,1)])
TypeError: can only concatenate list (not "pygame.math.Vector2") to list
edited
it does work.. but you can't teleport in the edges
oh
seems the original program also has the problem
this is 162 less than original
nice.
my head isn't working after just 91
It's a feature 😠
here's a notable downsize py not(0<=sp.x<=600and 0<=sp.y<=600) to ```py
not 0<=sp.x<=600>=sp.y>=0
cool
that the snake break dances on the edge of the screen? 😄
...... Why wouldn't you want that xD
0
3cell_pos:1
3cell1:0
3cell2:0
3cell3:0
3cell4:0
3input:+>+>+>+<++<-
6n\12\3index:^n-1;3letter:@input.index;?letter=>|3cell_pos=^cell_pos+1|?letter=<|3cell_pos-1|?letter=+|?cell_pos=1|3cell1:^cell1+1|?cell_pos=2|3cell2:cell2+1|?cell_pos=3|3cell3:cell3+1|?cell_pos=4|3cell4:cell4+1|2error
1
added 3 instructions of bf in this interpreter >, <, +
This is crazy, I love it!
numberscript with any space/newlines given there right
🤦♂️ ofc
This interpreter is broken
there is a bug some where
0
3cell_pos:1
3cell1:0
3cell2:0
3cell3:0
3cell4:0
3input:+>+>+>+<++<-
6n\12\3index:^n-1;3letter:@input.index;?letter=>|3cell_pos=^cell_pos+1|?letter=<|3cell_pos:^cell_pos-1|?letter=+|?cell_pos=1|3cell1:^cell1+1|?cell_pos=2|3cell2:cell2+1|?cell_pos=3|3cell3:cell3+1|?cell_pos=4|3cell4:^cell4+1|2error
1
Can anyone fix this (mess)?
Error: Error: Variable Content not defined
oh waity
I placed = then :
sily old me
wait it still isn't working
0
3cell_pos:1
3cell1:0
3cell2:0
3cell3:0
3cell4:0
3input:+>+>+>+<++<-
6n\12\3index:^n-1;3letter:@input.index;?letter=>|3cell_pos:^cell_pos+1|?letter=<|3cell_pos:^cell_pos-1|?letter=+|?cell_pos=1|3cell1:^cell1+1|?cell_pos=2|3cell2:cell2+1|?cell_pos=3|3cell3:cell3+1|?cell_pos=4|3cell4:^cell4+1|2error
2cell1
2cell2
2cell3
2cell4
1
any idea?
ah ok, nice
Is there a way to preserve type annotations on an object? e.g, with a simple generic class: py print(Pointer) # -> <class 'memhax2.native_complex.Pointer'> print(Pointer[Char]) # -> memhax2.native_complex.Pointer[memhax2.native.Char] print(Pointer[Char](0).__class__) # -> <class 'memhax2.native_complex.Pointer'> # <- We don't want to lose type info here
hmm yeah idk what're you asking for
do you like mean having Pointer[Char](0).__class__ return Pointer[Char]?
yeah
I guess something similar to __orig_class__ which existed before 3.7 (which did have that information)
no wait it does stll exist
but not always?
__orig_class__ is available on any class after init has finished if it subclasses typing.Generic or a builtin generic (class with a __class_getitem__ = classmethod(types.GenericAlias))
oh so only after __init__ has finished?
and it has the slot for it if required (not in the case of classes like list/tuple)
that's gonna make things a little less fun but still doable
yeah cause guido thinks types should be erased at runtime
god, I'm rewriting it again inspired by chilaxan but now I've run into an issue where scoping is a pain
class PyTupleObject(PyVarObject, Struct[tuple]):
ob_item: PropertySizeArray[Pointer[PyObject], lambda self: self.ob_size()] # how am I gonna pass `self` [PyTupleObject] to this function
hmm, how would you approach this? because it's only used in PropertySizeArray
And in some cases it's even worse, here it's wrapped inside a Pointer: ```py
class PyListObject(PyVarObject, Struct[list]):
ob_item: Pointer[PropertySizeArray[Pointer[PyObject], lambda self: self.allocated()]]
allocated: Py_ssize_t
ob_item: PropertySizeArray[Pointer[PyObject]] = PropertySizeArray(callback=lambda self: self.ob_size())
and then on access to ob_item it just calls callback with the instance argument from __get__
but passing self to the array in a way that doesn't require a breaking change is gonna be tough
you dont have a stability policy or are at v1 why do you care?
I mean I'd like to not overcomplicate the code, which is the biggest problem
__get__ would work if it was only direct children
but the self always refers to the class level which isn't always the parent
also __get__ requires being a property on the class, which doesn't work here
My alignment code is wrong 
PyMemberDef(
name=INVALID_STRING
type=208
offset=1
flags=0
doc='__base__'
)
PyMemberDef(
name='__base__'
type=6
offset=256
flags=1
doc=NULL
)
```hmm
PyObject(
ob_refcnt=1000000009,
ob_type=<class 'str'>
),
```another bug(?) found while debugging, how in the world is it getting this for refcnt? do some values just have an inherent high refcount?
this is for "a" btw
cant you just check sys.getrefcount("a")?
hmm, I get a slight mismatch but that's likely just the code
yeah for some reason it's just massive in the IDE and not in the REPL lol
no wait
it's on 3.11 where it's crazy high
it might be immortal?
¯_(ツ)_/¯
3.11 immortal objects
at some point they decided to make the cached values have an obscenely high reference count
at the end of a program the immortal object must have a reference count of exactly 999999999
do you get a segfault otherwise?
i remember seeing the change in the git commit list just after it was pushed
i can probably find it
!e ```py
i = 0
while i < 10:
print(i)
i++ # this used to work in C
@plush halo :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 4
002 | i++ # this used to work in C
003 | ^^^^^^^^^^^^^^^^^^^^^^^^
004 | SyntaxError: invalid syntax
!e ```py
i = 0
while i < 10:
print(i)
++i # works in python but..
@plush halo :x: Your 3.11 eval job has completed with return code 143 (SIGTERM).
001 | 0
002 | 0
003 | 0
004 | 0
005 | 0
006 | 0
007 | 0
008 | 0
009 | 0
010 | 0
011 | 0
... (truncated - too many lines)
Full output: too long to upload
looks like it yeah
I wonder if I can wrap a memoryview in a file-like object 🤔
as it turns out i cant find the commit
turns out there's no proper way to do this
and my crappy impl seems to also just fail and segfault for no reason 
fatal error
Huh, I wonder what a missing decref on my end did to cause the segfault then
wdym by "used to"
it still works in C but not python... just lamenting xD
you mean "this only works in C" (works in C only) instead of "this used to work in C" (works in C some time ago, but now it doesn't)
started with that
I'm seeing things from python's point of view... maybe it didn't carry the clear message I thought it would
>>> def f():
... def g():
... return g
... return g
...
>>> f()
<function f.<locals>.g at 0x105971cf0>
>>> f()()
<function f.<locals>.g at 0x105971e10>
>>> f()()()
<function f.<locals>.g at 0x105971ea0>
this is a fun one
How can I do from urllib.parse import urlsplit in an import dunder
__import__("urllib.parse",1,1,'a').urlsplit
Nice
Was it intentional to be able to use keywords as variable names when using ast?
I thought I was gonna get an error or something but I guess not
!e ```py
import ast
module = ast.Module(
body=[
ast.Assign(
targets=[ast.Name(id="import", ctx=ast.Store())],
value=ast.Constant(value="Foo")
)
],
type_ignores=[],
)
code = compile(
ast.fix_missing_locations(module),
"<ast>",
"exec"
)
exec(code, d:={})
print(d["import"])
@old socket :white_check_mark: Your 3.11 eval job has completed with return code 0.
Foo
Whats the integers and a for?
so it works
you can also just do __import__("urllib.parse",fromlist='a').urlsplit
they're only checked in the parser
What does the fromlist do exactly?
if you try to use True/False/None(/__debug__?) it'll error
makes it work
Yea I was thinking that as well at first I was just confused and realised it only matter in the lexical part
Overrides the module dunder all
https://stackoverflow.com/questions/2724260/why-does-pythons-import-require-fromlist
TL DR unless you are importing a whole module (you just want urlsplit which is a function), fromlist can be anything
When importing a module from a package, note that __import__('A.B', ...) returns package A when fromlist is empty, but its submodule B when fromlist is not empty.
using fishhook, sometimes causes SIGSEGV to occur
not surprising 
@fickle scarab you can call type(or some other metaclass) manually:
class A(Base):x=4
# =
A=type('A', (Base,), {'x'=4})
thank you! after shuffling around my words in the search engine I actually came across this exact same solution a few minutes ago. thank you very much nonetheless
(i initially came here not being able to find any results online)
is there a way to reassign properties as an expression? seems walrus doesn't allow it for some reason
the setattr builtin
ah thanks
whats the reasoning for walrus not allowing it 
like sure setattr works but i dont see that being the reason for going out of the way to forbid it for walrus
The reason is to push you to use regular assignments, not bloat the scope of walrus to other tasks. It's easy to remove a restriction later, much more difficult to deprecate functionality if it is found to be confusing.
another possibility is that having the lhs of the assignment create an exception somehow makes the impl harder
it was already too controversial using just names
it's quite easy to change the grammar for that but there'll be some problems with the symtable when checking for comprehension walruses i think
Ye, grammar seems fine
My worry is None.attr := value, feels like that could be an annoying thing to compile correctly.
I mean it would be the same as attr := value except with an extra LOAD_* at the beginning and it would use STORE_ATTRIBUTE instead of STORE_FAST or STORE_GLOBAL
!e ```py
import dis
dis.dis('(a := 1)')
dis.dis('a.attr = 1')
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 0 0 RESUME 0
002 |
003 | 1 2 LOAD_CONST 0 (1)
004 | 4 COPY 1
005 | 6 STORE_NAME 0 (a)
006 | 8 RETURN_VALUE
007 | 0 0 RESUME 0
008 |
009 | 1 2 LOAD_CONST 0 (1)
010 | 4 LOAD_NAME 0 (a)
011 | 6 STORE_ATTR 1 (attr)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/digoganona.txt?noredirect
so the resulting bytecode would need to be this: ```py
001 | 0 0 RESUME 0
002 |
003 | 1 2 LOAD_CONST 0 (1)
004 | 4 COPY
005 | 6 LOAD_GLOBAL 0 (obj)
006 | 8 STORE_ATTR 1 (a)
007 | 10 RETURN_VALUE
>>> x = lambda v:(v or a.a)
>>> dis.dis(x)
1 0 LOAD_FAST 0 (v)
2 JUMP_IF_TRUE_OR_POP 4 (to 8)
4 LOAD_GLOBAL 0 (a)
6 LOAD_ATTR 0 (a)
>> 8 RETURN_VALUE
>>> co_code = bytearray(x.__code__.co_code)
>>> co_code[2] = dis.opmap['DUP_TOP']
>>> co_code[6] = dis.opmap['STORE_ATTR']
>>> x.__code__ = x.__code__.replace(co_code=bytes(co_code))
>>> class a:pass
...
>>> x(5)
5
>>> a.a
5
>>>
``` ^3.10 example
this would be a little annoying to check against iterator assignments in a comprehension
I think also the issue comes from the fact that the target object would be able to override behaviour, so if __getitem__ and __setitem__ didn't match up you'd get inconsistent results.
personally i think that if it was implemented to allow (obj.attr := value) it would be the same as obj.attr = value; return value so __getitem__ wouldnt matter
that seems the only logical way to set it up
if 'm reading this bytecode right, you just dup the rvalue before assignment and return it
which seems to be a not-so-difficult way of doing it in bytecode
(i come from java bytecode so maybe it's different in python)
that's how java does it
return someField = someOtherField;
compiles to
getstatic someOtherfield
dup
putstatic someField
ireturn
list.count(max(list))
i was so confused by the "word problem" aspect of it for some reason until i looked at the code and realized that it's just "find the mode of the list"
# alternative to ternary
((condition)and(_:=expressionIfTrue,)or(_:=expressionIfFalse,),_)[-1]
it's like a ternary but more characters to get the same result
oh and it also assigns the result to the local namespace so that's a thing
Is there a delete-as-expression?
I don't think so, other than del keyword you have the garbage collector module though, perhaps you can manually GC a variable, __del__ and __delete__ won't do anything either since those are called after the fact, iirc.
((condition)and(if_true,)or(if_false,))[0]
oh well
i tried
but anyway, i like that way of doing things over python's ternary because it's closer to C/C++, with the condition first and then the results
del a.b
(delattr(a, 'b'))
del a[b]
(a.__delitem__(b))
del a
(a := None) or (a := MISSING)
# what shoult expression return in this case?
i think you can use ctypes to break frame object and assign NULL to your variable
in this case you will get UnboundLocalError, just like after del a
if you want to delete global, you can globals().__delitem__('b')
>>> globals()
{ '__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>}
>>> globals().__delitem__('__name__')
>>> __name__
'builtins'
``` bruh
>>> globals().clear()
>>> import __main__
>>> __main__
<module '?'>
Would there be a way to do a++ in Python? (a is an int variable)
__import__("ctypes").c_void_p.from_address(id(a)+8)).value=id(a+1)```
(this doesn't actually work sadly)
even though it SHOULD
!e very brittle, breaks if number is too small or too large, but:
import ctypes
a = 1234
ctypes.c_int.from_address(id(a)+24).value += 1
print(a)
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
1235
and if you mean the syntax, then no, not without the usual syntax hacks (codecs or building your own CPython variant with different grammar)
hi mates!
I would have a question about Python, is it allowed to send screenshot here?
see #❓|how-to-get-help for general python questions
@maiden blaze ok thanks
As far as I understand you're just setting the value to an id? Don't you either have to remove the + 8 offset or just set a+1 without the id ()?
Heh, "Comprehension Walrus" sounds like it should be one of those philosophical animal memes
unfortunately that's not how objects work
fortunately i have done this before
unfortunately i can't find the code
this can just be used anyway
Yes
Totally
🙂
It has been a long time since I've come here
If sizeof void* is 8 this increases ob_refcnt, if sizeof void* is 4 this increases ob_size
Wait no that's incorrect
You get the gist of it at least
i actually don't really understand that snippet to be honest, but i messed around with it to get it to work
it's setting the type of a to a+1
so that should never work
well then, welcome back to the work of weirdness and strangeness good
I mean I don't understand how it works. And also, why can't we set a to a+1 if we can set True to an arbitrary class?
you're not setting a to a+1
you're setting the type of a to a+1
of course you can set a to a+1
__import__("ctypes").c_void_p.from_address(id(a)).value=id(a+1)
when you instead do this you set the reference count of a to id(a+1)
# biggest num it works for before overflow
# 0b111111_11111111_11111111_11111111 (1073741823)
# it probably overflows when decrementing on -(thatnumber+1), but I haven't tested that
# works for negative numbers
# breaks on: -1, 0, 1
n=some_integer
from ctypes import c_longlong as c_ll
c_ll.from_address(id(n)+24).value=c_ll.from_address(id(n+1)+24).value
!e ```py
from ctypes import c_uint
for n in range(-1, 2):
print(n, end=" -> ")
c_uint.from_address(id(n)+24).value=n+1&1073741823
print(n)
@quartz wave :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | -1 -> -0
002 | 0 -> 0
003 | 1 -> 2
@versed eagle seems to work as intended
you get nothing for 0 because it has a size of 0
this presents you with the value of -2 when you do it on -1
!e
import ctypes
n=1
for i in range(10):
ctypes.c_longlong.from_address(id(n)+24).value = ctypes.c_longlong.from_address(id(n+1)+24).value
print(n)
@versed eagle :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 2
002 | 4
003 | 8
004 | 16
005 | 32
006 | 64
007 | 128
008 | 256
009 | 512
010 | 1024
breaks on 1
you add 1 with itself
which is 2
then you add 1 (2) with itself
which is 4
and so on
why isn't that behavior replicated with 2 then
!e
import ctypes
n=2
for i in range(10):
ctypes.c_longlong.from_address(id(n)+24).value = ctypes.c_longlong.from_address(id(n+1)+24).value
print(n)
@versed eagle :x: Your 3.11 eval job has completed with return code 139 (SIGSEGV).
001 | 3
002 | 4
003 | 5
004 | 6
005 | 7
006 | 8
007 | 9
008 | 10
009 | 11
010 | 12
it just counts
because you don't add 2 with itself
ah
ok
ctypes.c_longlong.from_address(id(n+1)+24).value
^^
``` what do you think this is
1 is cached so it's effectively adding itself
it caches [-5, 256]
that's a range not a list
I only remember the positive numbers cause I don't use negative numbers lol
ik
is it possible to free the cache?
yes but that breaks everything
how so?
would it not just dynamically allocate the ints like it does for numbers bigger than 256
no, there are hardcoded code paths to grab from the cache
huh
it was wrong
oh
!e maybe will work ```py
def new_int(n):
sz = (n.bit_length() + 7) // 8
bts = n.to_bytes(sz, 'little', signed=n<0)
return int.from_bytes(bts, 'little', signed=n<0)
print(id(1), id(new_int(1)))
@rugged sparrow :white_check_mark: Your 3.10 eval job has completed with return code 0.
139897336873200 139897335828752
eh it works in 3.10
hi all, quite a specific question:
has anyone used the PyMultiNest package? I am trying to scan over a large combination of parameter values, although there is a particular parameter which I want to force to be integers only while scanning. does anyone know how to do this?
breaks if number is too small or too large
the cache is full of static structs as of 3.11
uh
check if type(param) == int, and if not, raise an error?
something like
if type(param) != int:
raise TypeError(f"param_name should be an int, but {param} is of type {type(param)}")
# then do stuff here
do_stuff()```
use is/is not
my logic for not using is/is not is that with my way, users can inherit from int, and then use a metaclass to overload eq and return true for int
I forgot about isinstance though :(
How would you go about destructuring a python dictionary?
for example, I have a person dictionary, with name and age
!e
person = {
"name" : "Bob",
"age" : 33
}
for values in person.values():
print(values)
I know this works
@keen swan :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | Bob
002 | 33
But in Javascript there's a way to destructure an object
with the spread operator
name, age = ...person
Sort of like that
What's the equivalent in Python?
You can do this
from operator import itemgetter
x = {'a': 1, 'b': 2}
a, b = itemgetter('a', 'b')(x)
hmm have to import itemgetter
Nothing built in?
oh wait
what about **kwargs?
doesn't seem right
So I know *args can spread a list
!e
numbers = [1,2,3,4,5]
print(*numbers)
@keen swan :white_check_mark: Your 3.11 eval job has completed with return code 0.
1 2 3 4 5
!e
x = {"a": 1, "b": 2}
keys = *x
print(keys)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 2
002 | SyntaxError: can't use starred expression here
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 1
002 | 2
!e
x = {"a": 1, "b": 2}
a, b = x
print(a)
print(b)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | a
002 | b
!e
a = {"a":1, "b":2, "c":3}
b, c, d = a.items()
print(b, c, d)
@royal whale :white_check_mark: Your 3.11 eval job has completed with return code 0.
('a', 1) ('b', 2) ('c', 3)
hmm
In Python this is called unpacking
How would I use it in a function?
The process of assigning names to values in a sequence
Gimme a min
What do you mean by that
You can use it anywhere, it's syntax
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro( name, age ):
print(f"Hi {name}. You are a {gender}")
intro(person.values())
Testing
@keen swan :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 9, in <module>
003 | TypeError: intro() missing 1 required positional argument: 'age'
hmm
oh wait
sorry I had it as age instead of gender
in func
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro( name, gender ):
print(f"Hi {name}. You are a {gender}")
intro(*person)
Would this work?
@keen swan :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hi name. You are a gender
oh I think I'm getting close
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro( name, gender ):
print(f"Hi {name}. You are a {gender}")
intro(*person.values())
@keen swan :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hi Bob. You are a Male
Which would still require using .values()
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro(*args):
name, gender = args
print(f"Hi {name}. You are a {gender}")
intro(*person.values())
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hi Bob. You are a Male
Or
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro(person_values):
name, gender = person_values
print(f"Hi {name}. You are a {gender}")
intro(person.values())
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hi Bob. You are a Male
huh, this function is a bit more readable that *args
Or is args just another word?
!e
person = {
"name": "Bob",
"gender": "Male"
}
def intro(*person_values):
name, gender = person_values
print(f"Hi {name}. You are a {gender}")
intro(*person.values())
@keen swan :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hi Bob. You are a Male
It's a name
!e
def add_all(*numbers):
return sum(numbers)
print(add_all())
print(add_all(1, 2, 3, 4))
print(add_all(1))
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 0
002 | 10
003 | 1
!e
def f(*args, **kwargs):
print(args, kwargs)
f(1, 2, argument=3)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
(1, 2) {'argument': 3}
!e
def f(a, *b, c):
print(a, b, c)
f(1, 2, 3)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | TypeError: f() missing 1 required keyword-only argument: 'c'
I guess it makes the rest of the arguments keyword-only
hmm
!e
def f(a, *b, c):
print(a, b, c)
f(1, 2, c=3)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
1 (2,) 3
I think this helped
!e
def f(a, *b, c):
print(a, b, c)
f(1, 2, 3, 4, c=5)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
1 (2, 3, 4) 5
Ok
oh
that example makes this unpredictable
It returned a tuple
Sorry I mean unexpected
Unrelatedly, because we are on the topic of function signatures I want to note that specifically in function signatures, / separates positional-only arguments (those are on the left side of it) and * separates keyword-only arguments (those are on the right side of it)
This time it's called packing
oh ok
In function signatures, a parameter prefixed with * is just like when you do
a, *b = "hello" # a = "h"; b = "ello"
!e
def f(a=1, /, b):
print(a, b)
f(b=7)
f(10, b=5)
f(a=4, b=6)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 1
002 | def f(a=1, /, b):
003 | ^
004 | SyntaxError: non-default argument follows default argument
!e
def f(a=1, /, b, *):
print(a, b)
f(b=7)
f(10, b=5)
f(a=4, b=6)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 1
002 | def f(a=1, /, b, *):
003 | ^
004 | SyntaxError: non-default argument follows default argument
Huh
first time seeing a / in a function arg
I explained it here
!e
def f(a, /):
print(a)
f(10)
f(a=10)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | 10
002 | Traceback (most recent call last):
003 | File "<string>", line 5, in <module>
004 | TypeError: f() got some positional-only arguments passed as keyword arguments: 'a'
!e
def f(*, a):
print(a)
f(a=10)
f(10)
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | 10
002 | Traceback (most recent call last):
003 | File "<string>", line 5, in <module>
004 | TypeError: f() takes 0 positional arguments but 1 was given
!e
def f(*, a):
print(a)
f()
@cloud fossil :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | TypeError: f() missing 1 required keyword-only argument: 'a'
Arguments after * are passed as keyword-only
Arguments before / are passed as positional-only
!pos
Positional vs. Keyword arguments
Functions can take two different kinds of arguments. A positional argument is just the object itself. A keyword argument is a name assigned to an object.
Example
>>> print('Hello', 'world!', sep=', ')
Hello, world!
The first two strings 'Hello' and world!' are positional arguments.
The sep=', ' is a keyword argument.
Note
A keyword argument can be passed positionally in some cases.
def sum(a, b=1):
return a + b
sum(1, b=5)
sum(1, 5) # same as above
Somtimes this is forced, in the case of the pow() function.
The reverse is also true:
>>> def foo(a, b):
... print(a, b)
...
>>> foo(a=1, b=2)
1 2
>>> foo(b=1, a=2)
2 1
More info
• Keyword only arguments
• Positional only arguments
• !tags param-arg (Parameters vs. Arguments)
With assignment it's different
Remember how I couldn't do def f(a, *b, c):?
!e
a, *b, c = "hello"
print(a, b, c)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
h ['e', 'l', 'l'] o
yup
* and ** are called star expressions I think
@keen swan :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 2
002 | SyntaxError: can't use starred expression here
!e
print({**{"a": 1}})
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
{'a': 1}
wouldn't that just be exactly calling the dictionary?
Without **
Once upon a time you would merge dictionaries with this
Now the pipe operator exists
!e
a = {"a": 1}
b = {"b": 2}
print({**a, **b})
print(a | b)
@cloud fossil :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | {'a': 1, 'b': 2}
002 | {'a': 1, 'b': 2}
Even |= is defined
huh
aren't sets immutable?
hmm
probably for another time
I just need to get around to packing and unpacking dictionaries
Also, | replaces typing.Union on newer versions of python
By "replaces" I mean exists there to use (instead of having to import and maybe for readability too)
I see
!e
person = {
"name" : "Bob",
"age" : 33
}
name, age = person.values()
print(name, age)
@fleet bridge :white_check_mark: Your 3.11 eval job has completed with return code 0.
Bob 33
Thanks denball. I've found that I can use that or *args in a function that I needed
Only problem:
!e
person = {
"name" : "Bob",
"age" : 33,
"test": 2
}
name, age = person.values()
print(name, age)
@rugged owl :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | ValueError: too many values to unpack (expected 2)
it is not a problem
Well yeah, but 🤷♂️
!e
person = {
"name": "Bob",
"age": 33,
"test": 2,
}
name, age, *_ = person.values()
print(name, age)
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
Bob 33
print('\n'.join([''.join([('Engineer'[(x-y)%8 ]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)]))
can anyone explain me the logic behind this code
like what is exactly happenening
Seems like its going through a 2d grid of x and y coordinates as it prints, checking whether the current position being checked lies inside of that equation for a heart shape, and if so, prints out a character from the string "Engineer"
ok hows it chcking tht
here's it re-written in a way using regular for loops: ```py
for y in range(15, -15, -1):
for x in range(-30, 30):
if (((x * 0.05) ** 2 + (y * 0.1) ** 2 - 1) ** 3 - (x * 0.05) ** 2 * (y * 0.1) ** 3) <= 0:
print("Engineer"[(x - y) % 8], end="")
else:
print(" ", end="")
print()
ohk
thank you very much it will be easier to understand now
Smells suspicious
My guess would be it obfuscates a slur
haha it does not
bjokey was right
the equation simplifies to https://www.desmos.com/calculator/pymohatezu and thats also what it prints
def equation_viewer(yes, equation, width, height, no=" "):
for y in range(height, -height, -1):
for x in range(-width, width + 1):
choice = yes if equation(x, y) else no
print(choice[(x - y) % len(choice)], end="")
print()
def heart(x, y):
return ((0.0025*x**2+0.01*y**2-1)**3-0.0000025*x**2*y**3) <= 0
equation_viewer("█#", heart, width=23, height=12, no="_")
Wow, I don't need a graphing calculator anymore
Which is faster,
(...)**2
or
(lambda k:k*k)(...)
for any given expression ...?
(a:=...)*a?
Variable creation is faster than anonymous function?
anonymous function still requires function making and calling
Huh nice
Which is faster for complex math, using built-in types or making a mimic with custom class and integers
Or functions of pairs of numbers?
oops
print('\n'.join(''.join(' 'if(.25*x*x+.01*y*y-1)**3-2.5*1e-6*x*x*y**3>0else'Engineer'[x-y&7]for x in range(-30,30)])for y in range(15,-15,-1)))
I was almost expecting 1e-6*x*x*y*y*y
👀
print('\n'.join(''.join('+'[(x-y)%1]if(abs(x) ** abs(y) < 10)else' 'for x in range(-30, 30))for y in range(15, -15, -1)))
def eso_graph_generator(yes, equation_as_str, width, height, no):
return f"print('\\n'.join(''.join('{yes}'[(x-y)%{len(yes)}]if({equation_as_str})else'{no}'for x in range(-{width}, {width}))for y in range({height}, -{height}, -1)))
raise IndexError("string index out of range")
``` golfed to the minimum
!e
print('\n'.join(''.join('+'[(x-y)%1]if(abs(x) ** abs(y) < 10)else' 'for x in range(-30, 30))for y in range(15, -15, -1)))
@ruby orbit :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | +++
002 | +++
003 | +++
004 | +++
005 | +++
006 | +++
007 | +++
008 | +++
009 | +++
010 | +++
011 | +++
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ubecamusep.txt?noredirect
nvm then
!e
print('\n'.join(''.join('+-'[(x-y)%2]if(abs(x) ** abs(y) < 10)else' 'for x in range(-30, 30))for y in range(5, -5, -1)))
@ruby orbit :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | +-+
002 | -+-
003 | -+-+-
004 | -+-+-+-
005 | +-+-+-+-+-+-+-+-+-+
006 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
007 | +-+-+-+-+-+-+-+-+-+
008 | -+-+-+-
009 | -+-+-
010 | -+-
hahaha thats hilarious
Nice
Did you make that?
yea sorry for the nick lmao
lambda call - 70 ns
assignment - 7 ns
float ** 2 - 50 ns
float * float - 25 ns```
`(lambda k:k*k)(...)`
creates lambda (100 ns) + call it (70 ns) + multiply vars (25 ns) + several assignments and lookups = 200+ ns
`f = lambda k:k*k; f(...)` (create lambda once and call it several times)
lookup (7 ns) + call (70 ns) = 77 ns
`(...)**2`
square float (50 ns) = 50 ns
`(a:=...)*a`
assignment (7 ns) + lookup (7 ns) + multiplication (25 ns) = 40 ns
all calculations are approximate
i have huge benchmark of different operations, i can show it if you want
!e ```py
from ctypes import pythonapi as p, py_object
p.PyUnicode_FromObject.argtypes = [py_object]
p.PyUnicode_FromObject.restype = py_object
p.PyUnicode_FromObject(py_object(5))
@quartz wave :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | TypeError: Can't convert 'int' object to str implicitly
Is it possible to catch an exception, and then get access to the frame where it occurred, and continue there (possibly with some bytecode offset)?
Just had a stupid idea, but fiddling with pdb on my phone turns out to be difficult
should be possible
seems fairly straightforward via sys.settrace
just wait for an exception event and create a jump to... IG the next line
No, I want to be able to catch an exception somewhere up higher in the callstack, and then optionally jump back to where / after where the exception happened
I guess I could keep a reference to the frame where the exception got raised with a trace function, and then somehow use that from outside
Ideal syntax:
def do_thing():
wat = raise ValueError(42)
print("wat:", wat)
do_thing() # raises ValueError
# prints "wat: lol"
try:
do_thing()
except ValueError:
continue with "lol"
But I'll settle for something without special syntax for now :)
algebraic effects 
You just invented javascript
Whatever happens, you will get no errors and execution will continue
You mean PHP?
I think it is doable with generators
(Idk how to use .send)
def do_thing():
wat = yield 42
print("wat:", wat)
do_thing().send('lol')
Right, but that means every function in-between has to "cooperate"
The idea of algebraic effects is that the functions in-between the handler and the "causer", so to speak, don't have to be aware of the effect.
You can implement your custom global context manager
class CManager:
def __init__(self, handler: Callable): ...
def get_value(): ... # some code here using Cmanager
# usage:
def do_thing():
wat = get_value(42)
print(wat)
def foo(f):
return f()
with CManager(handler=lambda x: 'lol'):
foo(do_thing)
you can track all active context managers and use innermost in get_value
I guess that would work, yes... I could add a bit more sugar and it would almost work
!e```py
from future import annotations
from types import TracebackType
from typing import Any, Callable, ClassVar
class CM:
_s: ClassVar[list[CM]] = []
def __init__(self, handler: Callable[[Any], Any]):
self.handler = handler
def __enter__(self) -> CM:
self.__class__._s.append(self)
return self
def __exit__(
self,
exc_type: type[Exception],
exc_value: type[Exception] | Exception,
traceback: TracebackType,
) -> bool:
assert self.__class__._s.pop() is self
return True
def handle(self, x: Any) -> Any:
return self.handler(x)
def handle(value: Any) -> Any:
return CM._s[-1].handle(value)
def do_thing() -> None:
print(f'{handle(42) = }') # 42 42\nhandle(42) = 'wat'
with CM(handler=lambda x: (print(x), 'lol')[-1]):
print(f'{handle(43) = }') # 43\nhandle(43) = 'lol'
print(f'{handle(44) = }') # 44 44\nhandle(44) = 'wat'
def foo(f: Any) -> Any:
return f()
with CM(handler=lambda x: (print(x, x), 'wat')[-1]):
foo(do_thing)
@fleet bridge :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | 42 42
002 | handle(42) = 'wat'
003 | 43
004 | handle(43) = 'lol'
005 | 44 44
006 | handle(44) = 'wat'
hey js isn't that bad
isn't that a vb feature
Imo, js is very bad
@mellow salmon :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello, world!
i dont understand anything
@mellow salmon :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello, world
@mellow salmon :white_check_mark: Your 3.11 eval job has completed with return code 0.
1st
@mellow salmon :white_check_mark: Your 3.11 eval job has completed with return code 0.
2
whats that
So i was trying to figure out the shortest code to find the sum of all even numbers from 0 to N, and we are wondering if there is a code shorter than 32 symbols:
n=int(input())//2
print(n*(n+1))
Is there a better code alternative?
Thanks in advnace
Wait, what does the tilda do?
sum(range( is unoptimal then?
How do you come up with this weird logic
how do i do for i in range(x): variable = variable(string)
also how do i use python to interact with a website from my computer
also how do i make a kahoot bot spammer
None of this goes in #esoteric-python except maybe the first one.
!rule 5
5. Do not provide or request help on projects that may break laws, breach terms of services, or are malicious or inappropriate.
!e My solution looks similar, but I think my solution should work with threads/async/etc.:
import sys
class Effect:
def __enter__(self):
self.local_handlers = sys._getframe().f_back.f_locals.setdefault("_effect_handlers", [])
self.local_handlers.append(self)
def __exit__(self, *args):
self.local_handlers.pop()
def __call__(self, key, *args, **kwargs):
if hasattr(self, f"handle_{key}"):
return getattr(self, f"handle_{key}")(*args, **kwargs)
elif hasattr(self, "handle"):
return getattr(self, "handle")(*args, **kwargs)
return NotImplemented
class Printer(Effect):
def __init__(self, prefix):
self.prefix = prefix
def handle_print(self, val):
print(self.prefix, val)
def perform(value, *args, **kwargs):
frame = sys._getframe()
handled = False
while frame := frame.f_back:
if "_effect_handlers" in frame.f_locals:
for handler in reversed(frame.f_locals["_effect_handlers"]):
if (retval := handler(value, *args, **kwargs)) is not NotImplemented:
return retval
raise RuntimeError("unhandled effect")
def something():
perform("print", "hello")
with Printer("outer"):
something()
with Printer("inner"):
something()
something()
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | outer hello
002 | inner hello
003 | outer hello
It is a lot better
how do i do for i in range(x): variable = variable(string). i tried fill = builtins.dict['color' + str(x)] but i bet you can guess how that went lol
i have defined variables like var1 var2 etc. i want to cycle through them by going stuff = var[1, 2, etc]. how do i do this.
!e You shouldn't? You should use a dictionary. But since this is #esoteric-python ```py
for i in range(3):
globals()[f'var{i}'] = i
print(var0, var1, var2)
@rugged sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.
0 1 2
seriously, don't do that. Use a dict.
or a list.
i know how to do that. thats why i want to know how to do it the other way.
then i guess use chilaxan's code
!e ```py
var0,var1,var2,var3,var4 = range(5,10)
print(*[globals()[f'var{i}']for i in range(5)])
@floral meteor :white_check_mark: Your 3.11 eval job has completed with return code 0.
5 6 7 8 9
after creating dictionary, you can do something like this
d = {'a': 1, 'b': 2}
locals().update(d)
print(a)
print(b)
oops i didn't see this... you still want me to review?
nice, dict.update is my favorite way of updating locals
didn't it already get merged?
how about view pull #16
!e
(lambda: [
['def'
for sys in [__import__('sys')]
for math in [__import__('math')]
for sub in [lambda *vals: None]
for fun in [lambda *vals: vals[-1]]
for echo in [lambda *vals: sub(
sys.stdout.write(u" ".join(map(unicode, vals)) + u"\n"))]
for Cylinder in [type('Cylinder', (object,), dict(
__init__ = lambda self, radius, height: sub(
setattr(self, 'radius', radius),
setattr(self, 'height', height)),
volume = property(lambda self: fun(
['def' for top_area in [math.pi * self.radius ** 2]],
self.height * top_area))))]
for main in [lambda: sub(
['loop' for factor in [1, 2, 3] if sub(
['def'
for my_radius, my_height in [[10 * factor, 20 * factor]]
for my_cylinder in [Cylinder(my_radius, my_height)]],
echo(u"A cylinder with a radius of %.1fcm and a height "
u"of %.1fcm has a volume of %.1fcm³."
% (my_radius, my_height, my_cylinder.volume)))])]],
main()])()
!e ```py
import sys, ctypes
def swap(a,b):
f=sys._getframe(1)
c=f.f_code
g=lambda n:(c.co_names,c.co_varnames)[c.co_code[f.f_lasti-n-1]==124][c.co_code[f.f_lasti-n]]
save=lambda:ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(f),ctypes.c_int(0))
t=(f.f_locals,f.f_globals)[c.co_code[f.f_lasti-4]==116][g(3)]
(f.f_locals,f.f_globals)[c.co_code[f.f_lasti-4]==116][g(3)]=(f.f_locals,f.f_globals)[c.co_code[f.f_lasti-2]==116][g(1)]
save()
(f.f_locals,f.f_globals)[c.co_code[f.f_lasti-2]==116][g(1)]=t
save()
x,y=10,5
swap(x,y)
print(x,y)```
@frigid wharf :white_check_mark: Your 3.10 eval job has completed with return code 0.
5 10
Hello what y'all talking about
!e
#Syntax isn't as cool, but this actually runs:
(lambda: [
['def'
for sys in [__import__('sys')]
for math in [__import__('math')]
for sub in [lambda *vals: None]
for fun in [lambda *vals: vals[-1]]
for echo in [lambda *vals: sub(
sys.stdout.write(" ".join(map(str, vals)) + "\n"))]
for Cylinder in [type('Cylinder', (object,), dict(
__init__ = lambda self, radius, height: sub(
setattr(self, 'radius', radius),
setattr(self, 'height', height)),
volume = property(lambda self: fun(
[self.height * top_area for top_area in [math.pi * self.radius ** 2]
][0],
))))]
for main in [lambda: sub(
['loop' for factor in [1, 2, 3] if sub(
['def'
for my_radius, my_height in [[10 * factor, 20 * factor]]
for my_cylinder in [Cylinder(my_radius, my_height)]
if echo(u"A cylinder with a radius of %.1fcm and a height "
u"of %.1fcm has a volume of %.1fcm³."
% (my_radius, my_height, my_cylinder.volume)
)
]
,
)])]
if main()],
])()
@vague cairn :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | A cylinder with a radius of 10.0cm and a height of 20.0cm has a volume of 6283.2cm³.
002 | A cylinder with a radius of 20.0cm and a height of 40.0cm has a volume of 50265.5cm³.
003 | A cylinder with a radius of 30.0cm and a height of 60.0cm has a volume of 169646.0cm³.
how do you get away with for sys in [__import__('sys')] without : at the end
it's a list comprehension.
When I saw advik's code I def did a doubletake before I figured out what was going on, then I had to move the execution bits to inside the def lists.
(Because list comprehension vars are local to the comprehension)
Everytime I come into this channel I learn something funky syntax
!e
started messing around and came up with this shi
(lambda: [
['def'
for math in [__import__('math')]
for sys in [__import__('sys')]
for numpy in [__import__('numpy')]
for sub in [lambda *vals, **kwds: None]
for fun in [lambda *vals: vals[-1]]
for echo in [lambda *vals: sub(fun(
sys.stdout.write(" ".join(map(str, vals)) + "\n")
))]
for Rectangle in [type('Rectangle', (object, ), dict(
__init__ = lambda self, length, width, height: sub(
setattr(self, 'length', length),
setattr(self, 'width', width),
setattr(self, 'height', height)),
area = property(lambda self: fun(
[self.length * self.width * self.height * n for n in [abs(numpy.arcsin(-1)) // numpy.arcsin(1)]][0]
))))]
for main in [lambda: sub(fun(
['loop' for factor in [1, 2, 3] if sub(
['def'
for my_height, my_length, my_width in [[10 * factor, 20 * factor, 30 * factor]]
for my_rect in [Rectangle(my_length, my_width, my_height)]
if echo(u"A rectangle with the area of %.1fcm^2 and a height "
u"of %.1fcm and a width "
u"of %.1fcm and a length "
u"of %.1fcm" % (my_rect.area, my_height, my_width, my_length))
]
,
)]))]
if main()],
])()
@rugged owl :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | A rectangle with the area of 6000.0cm^2 and a height of 10.0cm and a width of 30.0cm and a length of 20.0cm
002 | A rectangle with the area of 48000.0cm^2 and a height of 20.0cm and a width of 60.0cm and a length of 40.0cm
003 | A rectangle with the area of 162000.0cm^2 and a height of 30.0cm and a width of 90.0cm and a length of 60.0cm
Weird how any indentation error, makes the variable not found. Like you have to indent atleast 1 tab to use all the imported libs
!e
print((lambda n: str(n) + 'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4])(22))
@frozen silo :white_check_mark: Your 3.11 eval job has completed with return code 0.
22nd
!e
print((lambda n: str(n) + 'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4])(0))
@frozen silo :white_check_mark: Your 3.11 eval job has completed with return code 0.
0th
!e
print((lambda n: str(n) + 'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4])(-1))
@restive void :white_check_mark: Your 3.11 eval job has completed with return code 0.
-1th