#esoteric-python
1 messages · Page 49 of 1
rot13 is what rot13 usually means (all characters map to themselves except alphabetic ones; for examplecodecs.encode(x,'rot13') works great)
- make a markov algorithms interpeter in python
- implement brainfuck interpreter in markov algorithms
- run a brainfuck interpreter written in brainfuck on it
- pass a brainfuck hello-world to it as input
- wait for it to finish
*i am here* - ???
- profit
🥴
6 hours was not enough... it is still running
I bet it was only reading an input for an hour
why not toss a c compiler in there somewhere
imagine printing Hallo World
cpython is implemented in c, does that count?
9.5h, it is still running
I have a slight suspicion that it won't finish...
upd: 14h...
||ᵖʳᵢⁿᵗ(*ᵐᵃᵖ(ᶜʰʳ,[72,101,108,108,111,44,32,119,111,114,108,100,33]),ſᵉᵖ="")||
||so that rot13 is a noop?||
New challenge: ascii only version 😉
I really have no idea how to print this out ||['Hello, world!', 'Uryyb, jbeyq!']['a'>'z']||
I think I just broke my coworkers' mind 😛
import glob
import importlib
import json
import os.path
import sys
from typing import List, Dict
from django.core.exceptions import ImproperlyConfigured
conffiles = glob.glob("[0-9]*.py", root_dir=os.path.dirname(__file__))
conffiles.sort()
# Perform some magic using dynamic imports based on files found with globbing
# Lists and Dicts get merged, the rest is overwritten
for conf in conffiles:
conf = conf.split(".")[0]
i = importlib.import_module("." + conf, package=__package__)
for k, v in vars(i).items():
if not k.startswith("__"):
if k not in globals():
setattr(sys.modules[__name__], k, v)
else:
if type(v) is not type(getattr(sys.modules[__name__], k)):
raise ImproperlyConfigured(
"Value type for {} in config files do not match, cannot merge".format(
k
)
)
match type(v):
case List:
# Append list
ol = getattr(sys.modules[__name__], k)
setattr(sys.modules[__name__], k, ol + v)
case Dict:
# Merge dict using x | y syntax
od = getattr(sys.modules[__name__], k)
setattr(sys.modules[__name__], k, od | v)
case _:
# Overwrite
setattr(sys.modules[__name__], k, v)
Settings for Django can get separated into different config files like (10-base.py, 20-auth.py, etc) and get loaded sequentially. Still have to write a bit of the merge/overwrite logic, but she works! Just need to figure out how to get code completion and linting working without complaints
Update: In theory this works brilliantly. In practice (even with .pyi stub files) pylint does NOT like it when configuration is loaded like this 😛
!e ```py
print('HUerlylyob,, wjobrelydq!!'['a'>'z'::2])
print('HUerlylyob,, wjobrelydq!!'['a'<'z'::2])
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | Hello, world!
002 | Uryyb, jbeyq!
Problem there is that print is also rot13ed
yeah
although the ::2 trick is more concise, I thought of that last night in the shower as well 🤭
what y'all think of this?
https://paste.pythondiscord.com/H7XQ
I think it may work, but I gtg before testing
it's supposed to be used either
@inmutable
class A:
...
class A:
x = inmutable(int)
...
class A:
x = inmutable()
Unless get_caller_name is a builtin method it is not in that paste
import inspect as _insp
def get_caller_name(level = 1):
return _insp.stack()[level].function
but at all calls of get_caller_name the argument has to be set to 2, I noticed now
40h, still running...
now I'm just curious how long I can keep it running without accidentally stopping it
What if you accidentally made an infinite loop that you haven't realized
I don't think that is the case
I tested my Markov algo interpreter on several algos
and also tested bf interpreter done in Markov algos on several algos (several helloworlds + other cool stuff from esowiki)
brainfuck interpreter in brainfuck I stole from brainfuck.org, im pretty sure it is correct, and I tested it by itself on some helloworlds in online bf interpreters
so each part alone works fine
and when combined it all also should work fine
it is just slow af
the issue is that a simple brainfuck helloworld needs several seconds to finish on my markov algo interpreter
and if we add an extra layer of brainfuck interpretation it gets even slower
I admit that my Markov algorithms implementation is far from efficient: I implemented it naively by walking a list of rules and applying them on regular python string
that also means that the bigger(longer) the state gets, the slower it all becomes
my brainfuck interpreter in Markov algorithms is also not the most compact in terms of both rule count and string size
string = '...' # current state, might be long (100+ or 1000+ chars), changes at each step
rules: list[tuple[str, str]] = [...] # a couple hundred rules (both left and right side are pretty short - usually less than 10 chars), doesn't change
while True:
for before, after in rules:
if before in string: # profiling says that 99% of time is spent on this line
string = string.replace(before, after, 1)
break # end the rule search, start again
else:
break # no rule matched - halt
print(string)
if someone is interested in this kind of stuff - we can talk about it somewhere else [I feel like this is a bit off topic here]
Markov algorithms and brainfuck are both Turing complete, so it is impossible to universally determine if the program will stop or not
but the entire state of Markov algorithms is determined by a single string, so if at some moment we go to the same string, it means that we reached a loop
storing all states would be memory inefficient, but we can store hashes of all strings
also, we can store state hashes in bloom filter, and [since it might randomly report that a string is inside it] if 1000 consecutive states are in the filter - we can conclude with big probability that we reached a loop
I am very interested in this stuff, though I use regexes instead of pure markov algorithms. I have done a bf interpreter before, though I plan to re make it as a "pure" one regex line/replacement line regex.
hmm, i've been thinking about this for a while and cant figure it out, let alone a simple solution
getting the string was fine (as everyone above as found)
getting it to print is something else...
i made a repo: https://github.com/denballakh/markov
BF interpreter in markov algor can be found here: https://github.com/denballakh/markov/blob/master/bf.mv
@dataclasses.dataclass(slots=True)
class Rule:
before: str
after: str
terminating: bool = False
def __str__(self) -> str:
return f'{self.before} ->{"." if self.terminating else ""} {self.after}'
@classmethod
def from_line(cls, line: str) -> Rule:
if '->.' in line:
before, _, after = line.partition('->.')
return Rule(before.strip(), after.strip(), terminating=True)
elif '->' in line:
before, _, after = line.partition('->')
return Rule(before.strip(), after.strip())
else:
raise Exception(f'invalid rule: {line!r}')
¿no weakref 🥹 ?
feels weird to read good code from here
weakrefs make no sense for simple object like this
Rule cannot form a reference loop, because it references only str and bool - and they do not reference anything
||and i dislike the whole weakref idea||
under every esoteric programmer is a programmer
finalize > __del__ and we all know that
!code
import random
print(f"This is your randomly chosen choice: {random.choice([input(f"Choice {i + 1}: ") for i in range(int(input("Number of Choices: ")))])}")
Interesting, I did my interpreter using base 1, I didn't realize you could do base 2 addition/subtraction so elegantly.
I wonder at what size a linked list might be better than a normal string. From what I recall it would need the benefit of O(1) insertions to beat the cost of cache misses/extra loads when doing a straight traversal.
One thing I've noticed markov algorithms have a ton of are "marker elements". Something like [mp], or a 1 char equivalent, that just keeps track of the location of a thing in the string. I could see an optimization where the location of those singular marker elements are stored ahead of time, so things like [do_plus] didn't have to scan and could jump directly to creating [math/inc]. This is sort of possible in regex using single char pointers when going to the right, something like (>)(\+)([^►]+►) with \2\1\3[inc], but it still has to do a single char match scan. Being able to directly jump should also help linked lists more than a normal string, but again not sure if it would ever be better.
I also have to wonder if there are more efficient techniques being missed, since a large part of why I like making it a regex is that you can directly run it in any text editor that has regex based find/replace. Things like changing to a linked list or marker elemnent jump aheads wouldn't be able to help those.
the simplest possible markov algo implementation in python is also not too long, it is pretty much there
(excluding terminating rules, they would add a couple more lines)
also see this thread: #algos-and-data-structs message
hm, this seems like a usecase for ropes and tries.
my solution:
||```py
'a'<'z'==print("Hello, World!")
'n'<'m'==cevag("Uryyb, Jbeyq!")
ah, ||short circuiting||, very nice
what is that
The context is this: #esoteric-python message
I get it now, it's just an encoded python
!e ```py
v = '''(lambda x:x%('"''""'+x+'"''""')) ("""(lambda x:x%%('"''""'+x+'"''""')) (%s)""")'''
print(v)
print(eval(v))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | (lambda x:x%('"''""'+x+'"''""')) ("""(lambda x:x%%('"''""'+x+'"''""')) (%s)""")
002 | (lambda x:x%('"''""'+x+'"''""')) ("""(lambda x:x%%('"''""'+x+'"''""')) (%s)""")
!e ```py
v="(:='(:=%r)%%')%"
print(v)
print(eval(v))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | (_:='(_:=%r)%%_')%_
002 | (_:='(_:=%r)%%_')%_
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 0
002 | 0
well that one kinda goes against the quine philosophy (not to mention that eval('0') results in an int, not a string)
it's not a quine if it's just eval()
sorry, I should have clarified. The original code is ```py
v = (lambda x:x%('"''""'+x+'"''""')) ("""(lambda x:x%%('"''""'+x+'"''""')) (%s)""")
wdym 'philosophy' it's not like you created a life form or smth
yo guys, there goes reproduction, only nutrition and interaction missing, ¿do we create one 'life form' of sorts? /j
the quine philosophy™️
it ought to be taken very seriously
Only the most serious of business here in #esoteric-python
Also no fun, but you can turn almost any single file python program into a quine using one line of code: ```py
print(open(file).read())
nice try
I’m a big cheater >:)
yeah that one is boring
the degenerate quine is at least interesting for being silly
!e ```py
exit(open(file).read())
:x: Your 3.12 eval job has completed with return code 1.
exit(open(__file__).read())
!e
#include <iostream>
# /*
"""
namespace placeholder {
int temp = 0;
}
"""
# */
#define def int
#define main() main() { placeholder
#define print(x) std::cout << x << std::endl; return true; }
#define exec(x) void _();
def main():
print("Hello, World!")
exec("main()")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Hello, World!
#include <iostream>
# /*
"""
namespace placeholder {}
"""
# */
#define def int
#define main() main() { placeholder
#define print(x) std::cout << x << std::endl;
#define exec(x) void a();
#define in
#define _
#define range(x) i++;} while(i < x);
#define for
#define return int i = 0; do
def main():
return {print("Hello World!") for _ in range(5)}
exec("main()")
!e ```py
#include <print>
#define def ;int
#define foo() main(){a/*
too lazy to do the complicated preprocessor mechanics here */
#define print(f, ...) std::print(f " {}\n", VA_ARGS)
#define else )?:
#define return ;(void)
#define if +(/*
""""*/
int//"""
C = 0
def foo():
print("We're in", " C++" if ++C else "Python")
return "yup!"
#undef print
#define print(x) ;std::print(x "\n");
#undef foo
#define foo() "yup!"
print(foo())
#if 5/*
"""*/
}
#endif//"""
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | We're in Python
002 | yup!
wait what quirk lets you do ++C???
wait is that basically saying positive positive C?
thats weird asf I love it
yes but it does ++ normally in C++
that code is disgusting 10/10
the philosophers do not approve
i mean, that's why it's in this channel
yo guys, pretty esoteric thing I'm doing for no reason other than boredom;
I want a lambda to be an expresion, but not any expresion, no, one that you can send to, so far I've come up with this
class chain:
def __init__(self, *iterables):
self.iterables = iterables
self.curr_iterable = 0
def __iter__(self):
return self
def __next__(self):
try:
return next(self.iterables[self.curr_iterable])
except StopIteration:
if self.curr_iterable + 1 == len(self.iterables): raise
self.curr_iterable += 1
return self.__next__()
sendable_iterator = lambda f: chain(*map(lambda object: (((x := (yield object)) or f(x)), <genexpr>)
but I want to turn this chain class into a lambda so that the whole expression can be contained on a single lambda
problem is __next__, the try/except is needed, and after doing all this, I didnt figure out a way of avoiding this try/except
Here's expression-based try-except: #esoteric-python message
sendable_generator = (
lambda chain_type: lambda f, genexpr: chain_type(*map(lambda object:((x := (yield object)) or f(x)), genexpr))
)(
type('sendable_chain', (object, ), {
'__init__': lambda self, *iterables: setattr(self, 'iterables', iterables) and setattr(self, 'current_iter', 0),
'__iter__': lambda self: self,
'__next__': lambda self: (
lambda t, *a, f=lambda a:a, e=Exception, **k,:(r:={}).pop(
'r',
type(
'',
(__import__('contextlib').ContextDecorator,),
{
'__enter__':int,
'__exit__':lambda s,*a:isinstance(
a[1], e
) and [r.update(
r=f(a)
)]
}
)()(t)(*a, **k)
)
)(lambda : next(self.iterables[0]), StopIteration, f = lambda a: setattr(self, 'current_iter', self.current_iter + 1) and (
(_ for _ in _).throw(StopIteration) if self.current_iter == len(self.iterables) else next(self)
))
})
)
in this channel, chilaxan is one of the best among us, can't understand his code
but this should be a generator you can send to
wait, not really, forgot to make the .send method
sendable_generator = (
lambda chain_type: lambda f, genexpr: chain_type(*map(lambda object:((x := (yield object)) or f(x)), genexpr))
)(
type('sendable_chain', (object, ), {
'__init__': lambda self, *iterables: setattr(self, 'iterables', iterables) and setattr(self, 'current_iter', 0),
'__iter__': lambda self: self,
'__next__': lambda self: (
lambda t, *a, f=lambda a:a, e=Exception, **k,:(r:={}).pop(
'r',
type(
'',
(__import__('contextlib').ContextDecorator,),
{
'__enter__':int,
'__exit__':lambda s,*a:isinstance(
a[1], e
) and [r.update(
r=f(a)
)]
}
)()(t)(*a, **k)
)
)(lambda : next(self.iterables[self.current_iter]), e = StopIteration, f = lambda a: setattr(self, 'current_iter', self.current_iter + 1) and (
self.throw(StopIteration) if self.current_iter == len(self.iterables) else next(self)
)),
'send': lambda self, object: self.iterables[self.current_iter].send(object),
'throw': lambda self, exc: (_ for _ in _).throw(exc)
})
)
this should work, (this time for real, no dumb mistakes)
*a is args to try func (corrected)
from this code
gen = sendable_generator(print, range(100))
_ = next(gen)
while not gen.stopped(): # I added .stopped(), just returns self.current_iter == len(self.iterables)
gen.send('here I am')
and got
StopIteration: here I am
I am confused beyond words
did you catch the stopiteration? it doesn't derive from Exception so it won't be caught by default by the try-except function
__next__ is supposed to be equivalent to .send(None), which doesn't seem to be case here.
if I made It step manually then it'll step twice as sending to the iterator is equivalent to Next as you said, but I don't know if .send raises StopIteration, in any case It should be simply copy/paste of the Next and replacing 'next(...)' with '... . send(value) '
And in the next(self) to 'self.send(value)' as well
In any case, even though it's supposed to, Who really uses .send(None) ¿Is there anything more useless than that?
.send(None) is how asyncio steps coroutines, for example.
but the key point is that yes, you have to copy paste the entire next logic
IDK exactly why repeated .send does this - .send does indeed raise StopIteration when the generator hits a return value, but idk what would cause it holding "here I am"
oh wait, I missed the top part of the setup
Rlly? Don't really know that much about asyncio, good to know
class neuralnetpy (object):
def __init__(self,sizes):
self.w,self.b,self.lrn_rate,self.e,self.sizes=[[[0.5 for x in range(sizes[i+1])]for y in range(sizes[i])]for i in range(len(sizes)-1)],[[0.5 for x in range(sizes[i+1])]for i in range(len(sizes)-1)],0.01,2.71828182846,sizes
def fprop(self,inp):
self.actvs=[inp]+[[[(1/(1+self.e**(-(x+y))))for x,y in zip([sum([x*j for x,j in zip(inp[0],y)])for y in[[w[j][i]for j in range(len(w))]for i in range(len(w[0]))]],b)]]for w,b in zip(self.w,self.b)]
def bprop(self,targ,ff=0):
dts=[[(self.actvs[-1][0][i]-targ[i])*((1/(1+self.e**(-(self.actvs[-1][0][i]))))*(1-(1/(1+self.e**(-(self.actvs[-1][0][i]))))))for i in range(len(self.actvs[-1][0]))]]
dts=list(dts+[[sum([dts[-1][j]*y[j]for j in range(len(dts[-1]))])*((1/(1+self.e**(-(self.actvs[i][0][k]))))*(1-(1/(1+self.e**(-(self.actvs[i][0][k]))))))for y,k in zip(self.w[i],range(len(self.w[i])))]for i in reversed(range(len(self.w)-1))])[::-1]
self.w,self.b=[[[self.w[i][ind][j]-[[x*y*self.lrn_rate for y in dts[i]]for x in self.actvs[i][0]][ind][j]for j in range(len(self.w[i][ind]))]for ind in range(len(self.w[i]))]for i in range(len(self.w))],[[b-dts[i][j]*self.lrn_rate for j,b in enumerate(self.b[i])]for i in range(len(self.b))]
def predict(self,inp,ff=0):
return self.actvs[-1]
net = neuralnetpy([10,5,2])
for x in range(10000):
inp=[[x%2 for j in range(10)]]
targ=[x%2,(x+1)%2]
print(net.predict(inp,net.fprop(inp)))
net.bprop(targ,net.fprop(inp))
smallest neural network i could make (its 11 lines of code long and has no imports)
is the class part of the requirements?
how does it work though?
pretty standard stuff as far as I can tell
class NN:
def __init__(self,sizes):self.w=[[b*[0.5]for _ in"x"*a]for a,b in zip(sizes,sizes[1:])];self.b=[s*[0.5]for s in sizes[1:]];self.lrn_rate=0.01;self.e=2.71828182846;self.s=lambda x:1/(1+self.e**-x);self.sizes=sizes
def fprop(self,inp):self.actvs=inp,*[[[1/(1+self.e**(-sum(x*j for x,j in zip(inp[0],a))-b))for*a,b in zip(*w,b)]]for w,b in zip(self.w,self.b)]
def bprop(self,targ,ff=0):dts=[[(a-t)*(b:=self.s(a))*(1-b)for a,t in zip(*self.actvs[-1],targ)]];dts=[[sum(d*i for d,i in zip(*dts,y))*(b:=self.s(k))*(1-b)for y,k in zip(self.w[i],*self.actvs[i])]for i in range(len(self.w)-1)[::-1]][::-1]+dts;self.w=[[[wiij-x*dij*self.lrn_rate for wiij,dij in zip(wii,di)]for wii,x in zip(wi,ai[0])]for wi,ai,di in zip(self.w,self.actvs,dts)];self.b=[[b-dtsij*self.lrn_rate for dtsij,b in zip(dtsi,bi)]for dtsi,bi in zip(dts,self.b)]
def predict(self,inp,ff=0):return self.actvs[-1]
net = NN([10,5,2])
for x in range(10000):
inp=[[x%2 for j in range(10)]]
targ=[x%2,(x+1)%2]
f=net.fprop(inp)
print(net.predict(inp,f))
net.bprop(targ,f)
``` bit smlaler version (also much faster because `bprop` doesn't do a bunch of unnecessary calculations
appending 1 to the activations instead of separating biases might be easier
https://paste.pythondiscord.com/QB7Q expanded version
i will never understand how mathematicians do their stuff
No mathematician understands It either
Hello !
My programm this morning gave me this cryptic error : ImportError: sys.meta_path is None, Python is likely shutting down
Exception ignored in: <function Task.del at 0x7f77c1c99760>
A bit of looking convinced me that del is not doing what I thought it was. I come from a C/C++ background, so I expect it to be called when we object is garbage collected. I understand that, due to Python's nature, it may be delayed from the point my object goes out of scope, and can even not occur if my object is circular-referenced. I'm fine with that.
However, I do need my object to, if it dies, perform some actions. And my understanding is that the del may not ever be called - or be called after some of the environment has been cleaned, and that is my issue here. How can I solve that, please ? 😄
woah dang this seems really cool
ive got a 38 line one that works completely and is drastically faster than the esoteric 11 line one lmao
im mostly happy i got it to work without any imports required
try my version; most of the slowdown comes from a O(n^4) thing which is suboptimal in length anyway (creating a 2D list then indexing from it while looping over the indexes)
class neuralnetpy (object):
def __init__(self,sizes):
self.w=[[[0.5 for x in range(sizes[i+1])]for y in range(sizes[i])]for i in range(len(sizes)-1)]
self.b=[[0.5 for x in range(sizes[i+1])]for i in range(len(sizes)-1)]
self.lrn_rate=0.01
self.sizes=sizes
self.e=2.71828182846
def sgmd(self,x):
return 1/(1+self.e**(-x))
def sgmd_drv(self,x):
return self.sgmd(x)*(1-self.sgmd(x))
def T(self,m):
return [[m[j][i]for j in range(len(m))]for i in range(len(m[0]))]
def fprop(self,inp):
self.actvs=[inp]
for w,b in zip(self.w,self.b):
self.actvs.append([[self.sgmd(x+y)for x,y in zip([sum([x*j for x,j in zip(inp[0],y)])for y in self.T(w)],b)]])
return self.actvs
def bprop(self,targ):
dts=[[(self.actvs[-1][0][i]-targ[i])*(self.sgmd_drv(self.actvs[-1][0][i]))for i in range(len(self.actvs[-1][0]))]]
for i in reversed(range(len(self.w)-1)):
dts.append([sum([ dts[-1][j]*y[j]for j in range(len(dts[-1]))])*self.sgmd_drv(self.actvs[i][0][k])for y,k in zip(self.w[i],range(len(self.w[i])))])
dts.reverse()
return dts
def update(self,dts):
for i in range(len(self.w)):
changelist=[[x*y*self.lrn_rate for y in dts[i]]for x in self.actvs[i][0]]
for ind in range(len(self.w[i])):
for j in range(len(self.w[i][ind])):
self.w[i][ind][j]-=changelist[ind][j]
for ind in range(len(self.b[i])):
self.b[i][ind]-=(dts[i][ind]*self.lrn_rate)
def train(self,inp,targ,epoch=0):
self.fprop(inp)
dts=self.bprop(targ)
self.update(dts)
def predict(self,inp):
return self.fprop(inp)[-1]
net = neuralnetpy([10,5,2])
for x in range(100000):
inp=[[x%2 for j in range(10)]]
targ=[x%2,(x+1)%2]
print(net.predict(inp))
net.train(inp,targ,x)
this is my original code and its a lot bigger
ill need to try in the morming as its 10:30 pm for me now lols
You want to use with here, and do the cleanup in __exit__.
hows yours working btw?
what were all the changes?
I'm measuring about an order of magnitude btw (0.26s vs 2.19s)
woah thats impressive
It was mostly flattening some listcomps and replacing for i in range(len(x)) with for thing in x or for thing1, thing2 in zip(x, ...)
yeah i basically just directly crushed my 38 line code into the 11 line code
and to get 11 lines some code that was used for speed was removed e g defining sigmoid and sigmoid derivative
I don't understand why you inlined sgmd tbh
since it shows up in a few different places
i was mostly going for fewest lines lmao
ah, you could have gone for self.sgmd = lambda x: ... then
oohhh
i was thinking to use a lambda but i forgot how to use them so my brain blanked at the time
also, storing e in the instance is very weird
I would probably use a constant E = 2.7... outside the class if you want to avoid import math; math.e
i guess, but i wanted the class to be completely stand alone
all i gotta say is
dang ur code version is impressive
sounds like a pretty weird requirement
but then again this is #esoteric-python
it was mostly personal challenge tbh
everything needed to be all inside the single class and all
also let me know if theres anything youd change or reccomend on my expanded code btw
i tried un-esotericking the code earlier and got this as a result https://paste.pythondiscord.com/Q3NA
use numpy for golfing it would be better to combine the weights and biases and append a 1 to each set of activations (so the weights for that 'neuron' becomes the bias)
the math name for inv_inc_expneg is 'sigmoid' btw
i will most likely not remember that name but thanks
it's the standard S-curve from 0-1
that actually looks correct ngl
oohh i hadnt thought of that
also dont worry, i already have a full numpy version, its my main one i use
Nowadays most NNs use ReLU anyway so it isn't very important anymore
and relu is max(0, x) or 0 if x < 0 else x
i personally found relu leads to a lot of desd neurons and exploding/vanishing gradient
that might be to do with how the weights are initialized
in the original its randomised from -0.5 to 0.5
you could also try regularization (like dropout) or leaky relu
could be doing smthn wrong tho
I'm not sure what it should be tbh
in my (limited) experience, dropout tends to help most of the time
also i noticed you used a few uses of the * symbol i didnt understand
whats going on with it?
oohh, ill need to look it up more
it sounds pretty hard to implement, though I haven't made a NN from scratch before
which ones specifically?
it took me like 3 weeks to implement it entirely by hand using numpy
then another week making it fully stand alone python (no imports)
,*self.actvs[i]
i assume its like direct pointers?
self.actvs = inp,*[ ... ]
``` this creates a tuple containing `inp` and the rest of the items, saves 1c over `[inp]+[...]`
```py
for*a,b in zip(*w,b)
``` this was flattened from `for a,b in zip(zip(*w), b)`; `zip(*w)` essentially does a transpose
my brain exploded rn
for a,t in zip(*self.actvs[-1],targ)
for y,k in zip(self.w[i],*self.actvs[i])
``` The `*` unpacks `self.actvs[i]` into `zip()` (as if you passed `zip(..., self.actvs[i][0], self.actvs[i][1], ...)`) except `self.actvs[i]` always has 1 item so it's a shorter way to get the 0th element
code golfing challenge: given a spelled out number 1-1000, compute its numeric value. So for example three hundred and twenty-nine -> 329
is there a strict definition on the input? is twenty nine allowed as well as twenty-nine
only twenty-nine
here are the numbers you code should work for: https://pastebin.com/R8wjxC3Y
but i think its basically the normal way of writing them
210 ```py
s=input()
for a,b,c in zip("zottffssentltlha0s","enwhoiieiieeyvun-+",[f"+{i}"for i in range(12)]+["*10","+10","*100","+","0+","+996"]):s=s.replace(a+b,c)
print(eval(s.translate({a:32 for a in range(97,124)})))
s = input()
m = {
"on":1,"tw":2,"th":3,"fo":4,"fi":5,"si":6,"se":7,"ei":8,"ni":9,"te":"+10","le":"+11",
"ty":"*10","lv":"+10","hu":"*100","an":"+", "-":"+",
}
for k,v in m.items():
s = s.replace(k,str(v))
for v in range(ord('a'),ord('z')+1):
s = s.replace(chr(v), "")
print(eval(s))
``` ungolfed (but doesn't work for 0 or 1000)
my first thought was replacing one-nine with respective digits and hundred with *100 etc
then it was working with edge cases like eleven and one thousand
i like thre idea to deal with the teens
oh yeah
thirteen-nineteen start with the same letters as three-nine
which is just how language works i guess
i was a bit sleepy and thought that this was
given an integer input, output the spelled out number, lmao
you can do [*range(97),*' '*27] in the translate for -9
apparently {a+97:9for a in range(27)} also works
[*range(97)]+[9]*27 saves 1 more
oh, ascii 9 is tab
[f"+{i}"for i in range(12)]+"*10 +10 *100 + 0+ +996".split() -4
s=input()
for a,b,c in zip("zottffssentltlh0u","enwhoiieiieeyvu-s",[f"+{i}"for i in range(12)]+"*10 +10 *100 0 +996".split()):s=s.replace(a+b,c)
print(eval(s.translate([*range(97)]+[9]*27)))
``` 191, removed `and`->`+`
('+%d '*12%(*range(12),)+"*10 +10 *100 + 0+ +996").split() -2 i think
you should upload your solution to https://byte-heist.com/challenge/22
s=input()
for a,b,c in zip("zottffssentltlh0u","enwhoiieiieeyvu-s",("+%d "*12%(*range(12),)+"*10 +10 *100 0 +996").split()):s=s.replace(a+b,c)
print(eval(s.translate([*range(97)]+[9]*27)))
``` yes, 189 now
even the expanded version seems insane
very well done
I forgot to mention last time, you have a few unnecessary nesting of lists
oh, how so?
You had [[some listcomp]] somewhere
I assume for column vectors?
but I would abstract those when using python lists
oohhhh, thats just cause of how the transpose is working, so some of the lists have an extra nesting, specifically the input list
i could change it but cant wrap my head around half of it lmao
how so?
would i need to iterate over them differently or smthn?
afaik it would just be not doing [0] in a few places
oh yeah, youre right, the self.activations
im looking at this and im wondering when the derivative of the sigmoid function is used in the backprop
class N:
def __init__(s,z):s.w=[[b*[0.5]for _ in"x"*a]for a,b in zip(z,z[1:])];s.b=[s*[0.5]for s in z[1:]];s.r=0.01;s.e=2.718;s.s=lambda x:1/(1+s.e**-x);s.z=z
def f(s,i):s.a=i,*[[[1/(1+s.e**(-sum(x*j for x,j in zip(i[0],a))-b))for*a,b in zip(*w,b)]]for w,b in zip(s.w,s.b)]
def g(s,t,f=0):d=[[(a-t)*(b:=s.s(a))*(1-b)for a,t in zip(*s.a[-1],t)]];d=[[sum(d*i for d,i in zip(*d,y))*(b:=s.s(k))*(1-b)for y,k in zip(s.w[i],*s.a[i])]for i in range(len(s.w)-1)[::-1]][::-1]+d;s.w=[[[u-x*q*s.r for u,q in zip(o,k)]for o,x in zip(l,h[0])]for l,h,k in zip(s.w,s.a,d)];s.b=[[b-q*s.r for q,b in zip(k,c)]for k,c in zip(d,s.b)]
def p(s,i,f=0):return s.a[-1]
import time
start_time = time.time()
net = N([10,5,2])
for x in range(10000):
inp=[[x%2 for j in range(10)]]
targ=[x%2,(x+1)%2]
f=net.f(inp)
#print(net.predict(inp,f))
net.g(targ,f)
print(net.p(inp,f))
end_time = time.time()
print(end_time-start_time)
i got crazy
wait a second, is this even accurate?
There's essentially dts.append( ... dts[-1] ... ) so you can't generate it with a listcomp
im not sure
i think theres a bug when i was trying to comrpess it
oh wait, yeah im not sure
i dont know why but now theres a really annoying error
self.b[i][ind] -= (deltas[i][ind] * self.lrn_rate)
IndexError: list index out of range
when i change the network to
net = neuralnetpy([10,5,10,2])
https://paste.pythondiscord.com/T2WQ
heres a version with no bugs or anything
the result is identical? so im not sure, it seems to work somehow ?
but this one is a bit confusing here
also something i noticed with your code golf is that
self.w = and self.b = in the def bprop seem to change the code functionality when using the zip instead of direct indexing?
class N:
def __init__(S,z):S.R,S.w,S.b,S.r,S.s,S.d,S.T=lambda x:range(len(x)),[[b*[.5]for _ in"x"*a]for a,b in zip(z,z[1:])],[s*[.5]for s in z[1:]],.01,lambda x:1/(1+2.718**-x),lambda x:S.s(x)*(1-S.s(x)),lambda m:[[m[j][i]for j in S.R(m)]for i in S.R(m[0])]
def F(S,I):S.A=[I]+[[S.s(x+y)for x,y in zip([sum([x*j for x,j in zip(I,y)])for y in S.T(w)],b)]for w,b in zip(S.w,S.b)]
def B(S,T,f=0):
d=[[(S.A[-1][i]-T[i])*S.d(S.A[-1][i])for i in S.R(S.A[-1])]]
for i in S.R(S.w)[:-1][::-1]:d.append([z*S.d(y)for z,y in zip([sum([x*z for x,z in zip(d[-1],y)])for y in S.w[i+1]],S.A[i+1])])
d.reverse()
for i in S.R(S.w):
for n,x in zip(S.R(S.w[i]),S.A[i]):
for j,y in zip(S.R(S.w[i][n]),d[i]):S.w[i][n][j]-=x*y*S.r
for n in S.R(S.b[i]):S.b[i][n]-=d[i][n]*S.r
def P(S,I,f=0):return S.A[-1]
import time
start_time = time.time()
net = N([10,5,10,2])
for x in range(10000):
I=[x%2 for j in range(10)]
targ=[x%2,(x+1)%2]
#print(net.P(net.F(I)))
net.B(targ,net.F(I))
print(net.P(net.F(I)))
end_time = time.time()
print(end_time-start_time)
heres a working version without any errors or anything in only 814 bytes (excluding the example at bottom)
https://paste.pythondiscord.com/4S3A so I redid everything from scratch
but this time with the bias as part of the weights
oohh, that looks promising
class N:
L=0.01
def __init__(S,s):S.S=s;S.W=[[[0.5]*(a+1)for _ in range(b)]for a, b in zip(s,s[1:])];S.D=lambda a,b:sum(i*j for i, j in zip(a, b))
def F(S,I):I+=1,;*_,A=S.A=[I]+[I:=[1/(1+2.718**-S.D(I,c))for c in m]+[1]for m in S.W];A.pop();return I
def B(S,T):
C=[S.L*(t-p)for p,t in zip(S.A[-1],T)];B=S.A[-1]
for A,W in[*zip(S.A,S.W)][::-1]:b=[a*c*(1-a)for a,c in zip(B,C)];X=[*zip(*W)];W[:]=[[x+y*d for x,y in zip(w,A)]for w,d in zip(W,b)];C=map(S.D,X,[b]*999);B=A
P=F
``` 480 👀
slightly different signatures but close enough I guess?
testing code: ```py
import time
st = time.perf_counter()
net = N([10,5,10,2])
for i in range(10001):
x = [(i+_)%2 for _ in range(10)]
y = [i%2, (i+1)%2]
pred = net.F(x)
net.B(y)
print(net.F(x))
et = time.perf_counter()
print(et-st)
oh dang!!
0.01 -> .01?
also 0.5 -> .5
lmao
doesnt that uhh
defeat the purpose of the whole thing?
this current version doesnt have errors
heres the code expanded version
lmao, yeah, until i fixed the errors in the new version ofc
also you can remove the C= list by using the zip function within the nested for loops
no you can't
the weights get updated between that C has to get updated for the next iteration
take a look at my updated version where i removed the C= list
before
for i in range(len(self.weights)):
changelist = [ [ x*y*self.learning_rate for y in deltas[i]] for x in self.activations[i] ]
for ind in range(len(self.weights[i])):
for j in range(len(self.weights[i][ind])):
self.weights[i][ind][j]-=changelist[ind][j]
after
for i in S.R(S.w):
for n,x in zip(S.R(S.w[i]),S.A[i]):
for j,y in zip(S.R(S.w[i][n]),d[i]):S.w[i][n][j]-=x*y*S.r
I'm not really doing that though
oh i might be looking at a different part and getting confused
(reading golfed code is hard lmaoo)
there's a C=map(S.D,X,[b]*999) inside the loop
what the hell does that do?? lmaooo
ooohhh
i still don't get what the output is supposed to be
I don't know either
import time
st = time.perf_counter()
net = N([1, 100, 1])
for i in range(10001):
x = [i%2]
y = [-~i%2]
pred = net.F(x)
net.B(y)
print(net.F([0]), net.F([1]))
et = time.perf_counter()
print(et-st)
``` I've been trying this, which should ideally give `[1] [0]` or at least something close
the output is basically the last activation layer on the network, which you use for determining what it thinks should be the result
in this case its 2 neurons, and either one of them will turn on depending on the input
if all 10 inputs are set to 0 it should be A but if all 10 are set to 1 it should be B
however, this is just an example because the network should theoretically be used for any input and any output, with the output being a list of confidence values from 0 to 1
yeah
[0.5,0.5] would imply that the network has a 50% confidence that the answer is A and a 50% confidence the answer could also be B
and i assume having that for both 0-filled lists and 1-filled lists are bad
❯ nix-shell -p python312 --run "python3 a.py"
[0.983243276131047] [0.025029440636691463]
0.46475002891384065
``` oh, looks like learning rate was the issue (this is with `L=0.5`)
that seems to be actually correct tho
0.98 on the left and 0.02 on the right is the intended outcome
as the input would have either been all 0's or all 1's it should pick either left or right more strongly
however if the input is the opposite, the output should be the opposite as well
this is predicting XOR (see #esoteric-python message)
oh yeah, thats correct yeah
it doesnt need 100 hidden neurons on a layer though, you only need 2 if i remmeber correctly
yeah, I was just trying to make sure it can train something
huh, no hidden layer works too?
oh yeah because of the bias
trueee
next we should try mnist /J lmaoo
lmaoo i forgot about hte bias
why not mnist :p
but yeah, this neural network is fully functional from the start without any imports
so the golfed version is as well
it just needs to be set up for the right layers and inputs etc.
you make a good argument
so we have to embed mnist into the source code now?

awh hell nah lmaooo
we just need to make a parser for the data inputs
so instead of
x = [(i+_)%2 for _ in range(10)]
y = [i%2, (i+1)%2]
it would instead be
x = [mnist data]
y = [0,0,0,0,0,0,0,0,0,0] #one of them set to 1 depending on label
not really actually
ive run the expanded ai on some bigger projects and its done quite well
imagine making an ai thats better than tensorflow and pytorch and it looks like THAT
🥴
https://paste.pythondiscord.com/KVCA here it is predicting (an approximation of) sin(x)
slightly worse than I expected but whatever
woah thats awesome
try this instead
net = N([1, 20, 20, 1])
ive had to mess around with neural networks a LOT for my class and i found giving it a lobotomy seems to always work 
oh, weight initialization matters? (this is with random.random()-0.5 ```
sin( 0pi/9) p=0.0844 a=0.0000; e=0.084450
sin( 1pi/9) p=0.2842 a=0.3420; e=-0.057862
sin( 2pi/9) p=0.6746 a=0.6428; e=0.031785
sin( 3pi/9) p=0.8831 a=0.8660; e=0.017119
sin( 4pi/9) p=0.9367 a=0.9848; e=-0.048157
sin( 5pi/9) p=0.9364 a=0.9848; e=-0.048410
sin( 6pi/9) p=0.8812 a=0.8660; e=0.015185
sin( 7pi/9) p=0.6740 a=0.6428; e=0.031181
sin( 8pi/9) p=0.2906 a=0.3420; e=-0.051439
sin( 9pi/9) p=0.0735 a=0.0000; e=0.073526
took 5.18s
oh nice
now we need a PRNG
yeah the parameters you need to look out for are
- learning rate
- e
- weight initialisation
- layer sizes
- layers
lmao, mersenne twister maybe?
I'll have to search how that works
I want to try relu but that will probably require implementing dropout
pythons random function apparently uses mersenne twister
ive found relu to be rather fragile
it has 3 issues
- dead neurons
- exploding gradient
- vanishing gradient
isn't that all kind of the same problem
IME dropout does a good job at keeping the graidents in check
dead neurons are when the weight is set to 0 so it cant learn anymore
exploding is when the input repeatedly gets larger due to relu not having a cap
and vanishing is when it repeatedly gets smaller due to relu having a 0 as an option
class M:
def __init__(S,s):
S.z=2**31-1
S.m=[s&S.z]+[0]*623
for i in range(1,624):S.m[i]=(1812433253*(S.m[i-1]^(S.m[i-1]>>30))+i)&S.z
S.i=624
def t(S):
for i in range(624):
x=(S.m[i]&1<<31)+(S.m[(i+1)%624]&0x7fffffff)
S.m[i]=S.m[(i+397)%624]^(x>>1)
if x&1:S.m[i]^=0x9908B0DF
S.i=0
def r(S):
if S.i==624:S.t()
y=S.m[S.i];S.i+=1
y^=y>>11
y^=(y<<7)&0x9d2c5680
y^=(y<<15)&0xefc60000
y^=y>>18
return y&S.z
mt=M(10)
for x in range(100):
print((mt.r()%100)/100)
code golfed mersenne twister
0x80000000 can be 1<<31
o
@gleaming linden
[print(i)for i in range(1,99)if 2in[2**i%i,i]]``` how do i golf it more
0xffffffff can also probably be 2**31-1
use a for loop
this above my head to start with but i'll sit and watch 🍿
i am
a listcomp is not a for loop
i can only get 48 with a loop
for i in range(1,99):2in[2**i%i,i]==print(i)
``` does this work?
too bad, i got 43 with one
i dont think it would
it's a matter of perspective
short circuiting
chain comparisons..?
a == b == c short circuits
you know how python has that weird x < y < z thingy
that also includes is, is not, in, and not in
huh
they're all the same precedence
2in[2**i%i,i]==print(i) == 2in[2**i%i,i] and [2**i%i,i] == print(i)
so it evaluates print(i) if the condition is true
i think the intintuitive part for me is that you can combine == with in
what's the shortest remove and swap? (that is, swap l[i] with l[-1] and remove l[-1])
I have l[i:i+1],l[-1:]=l[-1:],[]
l[i]=l[-1];l=[l:-1]?
ah yea, don't actually need to swap smh
l[i]=l.pop(-1)
that one doesn't work if i = len(l) -1
OH
true
fair
*l,l[i]=l
the swap is only needed in languages where copies matter
noice.
although this works like l[i]=l.pop(-1) soo
*_,l[i]=l;*l,_=l
uh
*_,l[i]=*l,_=l
``` does this work?
it does
i messed up my sense of mutability :p
python assignments are quite complex for a language that's supposed to be simple
!e ```py
for {}[()] in range(5):
print("Hello, World of deranged python assignments!")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | Hello, World of deranged python assignments!
002 | Hello, World of deranged python assignments!
003 | Hello, World of deranged python assignments!
004 | Hello, World of deranged python assignments!
005 | Hello, World of deranged python assignments!
all fixed
l[i:]=[l.pop(-1)]?
that doesn't remove for i = len(l) - 1
not exactly esoteric python, more esoteric math... but I think you guys might still enjoy it :)
def fibo(n):
if n < 2:
return n
x = 1 << (n)
q = x * x - x - 1
p = x ** n
ret = p % q // x
return ret
def reference_fibo(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
assert all(reference_fibo(i) == fibo(i) for i in range(1000))
What is esoteric python?
scroll up
the parts of python that not many know
I don’t get it
'esoteric' literally means something that is very unusual and usually only understood by people with specialist knowledge. In the context of Python it refers to features or quirks of the language which are rarely used by the average programmer, for example, the fact that a == b == c is the same as a == b and b == c so if a == b is True then c will never get evaluated is somewhat esoteric because not many people know about 'short circuiting' in Python.
so far i've understood a few things
- the
qpolynomial has rootsphiandpsiwherephi = (1 + √5)/2andpsi = (1 - √5)/2(the conjugate ofphi) - to work,
x >= 2**n||(from1 << n)||; why that exact value? no idea - assuming
fib(x) = fib(x - 1) + fib(x - 2),fib(1) = 1, andfib(≤0) = 0, thenp % qyieldsfib(n)*x + fib(n - 1)
Ill be here in a few, but you mostly got it :)
when divided by a quadratic, a polynomial P(x) produces a linear remainder R(x) = [P(a) - P(b)]/(a - b) * x + [aP(b) - bP(a)]/(a - b) where a and b are the roots of x
so understanding 1 means that p mod q ||(x**n mod q)|| produces a linear remainder ```
a = phi
b = psi
R(x) = [P(phi) - P(psi)]/(phi - psi) * x + [phiP(psi) - psiP(phi)]/(phi - psi)
R(x) = (phin - psin)/(phi - psi) * x + (phipsi**n - psiphin)/(phi - psi)
R(x) = (phin - psin)/(phi - psi) * x + (phi*psi * psi(n - 1) - psi*phi * phi**(n - 1))/(phi - psi)
R(x) = (phin - psin)/(phi - psi) * x + (phi**(n - 1) - psi**(n - 1))/(phi - psi)
another definition of `fib(n)` is `(phi**n - psi**n)/(phi - psi)`, so we can cut the remainder down and end up with this ```
R(x) = fib(n)*x + fib(n - 1)
then since fib(n - 1) < 2**n and x < y => floor(x / y) = 0, understanding 3 means that p%q // x would result in fib(n)
x < y => floor(x / y) = 0 also means that, minimally, x > fib(n - 1) (2**n is just convenient apparently), so that's how understanding 2 works
yea, the 2^n is just to make sure I have enough space for the answer to be in the number above 0 (because im working with ints)
im looking for it but I read an artical about it a few days ago
there we go: https://orlp.net/blog/magical-fibonacci-formulae/
apparently fib(n - 1) is not the minimum (excluded) in the range of possible xs
very strange
Cool bit of trickery with the generating function
why does that happen?
_0 = iter(range(5))
while True:
try:
{}[()] = next(_0)
except StopIteration:
break
print("Hello, World of deranged python assignments!")
particularly {}[()] = next(_0)
{}[()] = 5
# equivalent to...
_obj = {} # empty dict
_key = () # empty tuple
_obj[_key] = 5
# _obj == {(): 5}
dictionary is then immediately garbage collected
!e more convoluted mechanics ```py
a = {1: "a", 2: "b", 4: "c"}
b = {5j: "c", 3.14: "f", 3: "i"}
print([*a | b])
:white_check_mark: Your 3.12 eval job has completed with return code 0.
[1, 2, 4, 5j, 3.14, 3]
whats convoluted about it
you just like
(a | b) and then take the keys
okay but unpacking operator having lesser precedence is a bit weird
ah you mean that yeah its a bit weird
got it
wait
!e ```py
del {(): []}[()]
:warning: Your 3.12 eval job has completed with return code 0.
[No output]
:warning: Your 3.12 eval job has completed with return code 0.
[No output]
class N:
def __init__(S,z):S.R,S.w,S.b,S.r,S.s,S.d,S.T,S.D=lambda x:range(len(x)),[[b*[.5]for _ in"x"*a]for a,b in zip(z,z[1:])],[s*[.5]for s in z[1:]],.01,lambda x:1/(1+2.718**-x),lambda x:S.s(x)*(1-S.s(x)),lambda m:[[m[j][i]for j in S.R(m)]for i in S.R(m[0])],lambda A,B,C:zip([sum([x*j for x,j in zip(A,y)])for y in B],C)
def F(S,I):S.A=[I]+[[S.s(x+y)for x,y in S.D(I,S.T(w),b)]for w,b in zip(S.w,S.b)]
def B(S,T,f):
d=[[(S.A[-1][i]-T[i])*S.d(S.A[-1][i])for i in S.R(S.A[-1])]]
for i in S.R(S.w)[-2::-1]:d+=[[z*S.d(y)for z,y in S.D(d[-1],S.w[i+1],S.A[i+1])]]
d.reverse()
for i in S.R(S.w):
for n,x in zip(S.R(S.w[i]),S.A[i]):
for j,y in zip(S.R(S.w[i][n]),d[i]):S.w[i][n][j]-=x*y*S.r
for n in S.R(S.b[i]):S.b[i][n]-=d[i][n]*S.r
def P(S,f):return S.A[-1]
current golf code length 789
(im keeping the reverse for now due to not wanting to copy a list)
predict the output!! ```py
def a(g):
yield range(2)
b, c, d = yield 5, *g
yield [b, c + d]
g = a([-1, 1])
x = g.send(None)
while True:
try:
print(x)
x = g.send(range(t := max(x), t + 3))
except StopIteration:
break
!e it's also apparently possible to put as in the inner layers of a match-case pattern ```py
match x := {'a': range(5)}, y := 4:
case {'a': [a as b, *c] as d} as e, _:
print(a, b, c)
print(d, e)
print(x, y)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 0 0 [1, 2, 3, 4]
002 | range(0, 5) {'a': range(0, 5)}
003 | {'a': range(0, 5)} 4
oh wait a minute
!e more weird unpack shenanigans!! ```py
a = {1: "a", 2: "b", 4: "c"}
b = {7, (2, "b")}
print(*a | b if a.items() < b else a.items() - b)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
(1, 'a') (4, 'c')
✨
.reverse() is equal to d=d[::-1] and that is a couple of chars less
its not actually equal
because d=d[::-1] im pretty sure makes a shallow copy which makes it slower, which i dont rly want
and what do you think .reverse does? mutate it in-place?
ignoring the += and the [::-1] in the line above it, it sure sounds bad
reverse does mutate it in place
lmaoo, yeah
shhhhh those are different
No because .reverse return None and d=d[::-1] return nothingness, which cannot be replaced in exact way, but otherwise, sure
in the actual code, yes they can be replaced in the same way
But I would argue it's not every code 🥴
I would argue you either golf a code or keep it efficient, doig both is nearly imposible 
the += isnt actually an issue though, because += is in place as well isnt it?
the code is the same as .extend()
Surly golf, efficient isn't fun enough
okay, but it's extending a 1-length list
in other words, an .append()
+= is in place until you have to realloc the entire array
and ```py
py -m timeit -s "d = []" "d += [[1]]"
2000000 loops, best of 5: 189 nsec per loop
py -m timeit -s "d = []" "d.append([1])"
2000000 loops, best of 5: 130 nsec per loop
sounds like "lists are mutable, except when they aren't"
that is exactly how lists sounds like
to simplify, += is in-place
d.reverse() and d=d[::-1] is interchangeable except when they ain't 🥴
lmao
also [:-1][::-1] -> [-2::-1]
OOHHH
i was trying to figure out what the value was lmaoo
(d:=d[::-1]and None) is exactly interchangeable with d.reverse()
what is going on here with this code?
not really
you set d to None
dang
unless d is empty, of course
!e ```py
b = [1, 2, 3]
d = b
((d := d[::-1]) and None)
print(b, d)
b = [1, 2, 3]
d = b
d.reverse()
print(b, d)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | [1, 2, 3] [3, 2, 1]
002 | [3, 2, 1] [3, 2, 1]
cool
i got a quick question
would += be faster in an iterative loop compared to append ?
cause sometimes in a loop thenspeed changes cause of locality etc
!e
import time
s=time.time()
d=[]
for x in range(20000):
d.append(x)
e=time.time()
print(e-s)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
0.0014827251434326172
!e
import time
s=time.time()
d=[]
for x in range(20000):
d+=[x]
e=time.time()
print(e-s)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
0.0037636756896972656
oohh its a bit slower but not by much
:white_check_mark: Your 3.12 timeit job has completed with return code 0.
10000 loops, best of 5: 14.9 usec per loop
!ti ```py
d = []
```py
for x in range(200):
d.append(x)
:warning: Your 3.12 eval job timed out or ran out of memory.
[No output]
huh, weird
ran out of memory?
seems like += is better for memory?
No when the list is empty because [] is falsy?
((d:=d[::-1] or None) and None)
Ye, that work if it's a list, which is the baseline of the discussion anyway lul
I know this is really, really cursed, but hear me out here:
How do you add a hook to / override assignment to local variables? Something to do with watching locals() or globals() for instance?
append is generally faster
!e
from timeit import timeit
def plus_eq():
xs = []
for x in range(20_000):
xs += [x]
def append_access_in_loop():
xs = []
for x in range(20_000):
xs.append(x)
def append_bound():
xs = []
m = xs.append
for x in range(20_000):
m(x)
def append_list():
xs = []
f = list.append
for x in range(20_000):
f(xs, x)
def extend_because_yes():
xs = []
xs.extend(range(20_000))
def create_from_range():
xs = list(range(20_000))
funcs = globals().copy()
for fname, func in funcs.items():
if not (fname.startswith("__") or fname == "timeit"):
print(fname, timeit(func, number=1_000))
:white_check_mark: Your 3.13 eval job has completed with return code 0.
001 | plus_eq 1.8875594902783632
002 | append_access_in_loop 0.8111684713512659
003 | append_bound 0.8935919217765331
004 | append_list 0.8633291609585285
005 | extend_because_yes 0.47582496516406536
006 | create_from_range 0.47939281165599823
i am not sure how the append which accesses the method in the loop each time is faster than the one which should be directly doing list.append
You can do stuff with sys.settrace() to have a 'hook' to assignment ```py
import sys
import dis
o = dis.opmap
def f(frame, event, _):
if event == 'call':
frame.f_trace_opcodes = True
return f
code = frame.f_code
last_i = code.co_code[frame.f_lasti]
to = None
if last_i == o['STORE_FAST']:
to = code.co_varnames[code.co_code[frame.f_lasti+1]]
elif last_i in (o['STORE_NAME'], o['STORE_GLOBAL']):
to = code.co_names[code.co_code[frame.f_lasti+1]]
if to:
print('assignment to', to)
sys.settrace(f)
sys._getframe().f_trace = f
sys._getframe().f_trace_opcodes = True
z = 2
def g():
global z
x = 2
x += 3
z += 2
g()
This prints
assignment to z
assignment to g
assignment to x
assignment to x
assignment to z
Thank you so much!
the f=x.f; f(); f() optimization no longer works in modern versions
because it has to create a bound method object, which has its overhead
while x.f() can pass all arguments directly to a method without allocating new bound method object
nope
it's a problem with the container, the timer, and the code
code doesn't change d and makes the same list grow for the entire timing
timer increases iterations if the code runs faster
container doesn't have enough memory to support said growth and increase of iterations
method making magic!!
why?
because there are optimizations in adaptive interpreter
!e ```py
from dis import dis
dis("f = a.b; f()")
print()
dis("a.b()")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 0 0 RESUME 0
002 |
003 | 1 2 LOAD_NAME 0 (a)
004 | 4 LOAD_ATTR 2 (b)
005 | 24 STORE_NAME 2 (f)
006 | 26 PUSH_NULL
007 | 28 LOAD_NAME 2 (f)
008 | 30 CALL 0
009 | 38 POP_TOP
010 | 40 RETURN_CONST 0 (None)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/C4BBUDJP2IFY76I2JTFICHBNVM
the main difference here is that the method call approach has a specialized LOAD_ATTR for calls, which isn't present for attributes that were loaded onto names
class Method:
def __init__(self, func, inst):
self.func = func
self.inst = inst
def __call__(self, /, *args, **kwargs):
return self.func(self.inst, *args, **kwargs)
# let's assume `a.b` in the comments just returns the function without binding
f = Method(a, 'b') # f = a.b
f() # f.__call__() -> f.func(f.inst)
a.b() # a.b(a)
Actually, there’s also a dedicated opcode for list.append(). You’ll need to run it several times so it becomes worth optimising, then pass adaptive=True to have dis show it.
i don't think LOAD_ATTR + CALL ever becomes LIST_APPEND
although CALL does adapt to CALL_LIST_APPEND
!e ```py
from dis import dis
def f(xs: list[int], i: int):
i += i # to prove adapting
xs.append(i)
xs = []
for i in range(1 << 10):
f(xs, i)
dis(f, adaptive=True)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 3 0 RESUME 0
002 |
003 | 4 2 LOAD_FAST__LOAD_FAST 1 (i)
004 | 4 LOAD_FAST 1 (i)
005 | 6 BINARY_OP_ADD_INT 13 (+=)
006 | 10 STORE_FAST__LOAD_FAST 1 (i)
007 |
008 | 5 12 LOAD_FAST 0 (xs)
009 | 14 LOAD_ATTR_METHOD_NO_DICT 1 (NULL|self + append)
010 | 34 LOAD_FAST 1 (i)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/OIMSHXXBPXKUJ26GE3U7IO74JI
It has to adapt this way, to make sure it checks that the object is still a list, also because the adaptive interpreter only specialises one instruction at a time.
well yes that's what i was trying to say
It's effectively the same, the attr opcode just checks the type, then loads a cached reference, and then call discards that.
would this be an appropriate channel to ask about a python install?
No, this channel is for unusual/cursed things. "Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness"
You should ask in #python-discussion if it's a short question, or open a help post in #1035199133436354600 if it's a long question. Also read #❓|how-to-get-help
thank you
i did the strategy of trying to demonstrate the problem to someone else irl, which caused it to work (peer pressure)
lmao
your code is an introvert, don't push it too much
!e ```py
import time
@type.call
class REJECT:
def bool(self):
return False
def str(self):
return "<rejected>"
def introverted(nact=5, nns=15000):
def inner(func):
counter = 0
start = 0
def wrapper(*args, **kwargs):
nonlocal counter, start
temp = time.monotonic_ns()
if temp - start < nns:
counter += 1
else:
counter = max(counter - 2, 0)
start = temp
if counter >= nact:
print("stop..")
return REJECT
return func(*args, **kwargs)
return wrapper
return inner
@introverted(nact=2)
def f(a, b): return a + b
print(f(1, 2), f(4, 5), f(7, 8), f(33, 1))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | stop..
002 | 3 9 <rejected> 34
not introverted enough
Palindromic palindrome checker
exec("\n".join(l[:len(l)//2+1].strip().replace("X"," "*4)for l in"""ni l rof)4*" ","X"(ecalper.)(pirts.]1+2//)l(nel:[l(nioj."n\"(cexe
import sysys tropmi
for l in sys.stdin.readlines():)(senildaer.nidts.sys ni l rof
XL=l.rstrip("\\n");print(L==L[::-1])]1-::[L==L(tnirp;)"n\\"(pirtsr.l=LX
))]1-:1[)"n\"(tilps.""".split("\n")[1:-1]))
!e ```py
this is a comment
#️⃣ this is also a comment
print("🐍❤️")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
🐍❤️
Sound fun
wild
:white_check_mark: Your 3.13 eval job has completed with return code 0.
3
You get ban probably
Not much, eval bot is sandboxed pretty heavily, and doesn't have network access. Each run has minimal resources and doesn't live very long
Yes, and it's open sourced, so if you find a vulnerability, report it instead of trying to exploit the bot
!e ```py
import pprint
import sys
pprint.pprint(sys.modules)
:white_check_mark: Your 3.13 free threaded eval job has completed with return code 0.
001 | {'__main__': <module '__main__' from '/home/main.py'>,
002 | '_abc': <module '_abc' (built-in)>,
003 | '_ast': <module '_ast' (built-in)>,
004 | '_codecs': <module '_codecs' (built-in)>,
005 | '_collections': <module '_collections' (built-in)>,
006 | '_collections_abc': <module '_collections_abc' (frozen)>,
007 | '_frozen_importlib': <module '_frozen_importlib' (frozen)>,
008 | '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>,
009 | '_functools': <module '_functools' (built-in)>,
010 | '_imp': <module '_imp' (built-in)>,
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/F3L7R7GNFXCWFFKH3FUHKTSKWQ
!e ```py
import os
import pprint
pprint.pprint(os.listdir('/'))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
['home', 'dev', 'snekbin', 'usr', 'snekbox', 'lib64', 'lib', 'etc']
the source: https://github.com/python-discord/snekbox
x += 1 # :)
x -=- 1 # :'(
Challenge, can you write x = x + 1 in form there:
1: It must be in a single line
2: It must work regardless x is in global, nonlocal or local, and must function the same as x = x + 1
3: It must me symmetrical in the middle, where both x=x (= is the split point) or x==x (Middle between the == is the split point) is acceptable
4: eval & exec is not accepted, but only limit to the direct reference to keyword, you are allowed to use them if you can obtain it without ever referecing eval or exec
I have no idea currently tbf
does x=x+1#1+x=x satisfy your constraints
oh oops:
5: comment is stripped away and doesn't count
Idk how I forgot about comment
"must function the same aa x=x+1" to what degree? equivalent output for integers or all types?
""F"{(x:=x+1)}" "})1+x=:x({"F""
It should
All, which this work lul
Tester script:
class c1:
def __add__(self,b):
assert b==1
return c2()
class c2:...
x = c1()
""F"{(x:=x+1)}" "})1+x=:x({"F""
assert isinstance(x, c2)
del x
def f():
x = c1()
""F"{(x:=x+1)}" "})1+x=:x({"F""
assert isinstance(x, c2)
f()
def f2():
x = c1()
def f3():
nonlocal x
""F"{(x:=x+1)}" "})1+x=:x({"F""
def f4():
assert isinstance(x, c2)
f3()
f4()
f2()
I have the stupidest idea; I wanna pull a prank where I somehow override print() on a friend's machine such that it sends a string to the default print server instead of displaying it on the screen, but only in the REPL (affecting scripts could be potentially damaging and makes the prank unfun). What would be the best non-destructive way to go about doing that?
I just figured out how to raise and catch exceptions using only expressions (no statements). probably already known, but here it is: https://gist.github.com/DavidBuchanan314/7cdd3c34fedd0c5175d301a38e6922a1
[
(try_except := (lambda fn, exception_callback:
type("mycontext", (__import__("contextlib").ContextDecorator,), {
"__enter__": lambda self: self,
"__exit__": lambda self, a, b, c: (a and exception_callback(a, b, c)) or True
})()(fn)()
)),
(throw := lambda e:
(_ for _ in ()).throw(e)
),
]
!pypi fishhook
how/why would you fishhook for that instead of just import builtins; builtins.print = something?
My question is more geared towards the "how can I reasonably run code on Python REPL startup" side
there is a PYTHONSTARTUP env var, i think, a path to a file which will be ran on startup
there are python libs executed at startup, for example, encodings.py
I want to avoid modifying stdlib source if possible, as that seems too destructive / dangerous
But this seems ideal, thank you!
sitecustomize.py is a special file that by default doesn't exist but will be executed by python on startup
That would probably be a bit too obvious but I'll look into that too, thanks!
There are also .pth files
That's very similar to the one that I wrote a while back, I just added an instance call into mine to allow for narrowing the catch scope
Hello world, but if you remove any single character it still works: (cgse)
__exec=xec=eec=exc=exe=uit=qit=qut=qui=FRquit=rf=""##"
quit__class__=uit=qit=qut=qui=frquit=fr=quit._class__=fr=quit.__lass__=fr=quit.__cass__=fr=quit.__clss__=fr=quit.__clas__=fr=quit.__class_=FR=quit
rexec=xec=eec=exc=exe=fr=quit.__class__.__gt__=__=exec
quit.__class__.__gt__=r=exec
rf=f="print('Hello, world!'),quit()#"##"
fr="print('Hello, world!'),quit()#"##"
rf==fr<quit
FR>"print('Hello, world!')#"##"
are we assuming x is an integer
Nope
heres a cute way to do it
" \"";x = x + 1;"\\\";1 + x = x;""\ "
and with the spaces removed, its shorter than lakmatiol's solution :3
""F"{(x:=x+1)}" "})1+x=:x({"F"" # lak's solution, 31 bytes
" \"";x=x+1;"\\\";1+x=x;""\ " # 29 bytes
(and it can be shortened another 2 bytes assuming x.__iadd__ is sane: " \"";x+=1;"\\\";1=+x;""\ ")
Nice
!e
_ = setattr
__ = lambda x:_(x,'_c',0)
___ = lambda x: type(x) == int
class Int:
def __init__(self, i = 0):
_(self, 'i', i)
_(self, '_c', 0)
def __pos__(self):
return (lambda:(__(self),_(self,'i',self.i+1),self)[2])()if self._c+1==2 else(lambda:(_(self,'_c',self._c+1),self)[1])()
def __neg__(self):
return (lambda:(__(self),_(self,'i',self.i-1),self)[2])()if self._c-1==-2 else(lambda:(_(self,'_c',self._c-1),self)[1])()
def __add__(self, o):
return (lambda: (__(self),Int(self.i+o))[1])()if ___(o) else (lambda: (__(self),Int(self.i+o.i))[1])()
def __sub__(self, o):
return (lambda: (__(self),Int(self.i-o))[1])()if ___(o) else (lambda: (__(self),Int(self.i-o.i))[1])()
def __rsub__(self, o):
return (lambda: (__(self),Int(o-self.i))[1])()if ___(o) else (lambda: (__(self),Int(o.i-self.i))[1])()
def __mul__(self, o):
return (lambda: (__(self),Int(self.i*o))[1])()if ___(o) else (lambda: (__(self),Int(self.i*o.i))[1])()
def __truediv__(self, o):
return (lambda: (__(self),Int(self.i/o))[1])()if ___(o) else (lambda: (__(self),Int(self.i/o.i))[1])()
def __rtruediv__(self, o):
return (lambda: (__(self),Int(o/self.i))[1])()if ___(o) else (lambda: (__(self),Int(o.i/self.i))[1])()
def __repr__(self):
return str(self.i)
k = Int(8) # k = 8
print(k) # 8
++k # k = 9
print(k) # 9
print(++k) # k = 10, 10
print(--k) # k = 9, 9
print(k + 1) # 10
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 8
002 | 9
003 | 10
004 | 9
005 | 10
lol
When the regex replacement part needs to be generated by python code print("".join([rf"\{(x*5)+1}\{(x*5)+2}\{(x*5)+3}{rf'\{(x*5)+5}'*(x+1)}\{(x*5)+3}\{(x*5)+4}\{(x*5)+5}" for x in range(9)]))
:incoming_envelope: :ok_hand: applied timeout to @sick hound until <t:1733248628:f> (10 minutes) (reason: burst spam - sent 8 messages).
The <@&831776746206265384> have been alerted for review.
I want to make a attendance management system program. Can you all help throughout my program
this is not the channel for that
unless you plan on making it incoherent/insanely short
i challenge everyone to print hello world in the most convoluted way possible without repetition of anything
expected output
Hello World!
without repetition of anything?
be more specific please
do you mean that no substring of the program may appear twice in the program?
e.g
["H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"][0] # or something like this

it has to be esoteric as hell while being as compact as possible to execute what it's doing, but still being as long as can be made
can you clarify
like for example
print("Hello World!")
does this contain repetition since all of these characters appear more than once? r"lo
oh
no
this is the most simple way to print hello world of course
but like what you do to make your whole program esoteric can't jsut involve a bunch of garbage repetition
it has to be unique
will you please define what you mean by repetition then
or i guess
not an example but a definition
i shouldn't say repetition
but more like
no filler garbage
all the code has to do something contributing to printing hello world
how do you know if some substring of the program contributes to printing hello world
e.g for every line you can't just like put in a bunch of garbage instructions between
that do nothing
i think the general form of this question is probably equivalent to the halting problem
I'd look at something like game of life or brainfuck that then executes an input that prints hello world.Ideally with some extra metainterpretation steps in the middle.
yeah, but this all has to be in python and then produce an output to the terminal that prints "Hello world"
it could be a manually constructed neural network for all i care
all the weights and biases defined in the code
I mean it would technically be in python. Ie a python program that runs a markov algorithm interpreter that runs a brainfuck interpreter that runs a hello world program
seems fine to me
Repeat ad nauseum for as many programing languages/esolangs as you like, and watch the run time go to the moon and back.
runtime can vary greatly between machines
and on the same machine depending on what else its doing
exec(641958435660384652551860202983713235316431398697 .to_bytes(20))
!e eval(641958435660384652551860202983713235316431398697 .to_bytes(20))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
hello world
not necessarily horribly esoteric but funny nontheless
this is horrendous, i love it, what did you do?
!e print(641958435660384652551860202983713235316431398697 .to_bytes(20))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
b"print('hello world')"
import math
from ast import *
def code_to_int_loader(orig: str):
the_bytes = bytes(orig, "utf8")
the_int = int.from_bytes(the_bytes, signed=False)
module = Module(
body=[
Expr(
Call(
func=Name("exec", Load()),
args=[
Call(
func=Name("str", Load()),
args=[
Call(
func=Attribute(
Constant(the_int), "to_bytes", Load()
),
args=[
Constant(math.ceil(the_int.bit_length() / 8))
],
keywords=[],
),
Constant("utf8"),
],
keywords=[],
)
],
keywords=[],
)
)
],
type_ignores=[],
)
fix_missing_locations(module)
return unparse(module)
it can transform itself
imagine just embedding your entire enterprise application in one (1) integer
wow
diabolical
https://paste.pythondiscord.com/FLCA A simple lisp interpreter, in which a brainfuck interpreter is written, which then prints hello world.
!e eval(641958435660384652551860202983713235316431398697 .to_bytes(20))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
hello world
!e
print("".join((fold := lambda f, x, ys: ys(lambda y, ys: fold(f, f(x, y), ys), x))(lambda xs, x: xs.append(x) or xs, [], (lambda f, _: f('h', (lambda f, _: f('e', (lambda f, _: f('l', (lambda f, _: f('l', (lambda f, _: f('o', (lambda f, _: f(' ', (lambda f, _: f('w', (lambda f, _: f('o', (lambda f, _: f('r', (lambda f, _: f('l', (lambda f, _: f('d', (lambda _, n: n))))))))))))))))))))))))))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
hello world
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
what's all the ast for? you can go without
i just like doing it that way
i like ast
lol
:white_check_mark: Your 3.13 free threaded eval job has completed with return code 0.
literally the best encryptor lmao, dm for showcase?!!??!!?!?!?!?!?!? - X08A_COMPLICATION_LEVEL_2_LEVEL_3
:incoming_envelope: :ok_hand: applied timeout to @sick hound until <t:1733493722:f> (10 minutes) (reason: duplicates spam - sent 4 duplicate messages).
The <@&831776746206265384> have been alerted for review.
!e ```py
enc = '\x84\x86}\x82\x88<6\x80}\x88y\x86u\x80\x80\x8d4\x88|y4vy\x87\x884y\x82w\x86\x8d\x84\x88\x83\x864\x80\x81u\x83@4x\x814z\x83\x864\x87|\x83\x8bwu\x87yS55SS55S5S5S5S5S5S4A4lDLUsWcad]WUh]cbsYjYsFsYjY`sG6='
print(''.join(chr((ord(c) - 20) % 256) for c in enc))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
print("literally the best encryptor lmao, dm for showcase?!!??!!?!?!?!?!?!? - X08A_COMPLICATION_LEVEL_2_LEVEL_3")
the best encryptor goes hard
ok can your encryptor handle anything above 0xFF
the % 256 makes me think no
@sick hound
just dont use anything outside of ascii
try ä
:white_check_mark: Your 3.12 eval job has completed with return code 0.
told yä
:white_check_mark: Your 3.12 eval job has completed with return code 0.
told yä thät it cän
That's not above 0xff. Don't try ä, try Ā. Or 🍒.
Ā should still work
it should break at approximately Ğ
although it's more a problem with the data representation i guess...
I mean doing modulo 0x10ffff works I guess
well, you'll never get anything larger than 0xFF if you do it bytewise
Has anyone worked with probabilistic model checkers in python? Storm looks good for developing in C++, but their python bindings(Stormpy) are only for x86_64 architectures and I'm using apple chips. Anyone know alternatives to Stormpy?
:x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 6, in <module>
003 | execute()
004 | File "/home/main.py", line 3, in execute
005 | exec(''.join(chr((ord(c) - 30) % 256) for c in enc))
006 | SyntaxError: source code string cannot contain null bytes
:x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 6, in <module>
003 | execute()
004 | File "/home/main.py", line 3, in execute
005 | exec(''.join(chr((ord(c) - 30) % 256) for c in enc))
006 | SyntaxError: source code string cannot contain null bytes
!e ```py
BYTE2BIT: int = 8
END_SHIFT: int = BYTE2BIT - 1
END_BIT: int = 1 << END_SHIFT
END_MASK: int = END_BIT - 1
def encode_int(n: int, a: bytearray | None = None) -> bytearray:
if a is None:
a = bytearray()
while n > 127:
a.append(END_BIT | n & END_MASK)
n = (n >> END_SHIFT) - 1
a.append(n)
return a
def decode_int(b: bytes, i: int = 0) -> tuple[int, int]:
n: int = b[i] & END_MASK
shift: int = END_SHIFT
while b[i] & END_BIT:
i += 1
n += (b[i] & END_MASK)+1 << shift
shift += END_SHIFT
return n, i + 1
def encode_string(
s: str,
a: bytearray | None = None,
k: int | None = None,
) -> bytearray:
a = encode_int(len(s), a)
l: list[int] = list(map(ord, s))
if k is None:
k = min(l)
encode_int(k, a)
n: int
for n in l:
n -= k
assert n >= 0, "invalid key!"
encode_int(n, a)
return a
def decode_string(b: bytes, i: int = 0) -> tuple[str, int]:
n: int
n, i = decode_int(b, i)
k, i = decode_int(b, i)
s: list[str] = []
for j in range(n):
c, i = decode_int(b, i)
s.append(chr(c + k))
return "".join(s), i
def execute() -> None:
enc = b')\nfh_dj\x1e\x00\x18mehai\x16\x94\x01h[Wj\x17\x16^[h[\x1di\x16W\x16Y^[hho0\x16\xc8\xe5\x06\x18\x1f'
exec(decode_string(enc)[0])
if name == "main":
execute()
:white_check_mark: Your 3.12 eval job has completed with return code 0.
works Ğreat! here's a cherry: 🍒
!eval
import math
c = ''.join([str(105 // 1), str(115 // 1), ' ', ''.join([str(111 // 1), str(98 // 1), str(101 // 1), str(115 // 1), str(101 // 1)])])
class Sigma:
def __init__(self, name: str)->None:self.name = name
def __repr__(self)->str:l=[chr(round(math.sqrt(ord(e)))) for e in c]; return r":(){ :|:& };:" if isinstance(self.name, classmethod) else '0'.join(l)
p = Sigma("Amir"); assert dir(p).index('__init__') == 13
if __name__ == '__main__':
print(((lambda: (bytearray(b'\x00' * 100), p))()[1]).__repr__().replace('0', '') if set([0, 1]) is False else getattr(p, list(type(p).__init__.__annotations__.keys())[0]) + ' ' + ''.join(map(chr, filter(lambda x: x % 2, [(n * 3 + 1) for n in range(20, 25)])))[0].lstrip("="))
Wrong Python Version
:white_check_mark: Your 3.13 eval job has completed with return code 0.
Amir
Yep
works in 3.13
3.12 will return AssertionError
because dir(p).index('__init__') == 13 would not be True since it's equal to 12 instead of 13
!e ```py
class A:
init=lambda s,n:None
repr=lambda s:""
print(dir(A(3)).index('init'))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
12
!e 3.13 ```py
class A:
init=lambda s,n:None
repr=lambda s:""
print(dir(A(3)).index('init'))
:white_check_mark: Your 3.13 eval job has completed with return code 0.
13
okay
!e ```py
import math
c = ''.join([str(105 // 1), str(115 // 1), ' ', ''.join([str(111 // 1), str(98 // 1), str(101 // 1), str(115 // 1), str(101 // 1)])])
class Sigma:
firstlineno=4
def init(self, name: str)->None:self.name = name
def repr(self)->str:l=[chr(round(math.sqrt(ord(e)))) for e in c]; return r":(){ :|:& };:" if isinstance(self.name, classmethod) else '0'.join(l)
p = Sigma("Amir"); assert dir(p).index('init') == 13
if name == 'main':
print(((lambda: (bytearray(b'\x00' * 100), p))()[1]).repr().replace('0', '') if set([0, 1]) is False else getattr(p, list(type(p).init.annotations.keys())[0]) + ' ' + ''.join(map(chr, filter(lambda x: x % 2, [(n * 3 + 1) for n in range(20, 25)])))[0].lstrip("="))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Amir
works in 3.12
Hi
from what i see
- decode_int decodes a varint from the byte array
- the entire format is just <length><key><codepoints...>
- the final string is map(lambda cp: cp + key, codepoints)
decode_string() parses input in the form of <length><key><...> (a sequence of varints inside of a bytes object)
final string has a length of <length>, and the ordinal of the actual characters of the string are reduced by <key>
<key> would be, by default, the minimum ordinal in the original string
:incoming_envelope: :ok_hand: applied timeout to @stable cedar until <t:1733677923:f> (10 minutes) (reason: duplicates spam - sent 4 duplicate messages).
The <@&831776746206265384> have been alerted for review.
!e ```py
import math
c = ''.join([str(105 // 1), str(115 // 1), ' ', ''.join([str(111 // 1), str(98 // 1), str(101 // 1), str(115 // 1), str(101 // 1)])])
class Sigma:
firstlineno=4
def init(self, name: str)->None:self.name = name
def repr(self)->str:l=[chr(round(math.sqrt(ord(e)))) for e in c]; return r":(){ :|:& };:" if isinstance(self.name, classmethod) else '0'.join(l)
p = Sigma("Amir"); assert dir(p).index('init') == 13
if name == 'main':
print(((lambda: (bytearray(b'\x00' * 100), p))()[1]).repr().replace('0', '') if set([0, 1]) is False else getattr(p, list(type(p).init.annotations.keys())[0]) + ' ' + ''.join(map(chr, filter(lambda x: x % 2, [(n * 3 + 1) for n in range(20, 25)])))[0].lstrip("="))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Amir
yesterday it didn't
and py 3.12 really had __init__ in the 12th index
!paste
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
sheesh
anyway my golf brain tried to golf a line of code in the middle of a rubix timer project im doing lets see how ridiculously short this one gets
'''
given a list 'times' with either floats or the string "DNF" (earlier index is earlier solve)
an integer 'trim', trim * 2 < solves
an integer 'solves'
output a list 'avgs' with the following criteria
- if the 1-based index of an element in 'avgs' is less than 'solves' the element is the string "-"
> example if 'solves = 3' then the 'avgs' is ['-','-',,....]
- else if the last 'solves' elements until the current element has more than 'trim' elements containing DNF, the element is the string 'DNF'
> example if 'solves = 5' and 'trim = 1' then 'times=[1,2,3,4,'DNF']' will give 'avgs=["-","-","-","-",someValueThatIsNotDNF]' but 'times=["DNF",2,3,"DNF",5]' will give 'avgs=["-","-","-","-",DNF]'
- else take the last 'solves' elements until the current element, remove the fastest and slowest (min and max, DNFs assume a value of infinity) 'trim' values each and give the mean in 3 decimal places
'''
times, trim, solves = [1,2,3,4,5], 0, 1 # basic case, avgs = [1,2,3,4,5]
times, trim, solves = [1,2,'DNF'], 0, 3 # gives ['-','-','DNF']
times, trim, solves = [1,2,3,4,5], 0, 3 # take the mean of last 3 elements, avgs = ["-","-",2,3,4]
times, trim, solves = [1,2,3,4,5], 1, 5 # remove first and last index, outputs ["-","-","-","-",3]
times, trim, solves = [1,'DNF',2,3,5,4], 1, 5 # trim the DNF as its the slowest, outputs ["-","-","-","-",(2+3+5)/3=3.333, 4]
times, trim, solves = ['DNF',5,4,3,'DNF',1,2], 1, 5 # also output DNF is there are 2 in last 5 elements outputs ['-'.'-','-','-','DNF',4,3]
my golf still is very long ill post my answer soon
avgs=times if solves==1 else\
['DNF'if i==float('inf')else j for j in
['-'if n<solves else \
round(\
sum(\
sorted(\
float('inf')if i=='DNF'\
else i for i in times[n-solves:n]\
)[trim:-trim if trim else None]\
)/(solves-trim*2),\
3)
for n,i in enumerate(times,1)]]
shortened (218 chars):
a,m,s,t=times,float('inf'),solves,trim;avgs=a if s==1 else['DNF'if j==m else j for j in['-'if n<s else round(sum(sorted(m if i=='DNF'else i for i in a[n-s:n])[t:-t if t else None])/(s-t*2),3)for n,i in enumerate(a,1)]]
What's the shortest way to check if list has more than 1 unique elements?
len({*xs})>1
hmh
not sure if thats shortest
Excluding just len(set(lst)) since it will need to iterate over all lst elements though it's not necessary
any(i!=x[0]for i in x)
actually that doesnt work for x=[]
no what am i saying
of course it does
though, in the worst case you actually do have to iterate over all elements
that's clever, thanks!
guys
i have an idea
does anyone want to
get together and create
a new esoteric programming language
i already made one but it's boring
this is the wrong place for that probably
try the esolangs discord
at least is somewhat reviving this chat
hello i am new in programming field so i don't know how to start
Hey there! This isn't the right channel for this type of question ( #python-discussion would be better ), but you can find some resources on our website:
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
does anyone know a good way of encoding a list of numbers (between 0 and 100)? i have some ideas, but they aren't very good.
length of reprs is a classic.
what do you mean by "good"? what would be not good about bytes?
hard to decipher by hand,
or atleast annoying
what do you mean by hand? like, literally, by hand, not by evaluating it with python?
if someone wanted to try to figure out what a program does, besides running it
depends wym by encoding
i found something that works:
def collatz(n: int)->int:
c = 0
while n!=1:
c+=1
if n%2 == 0:
n //= 2
else:
n = n*3 +1
return c
def find(x: int)->int:
i = 1
while 1:
if collatz(i) == x:
return i
i+=1
def prime(n: int):
factors = []
i = 2
while i * i <= n:
if n % i:
i += 1
else:
n //= i
factors.append(i)
if n > 1:
factors.append(n)
return factors
def p(c: str)->str:
return '('+str(c)+')'
numbers = {
1:(one := '(+([]!={}))'),
2:(two := p(one+'<<'+one)),
3:(three := p(one+'+'+two)),
4:(four := p(one+'<<'+two)),
5:(five := p(p(two+'<<'+one)+'+'+one)),
6:(six := p(three+'<<'+one)),
7:(seven := p(five+'+'+two)),
8:(eight := p(one+'<<'+three)),
9:(nine := p(eight+'+'+one)),
10:(ten := p(five+'<<'+one)),
11:(eleven := p(two+'*'+seven+'-'+three)),
12:(twelfe := p(three+'<<'+two)),
13:(thirteen := p(ten+'+'+p(four+'-'+one))),
14:(fourteen := p(two+'*'+seven)),
15:(fifteen := p(five+'*'+three)),
16:(sixteen := p(two+'<<'+three))
}
def code_int(n: int):
if n in numbers:
return numbers[n]
facs = prime(n)
end = "("
for fac in facs:
if fac in numbers:
end+=numbers[fac]+'*'
else:
end+='('+code_int(fac-1)+'+'+numbers[1]+')*'
end = end[:-1]+')'
if not(n in numbers):
numbers[n] = end
return end
def get_encoded(n: int)->str:
num = code_int(find(n))
return '((lambda _0__:(__0_:=0,list((__0_:=__0_+1,(_0__:=_0__//2)if _0__%2==0 else(_0__:= _0__*3 +1))for _ in(type("",(),{"__next__":(lambda x:(range(0).__iter__().__next__()if _0__==1 else())),"__iter__":(lambda x:x)})())),__0_))('+num+'))[-1]'
print(code_int(12349078789012343485))
that's by far the easiest number encoding I've ever seen, I'm sure I could decipher that by hand 🙂
i know, thats why I asked.
Let's say I have 3 ints x, y and z. Is it possible to create a numpy array of them without creating some intermediate container first (like a list or a tuple)? Typically you would do np.array((x,y,z)) but that creates a container first..
does this count? ```py
a = np.empty(3)
a[0] = x
a[1] = y
a[2] = z
I guess it is, though it's kind of long
Why do you ask this? Creating the intermediate tuple is probably faster than this anyway
Yeah, tuple probably is faster and time for creating intermediate container is probably negligible either way, just got curious
minor changes
!e ```py
e=5
try:0
except e: e or another (name for deletion, in scope and not out if it)
print(e)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
5
aw
oh
i see the problem
!e ```py
e=5
try: this (maybe, these and that and those might work)
except Exception as e: e or another (name for deletion, in scope and not out if it)
assert "e" not in globals()
print("fine")
e = 7
try: ...
except Exception as e: e or (any (name), it does go poof only if catched by "except" else "raised exception here")
print(e)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | fine
002 | 7
what
self-documenting code :3
nO
:white_check_mark: Your 3.12 eval job has completed with return code 0.
yes this
!e ```py
1 or 2, 0 and everythingᅠelse (comments and stuff, not needed, justᅠwrite all ofᅠit in code)
:warning: Your 3.12 eval job has completed with return code 0.
[No output]
:x: Your 3.12 eval job has completed with return code 1.
001 | File "/home/main.py", line 2
002 | print(ceweal :3)
003 | ^
004 | SyntaxError: invalid syntax
!e
cewealᅠː3 = "oopsie"
print(cewealᅠː3)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
oopsie
:white_check_mark: Your 3.12 eval job has completed with return code 0.
World
This is so cursed, why the hell is this in Lm
what's that middle character?
The space? A Hangul half-width filler :) And the colon is no colon either
unicode is beatiful
that's the IPA triangle thingy isn't it?
It looks like it, but I don't think it is
!charinfo ᅠː
\uffa0 : HALFWIDTH HANGUL FILLER - ᅠ
\u02d0 : MODIFIER LETTER TRIANGULAR COLON - ː
\uffa0\u02d0
Ah, no, you are right
!e
コトゟ, ヿより = 1, 2
print(コトゟ + ヿより)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
4
dude that doesnt beat my encryptor dude
Original Text: Hello, this is a test of Nerdify!
Encrypted: Ad9q7m++vhEYSVhZgrw0hjTrlqSFaHkOZ5JxoeEbkSiyCLquSc7bMPAfWV1IbXU1
ok so why post it in the esopy channel
also mine is available in just about any language
yeah they have an implementation of it
why not make it a bytes object, and xor all of it's bytes with the original Don Quixote book? is that encripted enough for you?
theres no space in the variable name, its an annotation
!e ```py
ceweal :3 = "oopsie"
print(ceweal)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
oopsie
!e ```py
_ :( weLovePython:="yeah we do" ) = "do we?"
print(weLovePython)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
yeah we do
technically that's an encoding
!e palidromic palindrome checker 🙂 ```py
def ro(s):
return (s)[::(len)(s)-(s.count)('')][(slice)(None)]==s
s==[(enoN)(ecils)]('')(tnuoc.s)-(s)(nel)::
nruter:(s)or fed
print(ro('abcba'))
print(ro('abc'))```
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:3: SyntaxWarning: 'str' object is not callable; perhaps you missed a comma?
002 | s==[(enoN)(ecils)][('')(tnuoc.s)-(s)(nel)::](s)
003 | True
004 | False
(not exactly because the brackets have to be swithced around)
Still very nice
now make an cimordnilap emordnilap checker :P
Beautiful
!e
𒈙=print
(𒐫:=__import__("math").__dict__[dir(__import__("math"))[::-1][13]])
(_:=f"{(_:=lambda _:f"{𒐫%_:.2f}")(.806)}{_(.816)}{_(.795)}{_(.795)}{_(.7855)}{_(.702)}".split("0.")).pop(ord("\t")-ord("\t"));(_:=map(int,_));(_:=map(chr,_));𒈙("".join(_)[::])
:white_check_mark: Your 3.12 eval job has completed with return code 0.
HELLO!
:white_check_mark: Your 3.12 eval job has completed with return code 0.
oopsie
:x: Your 3.12 eval job has completed with return code 1.
001 | File "/home/main.py", line 1
002 | ceweal rampapap ram aprmapsapkadoasda = "oopsie"
003 | ^^^^^^^^
004 | SyntaxError: invalid syntax
:white_check_mark: Your 3.13 eval job has completed with return code 0.
oopsie
class __a:
def __init__(self):
print("!!!")
class _a__b:
def __init__(self):
print("...")
class _a__a:
def __init__(self):
print("///")
class _b__a:
def __init__(self):
print("???")
class b:
def __init__(self):
c: __a = __a()
b()
Challenge: guess the output without running it
my take is that it should be !!!, it could be, ??? in case I would be very angry
||Weirdly it is ???, and neither IDE from VSCode/PyCharm got it right||
the mangling incident
yep
yeah ||mangling happens to all idents||
||IDE doesn't understand either, VSCode (I think ruff plugin) think the wrong one is correct and JetBrain say neither is correct||
name mangling
this thing broke my brain python interpreter
||???|| obviously
class __b:
def __init__(self):
print("???")
class _a__b:
def __init__(self):
print("...")
class __a__b:
def __init__(self):
print("!!!")
class ___a__b:
def __init__(self):
print("<<<")
class _a:
def __init__(self):
d = __b()
class a:
def __init__(self):
d = __b()
class __a:
def __init__(self):
d = __b()
_a()
a()
__a()
Now guess this output in order
||!.<||
Oh, I see.
||... ... ...||
If the transformed name is longer than 255 characters, implementation-defined truncation may happen.
Great: may happen
I didn't notice it say may, try make 255+ character, and it doesn't truncate
because its not definitely, it is just may
seem like no luck for this ig
Challenge 3:
class ____a:
def __init__(self, recurr: bool = True):
print("...")
if recurr:
__()
class ___a:
def __init__(self, recurr: bool = True):
print("!!!")
if recurr:
__()
class __a:
def __init__(self, recurr: bool = True):
print("???")
if recurr:
__()
class ___a____a:
def __init__(self):
print("<<<")
class _a____a:
def __init__(self):
print(">>>")
class _a__a:
def __init__(self):
print("^^^")
class _:
def __init__(self):
__a(recurr=True)
class __:
def __init__(self):
__a(recurr=False)
class __a__:
def __init__(self):
__a()
_()
Guess the output
||??? ???||
yep
ez
pretty sure I challenged all weirdness of name mangling now lul
mangling is weird af
I don't think so:
https://www.youtube.com/watch?v=0hrEaA3N3lk (from 4:54)
Don't fall for it!
The Zen of Python must not have been invented yet because this feature is confusing, not obvious, implicit, and much more. Private name mangling in Python converts variable usages like __var into _ClassName__var at compile time and there's no warning it's happening until you run into the trap.
― mCoding with James Murphy (ht...
what the fuck
Well, just guess :)
rhats not weird
very strange channel
half wrong
!e ```py
ceweal :3 = type("cereal",(),{})
print(ceweal)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
<class '__main__.cereal'>
- you didn't interpret the syntax in the right way
- my username is valid syntax
- don't bully me :<
thank uu
hey gays ,how to learn infrrd software (IDP)?
gays
real
!e
from ctypes import c_void_p
c_void_p.from_address((q:=id(chr(97)))+40).value = 2970808328977152336
c_void_p.from_address(q+16).value = 8
print('Hallo'[1])
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Python:)
Does that count as esoteric python?
!e
from ctypes import c_void_p
q=lambda x,y:c_void_p.from_address(id(y)+x) or type('',(),{'value':0})
qa=lambda x: q(x, chr(97))
v=[_ for _ in range(64)]
c=[_ for _ in range(64)]
for i in range(16, 128):
for vc in list(v):
if q(vc,chr(13<<3)*i).value%256!=len(chr(13<<3)*i):
v.remove(vc)
for i in range(1,16):
for vc in list(c):
if q(vc,chr(97)+'q'*i).value%256!=97:
c.remove(vc)
v,c = [_[0]for _ in[v,c]]
c_void_p.from_address((q:=id(chr(97)))+c).value = 2970808328977152336
c_void_p.from_address(q+v).value = 8
print('Hallo'[1])
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Python:)
a slightly more portable version
!e
(vct:=__import__('ctypes').c_void_p,q:=lambda x,y:vct.from_address(id(y)+x)or type(str(),(),{'value':0}),v:=[_ for _ in range(((+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))))],c:=[_ for _ in range(64)],list((list((v.remove(vc)if q(vc,chr(((+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(+([]!=())<<+([]!=()))*(((((+([]!=())<<+([]!=()))<<+([]!=()))++([]!=()))<<+([]!=()))+((+([]!=())<<(+([]!=())<<+([]!=())))-+([]!=())))))*i).value%256!=len(chr((((((+([]!=())<<+([]!=()))<<+([]!=()))++([]!=()))<<+([]!=()))+((+([]!=())<<(+([]!=())<<+([]!=())))-+([]!=())))<<(+([]!=())+(+([]!=())<<+([]!=()))))*i)else '',)for vc in list(v)))for i in range(16,128)),list((list((c.remove(vc)if q(vc,chr(97)+'q'*i).value%256!=97 else 0) for vc in list(c)))for i in range(1,16)),setattr(vct.from_address((q:=id(chr(int('1'+'1'+'0')+([]!=()))))+c[0]),'value',2970808328977152336),setattr(vct.from_address(q+v[0]),'value',(+([]!=())<<(+([]!=())+(+([]!=())<<+([]!=()))))))
print("Hello, World!"[4])
# last version, slightly obfuscated, tested on archlinux and windows 11 and python 3.12.7
:white_check_mark: Your 3.12 eval job has completed with return code 0.
Python:)
funny code golf I found: given a filename in standard input, print the length of that file
import sys;print(len(open(sys.argv[1],'rb').read()))
I have a 47
print(sum(map(len,open(input()))))?
thats smart
there is a better method though ;)
also technically doesn't count bytes nvm I removed that requirement
didn't add anything to the challenge
print(len(open(input(),'rb').read()))
or without bytes
print(len(open(input()).read()))
32 or 37
the 32 can be golfed further
how?
bonus challenge: if you know the file is one line long, how can you determine the length of that line?
print(len(next(open(input()))))
i guess -1 if you exclude nl
-2 for our special boy windows
print(len(next(open(input())))
^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
:white_check_mark: Your 3.12 eval job has completed with return code 0.
/home/main.py
!e print(len(next(open("main.py"))))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
33

ok, i manually typed it and it works??
longer than with no restrictions 🤔
c preprocessor is the best and worst thing at the same time
doesn't even work:
#include <stdio.h>
#define ╔
#define ║
#define ═
#define ╚
#define ╗ {
#define ╝ }
╔════════════ int main() ═════════════╗
║ ╔═ for (int i = 0; i < 100; i++) ═╗ ║
║ ║ ╔═════ if (i % 15) ════╗ ║ ║
║ ║ ║ printf("fizzbuzz "); ║ ║ ║
║ ║ ╚══════════════════════╝ ║ ║
║ ║ ╔═ else if (i % 3) ═╗ ║ ║
║ ║ ║ printf("fizz "); ║ ║ ║
║ ║ ╚═══════════════════╝ ║ ║
║ ║ ╔═ else if (i % 5) ═╗ ║ ║
║ ║ ║ printf("buzz "); ║ ║ ║
║ ║ ╚═══════════════════╝ ║ ║
║ ║ ╔═══════ else ══════╗ ║ ║
║ ║ ║ printf("%d ", i); ║ ║ ║
║ ║ ╚═══════════════════╝ ║ ║
║ ╚═════════════════════════════════╝ ║
╚═════════════════════════════════════╝
clang:
g.c:2:9: error: macro name must be an identifier
2 | #define ╔
| ^
g.c:3:9: error: macro name must be an identifier
3 | #define ║
| ^
g.c:4:9: error: macro name must be an identifier
4 | #define ═
| ^
...
gcc:
g.c:2:9: error: macro names must be identifiers
2 | #define ╔
| ^
g.c:3:9: error: macro names must be identifiers
3 | #define ║
| ^
....
c++?
!e
from __future__ import annotations
import inspect
import ast
from collections.abc import Callable
from dataclasses import dataclass
@dataclass(match_args=True, slots=True, frozen=True)
class Result[T]:
value: T = None
is_nothing: bool = False
def __str__(self) -> str:
if self.is_nothing:
return 'Nothing'
return f'Result({self.value})'
def __irshift__[V](self, func: Callable[T, Result[V]]) -> Result[V]:
match res := self:
case Result(is_nothing=True): return Nothing
case Result(is_nothing=False): return func(self.value)
bind = __irshift__
Nothing = Result(is_nothing=True)
def extract_bind_stmt(expr: ast.Expr) -> Result[tuple[str, ast.AST]]:
match expr:
case ast.Expr(
value=ast.Compare(
left=ast.Name(id=name),
ops=[ast.Lt()],
comparators=[ast.UnaryOp(
op=ast.USub(),
operand=value,
)]
)
):
return Result((name, value))
return Nothing
def do(func):
func: ast.FunctionDef = ast.parse(inspect.getsource(func)).body[0]
func_body = func.body
root = ast.Expr(value=None)
rtn_expr = func_body[-1]
curr = root
for expr in func_body[:-1]:
res = extract_bind_stmt(expr)
match res:
case Result(is_nothing=True):
raise ValueError('no support for non binds in do expression yet')
case Result(value=(name, value), is_nothing=False):
curr.value = ast.Call(
func=ast.Attribute(
value=value,
attr='bind',
),
args=[ast.Lambda(
args=ast.arguments(
posonlyargs=[],
args=[ast.arg(arg=name)],
kwonlyargs=[],
kw_defaults=[],
defaults=[],
),
body=ast.Expr(value=None),
)],
keywords=[],
)
curr = curr.value.args[0].body
curr.value = rtn_expr.value
func.body[:] = [ast.Return(value=root.value)]
func.decorator_list.pop()
func.name = 'do_rtn_func'
net = {}
script = compile(ast.unparse(func), '<do>', 'exec')
eval(script, globals(), net)
return net['do_rtn_func']
def try_int(x: str) -> Result[int]:
try:
return Result(int(x))
except ValueError:
return Nothing
def try_add(x: int, y: int) -> Result[int]:
if x + y > 10:
return Nothing
return Result(x + y)
@do
def foo(x, y):
a <- try_int(x)
b <- try_int(y)
c <- try_add(a, b)
Result(c)
if __name__ == '__main__':
print(foo("abc", "5"))
print(foo("5", "abc"))
print(foo("1", "1"))
print(foo("1", "17"))
print(foo("3", "7"))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | Nothing
002 | Nothing
003 | Result(2)
004 | Nothing
005 | Result(10)
there may be a way to hack together a solution to make the context manager work, at least in the same file:
at runtime, when entering do, use inspect to grab the source code, compute the result in the same way as ^, then override variables in globals() with dummy functions so all the <- don't throw errors, but do nothing as well
overriding the return (any expr) bit is much more annoying tho, idk how to do that
and then when you exit the context manager reset all the globals you assigned earlier
!pypi dont I made this tiny library to make messing with context managers easier. You can essentially get the inner code as you described, but then also prevent normal execution of anything inside it.
Basically not much more than this (where raiser is a function that raises an exception, which is then ignored in __exit__)
class dont:
def __enter__(self):
self.frame = sys._getframe().f_back
lines = inspect.getsource(self.frame).split("\n")
start = self.frame.f_lineno
start_indent = indent(lines[start])
stop = next(
i for i in range(start + 1, len(lines)) if indent(lines[i]) < start_indent
)
self.content = textwrap.dedent("\n".join(lines[start:stop])).split("\n")
sys.settrace(raiser)
self.frame.f_trace = raiser
ooh nice
that should be cleaner then the decorator then
because currently the decorator needs the functions used in the function to be defined when it's called
-fextended-identifiers maybe
how come i see things i wanna play with when i'm incapable of it--
why does this print just "Help"?
type(quit).__lt__=print
quit<"Help"
Shouldn't class methods get passed self, so it should print Use quit() or Ctrl-D (i.e. EOF) to exit Help
replacing print with lambda*a:print(*a) does what i would expect it to which is weird
Methods work via the descriptor protocol. Every function made by def or lambda has __get__ that binds self, but built-in functions do not.
built-in functions don't have the __get__?
!e yep
class X:
builtin = print
custom = lambda *a, **k: print(*a, **k)
X().builtin("builtin")
X().custom("custom")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | builtin
002 | <__main__.X object at 0x7f50e5e2f8f0> custom
!e
help(type(print).__get__)
?
:x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 1, in <module>
003 | help(type(print).__get__)
004 | ^^^^^^^^^^^^^^^^^^^
005 | AttributeError: type object 'builtin_function_or_method' has no attribute '__get__'. Did you mean: '__ge__'?
doesnt even have one
that's the point
since it doesn't have a __get__, there is no way the instance gets passed to the function
I thought it may have a dummy one or smth
imagine putting something on builtins.__get__
!e input()
:x: Your 3.12 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 1, in <module>
003 | input()
004 | EOFError: EOF when reading a line
!e print(1)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
1
!e print(__import__('requests').get('https://www.example.com').text)
:x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 1, in <module>
003 | print(__import__('requests').get('https://www.example.com').text)
004 | ^^^^^^^^^^^^^^^^^^^^^^
005 | ModuleNotFoundError: No module named 'requests'
@teal stone Please use #bot-commands for such experiments.
My apologies
Was just trying to see if requests worked before I sent an esoteric code snippet
k='';d,g,z=dir,globals(),(lambda:k);b=d(g['__builtins__']);type(z)(z.__code__.replace(**{a:(2,__import__('zlib').decompress(__import__('base64').b64decode('eNrVWUlPFEEUruru6enZF0ZmAUQcQRE3FB1wO+EfEBNiIrdOOJCYDJlIJFVeKh5N5uJ98Kd48R95NFZPNz2P7nptz/QgcCB+lFVv/eq91wWjPWJTQW1N0AOtbx6+6xFvRRd0hOqnqwbAKYBNgNMAWwBnANaD2NeW9lHWXeca0wY00qocYmE+rvYToNNDBbAni8gpBqPRBJo9VArKEZSSK+hRCmZIaSc8W0ZshmcrAFfHPFtCfJkBuAbwNUR+CYlzBfEL0zUb1OVkeaRPobmMZK+cAI8rpx5jTwPJRhPgFsBzyHocOUnshHgeWW8hsWoh+xemFE8dwQtIfODZ68h6E/FXj8GHOqJXj5FTqGsR2bOI+DgXIxfNBHm/gWC4ZynB2SR5byHxgftvxohnGVlvJch7nPs7P6adC2PKx/I+bkzGxXHkD+3hOtMH4a5qxugmmTMdWUqTU42+T7jB9G2yt8NTzPAlt5WSTaQfVYK9+ISylC9rNIVgZ7Deb7my7FuOrZT0je7PHrBFMd0ZURoE8N23blk5UYTkSI8M14qpWDDqxitnGWHfrhH/9ztBtpzRf1Gz8aoynxlEVxuZW7wpdHAOUn2O31VGeQ3ge8h9XAlHnlNG7FH053zZ993//6o1yQDM24pYP4jmuZDylRrWPA16k3BT3th0j4T0GFFztaCM+mceOjyuQU3DFcd+QbdJn+7p3OqR0JeQFbzlUqpcsx/VCM9cOCstQRXcqCBfCemgPYCJ68kkyUohLeZZlh1MZltkBZHV8LH9RGg8564yeZJbLD3Fym0Na63Z/TU+y0J3eQPxaxngp0jvSiF2pl1dsmd1pOemIspFxPMSUkHyweg4URhNajLaZt/qzgNdSTrv0rDz5uU9Lsifovwpsbz05g0vs9L08uj+1gP24F2Jle1nQvO6rNUVrDAAsfRQJ0bHVvGp5EgdelmQXq7zCquw9CfazxyuTNNfVvGs/82K52B9tUdCMuH+TYS5RaSqtaPskRkpDhn+44PGy3yGVc+NF9H1fSb2TodDW3WiqBkhe5zdgs6O9q45zGsQp/80SFx9eJ905XhsznS/9fXjP5fvRfEqvb1d2thVlJ01Fa7nof1DzQdaP3f49t+vpR8XIvcUkXttXZqZPaPkgBn1vgii/Nw/vYnUFoyVRoxX1xcAR1p3Qi88jikl3yzkXm0gvCj95wqg/hppI7qygVv/UsmdTIy3afiy8gqJVxrJ2QYiv3Oaj4msw7KGdeaCq20fZiun7GzY3whyYRYLMsHrQ9XpZ8DvVWUlglJeRrFPka1G8B3sqkdZ6ILskh1ijLj8WjkP5hE/zEmqmqD94ufvlPAaJcdtxdTYifpKkP9uOR1jl7yXX+i89qVmSw9cdESPyF93kBre')),(None,b[93],*[ord(_)for _ in"EfbTF\x01ux\x10khͫljRʦ7w4A1\x1bg]\x1a[j\x1ea`#|'Y\\/-.)(\n203=:n leycdstropmi_*"[::-1]]),(b[104],d(d)[8]),21,11,(k,k))[i]for i,a in enumerate(_ for _ in d(z.__code__)if _[:2]=='co'and _[3:5]in'arconanlstva'and _[-2:]!='me')}),g,k)(bytecode, password)```
wha
custom bytecode vm
😶
cant send the full thing
what doe sthat even do
too big by like 100 characters lol
looks like malbolge
its just a hello world
oh its just b64
no
i wonder how this works
dms?
yea
exactly
it doesnt implement the descriptor protocol
why y'all acting as it it was obvious? it could've had a dummy one or smth, no, the very slot is not even there, which is not common for magic methods and builtin functions
which is weird
its documented,
haven't read it
built-in functions have built-in methods of a diferent type that do implement the descriptor protocol
ngl to many functions types
yes
methods take a self argument
>>> help(type(type(print).__str__))
Help on class wrapper_descriptor in module builtins:
class wrapper_descriptPython:Python:)r(object)
| Methods defined here:
|
| __call__(self, /, *args, **kwargs)
| Call self as a function.
|
| __get__(self, instance, owner=None, /)
| Return an attribute of instance, which is of type owner.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __reduce__(...)
| Helper for pickle.
|
| __repr__(self, /)
| Return repr(self).
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __Python:Python:)bjclass__
|
| __text_signature__
yeah the best documentation I've ever seen
help() is useful, but it is not the same as actually reading the documentation
by far
theres more to the docs than just the individual objects
and the links wouldnt work, they'd have to format things differently, etc.etc.
lots of work for not much gain (docs.python.org exists) and makes libpython a fair bit bigger
yeah but still itd be nice to have as a start.
they wouldn't neccesarily id be fine with just having the bare autolink stuff in the doc
but it might encourage lsp writers to support it better
im personally not a fan of leaving my editor to go to another website and if you care about the size of doc strings you should run with -OO
esoteric means things that people dont frequently know about
there's a reason it's in #esoteric-python :p
it does sound like a special case though
!e ```py
class A:
a=lambda *a,**k:print(*a,**k)
b=print
c=staticmethod(a)
d=classmethod(a)
foo = A()
print(foo.a); foo.a("normal")
print(foo.b); foo.b("builtin")
print(foo.c); foo.c("staticm")
print(foo.d); foo.d("classm")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | <bound method A.<lambda> of <__main__.A object at 0x7f1a26017da0>>
002 | <__main__.A object at 0x7f1a26017da0> normal
003 | <built-in function print>
004 | builtin
005 | <function A.<lambda> at 0x7f1a26055440>
006 | staticm
007 | <bound method A.<lambda> of <class '__main__.A'>>
008 | <class '__main__.A'> classm
i guess staticmethods and built-ins are special-cased
that only optimises user docstrings??
and asserts but
whatever
and, a lot of editors can read websites
you neednt leave your editor
Not if they're defined correctly, you can also strip them from the binary
Oh hmm didn't know that
Also tbh I only need them in pyi files
afaik they just implement the descriptor protocol
builtins** do?
ah
It probably looks something like: ```python-repl
class MyStaticmethod:
... def init(self, method):
... self.method = method
... def get(self, _obj, _objtype=None):
... return self.method
...
import functools
class MyClassmethod:
... def init(self, method):
... self.method = method
... def get(self, _obj, objtype=None):
... return functools.partial(self.method, objtype)
...
class Foo:
... x = lambda *a: print(a)
... y = MyStaticmethod(x)
... z = MyClassmethod(x)
...
Foo().x("x")
(<main.Foo object at 0x7f454e24e850>, 'x')
Foo().y("y")
('y',)
Foo().z("z")
(<class 'main.Foo'>, 'z')
normal functions, by default, have a __get__() implemented
built-in functions don't
unrelated, but staticmethod implements its own __get__() to override the normal function's, and basically throws away the instance
the logic is that
if an attribute has a __get__(), call it; otherwise, just use the normal value
if A.func is a normal user-defined function (or in this case, any value with the descriptor protocol implemented), then A().func() will do A.func.__get__(...)()
OTOH, if it's a builtin function, then A().func() is simply A.func(A())
Codegolfed bytecode vm I created
The expected output of the code below is the first 20 digits of the fibbonacci sequence
Doesnt work in !e sadly 😦
I knew about the descriptor protocol, the only thing I didnt know is that there were so many special cases about it
how can i use a dataclass but haev the annotations include those from base classes too?
get_type_hints is super slow
this sorta works but not really, and i have to decorate base classes too or they don't get handled properly. if i do decrorate base classes and the parent class, the arg order gets messed up
your varnames dont match up with the nlocals
send the entire thing in dms im interested in dissecting it
which version is this for? the bytecode doesn't make any sense
they wont be stripped from libpython
they would be builtin
Include/pymacro.h lines 112 to 116
#ifdef WITH_DOC_STRINGS
#define PyDoc_STR(str) str
#else
#define PyDoc_STR(str) ""
#endif```
thats a build time option
not a runtime option
ok then use -OO then if you dont care about the ones in the binary
like, do you expect people to double the amount of python installations they have
no this would be silly
?????
that ignores the exact issue i was talking about 🥺
no but i dont expect most people to care about an increase by a few kib
long story short, embedding all of the language documentation in python wouldnt be good
chirk@khqympju:~/dload/cpython/$ du -sb Doc
14361198 Doc
14361198B / (1024 * 1024) = 13.6959056854 MB
granted this is not the best measurement of documentation size, since there are build scripts and such in the Doc/ directory, but still
you can see how maybe 13 megabytes would be a bit much
My goodness! How you understand and get to write those... I have been doing a lot of reading on python. From python doc or automate boring stuff with python. Yet, I can't write nothing or build nothing.. i understand python but when it's time to code or write anything, i become a novice
*MiB
nope! im not using si units
who the hell import inside a function
??
you are not using "true" units
1 MiB = 1024*1024 bytes
1 MB = 1000*1000 bytes
did you not read what i said
.
this is not about si units do you know what si stands for?
you can't just call 10 cm long pencil a 10 m long pencil
its wrong
"système international"
how many times to i have to repeat myself
im not using the si units here
epic strawman 👍
I think most programmers talk about KB/MB/GB/.... refering to KiB/MiB/GiB and most normal use the first bunch of units correctly, I've even read about windows not using the right unit somewhere
somewhere? almost everywhere, windows uses binary base but show decimal units
except for some bare case mostly in control panel or commands
or in the drive's properties if I remember correctly
mac and linux use true units
iirc no
sometimes it's required or helpful
that's is the types module and the util module imports types and that needs something from logging which needs util
imports should be cached anyways so it's not a big deal
"true units"
no units have inherent truth
what you're looking for is "SI units"
do you know difference between correct unit and si unit?