#esoteric-python
1 messages ยท Page 77 of 1
huh didn't know that, what was the drama around it?
well, no drama but discussions were tough as far as I have read from PEP 285
didn't even know Python used to not have booleans
we didn't even have str() as it is in python 3, in python 2
I like how I can't load bugs.python.org for some reason, haha
wait it really is blocked for me

Wait about overriding tuple comparisons?
Make then always return true
Or at least return true if the arguments are (true, false) and (false, true) @marsh void
hey this code is pretty good right? the programming discord didnt like it
from subprocess import *
global USEr_INPUt
USEr_INPUt = input("enter stuff here:" )
def DOthingsHERE():
for X in range(1,5):
for v_V in range(1,5):
for bIrDs in range(1,6):
R = X
hELLO = v_V
BiRdS = bIrDs
print (str(BiRdS)+str(int(str(hELLO)))+str(R))
DOthingsHERE()
subprocess.call([USEr_INPUt], shell = True)```
So it looks like there are maybe patterns in you capitalization - you'll wanna try to limit that as much as possible. Maybe try a language like PowerShell where you can capitalize variables differently each time.
Other than that, it looks solid and in no way incredibly dangerous.
so i need less patterns, gets too predictable
predictable code == bad code
easy for hackers to break
Suggestions: script isn't accessible via the web, what happens if I want to access it on the go. Also you should automatically append 'sudo' to the subprocess arg list, I hate having to retype commands.
Well this is a windows environment, but I could have our Networks root password stored and prints so they don't forget it
And on the front of making it not accessible on the go, I can open up ports so you could use psexec to run it remotely
Maybe give it a captcha, so hackers don't use it.
That's crazy, I'll just put a input that doesn't let you continue unless you type that you won't be bad
sys.stdin = io.StringIO(r0oTpAs$w0rD) might do it
Test = input(" are you bad? >>>")
If test != "":
Continue()
Else:
Continue()```
I think that would work without being too strict
Please publish this on pypi as REEEEEEEcaptcha
I'm worried about security though if I put it out to the masses wouldn't that be a vulnerability
I think you just have to dispute any CVEs people file for and you'll be okay
Oh okay in all reality they user input check of are you bad should really catch any bad doers
we should write a white paper this is brilliant
I Don't know that can cover the complexity of this though
Maybe make a catchy tik tok series on it, easier to remember and fun to learn
I don't want to have to dispute CVEs though, so I'll import random and use randomint(10000,100000000) to generate all my variable names
More secure
The less words the better
Code == secure
Passwords == secure
Secure == more character and no words.
So my code needs more characters generated randomly and no words when possible
Sounds like Pyth
yeah I agree
pyth has a load of predefined variables that don't really make any sense
How can I make this even less obvious?
https://gitlab.com/CrunchBangDev/Conf/blob/master/conf/conf.py#L142
I feel like that's almost as far as I can go with confusing string formatting, but I'm really wondering if there's a good way to bury the easter egg's existence even deeper somehow
The main reason I published this code in the first place is because the idea of getting this into other people's programs delights me
@next mist just hash variable names if ur going through all of that
is there an easy way to only allow instantiation of a class inside one of its classmethods?
and in a way that is done transparently unlike https://stackoverflow.com/a/42735965 where the classmethod has to be defined inside the metaclass' __new__
What's wrong with raising an exception in __init__
then you cant instantiate it anywhere
the point is youd be able to define everything as usual i.e.
class SomeClass:
def __init__(self):
self.thing = 0
self.other_thing = 0
@classmethod
def from_int(cls, value: int):
result = cls()
result.thing = value
return result
@classmethod
def from_float(cls, value: float):
result = cls()
result.other_thing = value
return result
then just drop in a metaclass or a decorator or something and prevent new_object = SomeClass() outside of the classmethods.
im working on an approach rn thatll step through the stack and check each caller but it's a bit difficult
almost done. now just need a reliable way to check whether a method is a classmethod.
import inspect
from functools import wraps
def callers():
for frame_info in inspect.stack()[2:]: # type: inspect.FrameInfo
frame = frame_info.frame
name = frame_info.function
yield name, frame.f_code
def no_init(cls: type):
old_init = getattr(
cls, '__init__',
lambda self, *args, **kwargs: None
)
@wraps(old_init)
def new_init(self, *args, **kwargs):
for name, code in callers():
try:
method: callable = getattr(cls, name)
except AttributeError:
pass
else:
if method.__code__ == code:
if (
inspect.ismethod(method) and
method.__self__ is cls
):
break
else:
raise RuntimeError(
'Instantiate this class using one of the classmethods.'
)
old_init(self, *args, **kwargs)
setattr(cls, '__init__', new_init)
return cls
@no_init
class Test:
def __init__(self):
print('ayy')
@classmethod
def from_int(cls):
return cls()
Test.from_int()
Test()
done
i spent too long trying to figure out how to get the function object directly, then realised you could just compare the __code__
actually that should be method.__code__ is code probably, just to be extra sure
the traceback isn't very good though
Traceback (most recent call last):
File "C:/Users/admin/Documents/Projects/shared_memory/scrap.py", line 137, in <module>
Test()
File "C:/Users/admin/Documents/Projects/shared_memory/scrap.py", line 116, in new_init
'Instantiate this class using one of the classmethods.'
RuntimeError: Instantiate this class using one of the classmethods.
would rather eliminate that last bit with new_init
but i suppose it'll have to do
method: callable = getattr(cls, name) oh yeah, the callable here doesnt make any sense. forgot to take it out.
hey guys
what are you doing
anyone knows how to obtain a specific type from a header file in cpython with ctypes
in Python-ast.h there is a struct named _expr/expr_ty and it contains all expressions
i want to get that struct without redefining everyting inside
anyone knows a way to do that
What use is there for python3.6+'s __set_name__ descriptor method? https://docs.python.org/3/reference/datamodel.html#object.__set_name__
PEP 487, I think
import weakref
class WeakAttribute:
def __get__(self, instance, owner):
return instance.__dict__[self.name]()
def __set__(self, instance, value):
instance.__dict__[self.name] = weakref.ref(value)
# this is the new initializer:
def __set_name__(self, owner, name):
self.name = name
class TreeNode:
parent = WeakAttribute()
def __init__(self, parent):
self.parent = parent
ok yeah that is a cool use
0xfor 0 still looks weird lol
oh yeah @brazen geyser i was gonna see if i could get a really fucking chunky variable name going on, wasn't i?
what broke it? was it a memory error?
yep, memory error on trying a trillion
memory errors are easy to throw hardware at, overflow errors are not.
was going up in powers of ten
@brazen geyser was not a good idea
allocated 500GB to swap and managed 10,000,000,000. then my HDD began sounding like it was having an aneurysm lmao
taking breaking python to the hardware level? ๐
one time occurence or always on the same array?
lemme check. i gave up after that haha
if somebody can manage to run my tic-tac-toe code, i will be massively impressed
I'm not sure I want to after reading the previous messages ๐
hm. seems to work now. maybe i just had something like chrome with 200 tabs eating all my ram...
@brisk zenith how much does it take?
how much what?
ram
sanity
i have no idea
or whats the limiting factor?
i tried running it with 800GB of swap once and the python interpreter segfaulted
it's a 400MB script
just tictactoe
are you calculating all possible endings/??!?!?
indeed.
was that script created by you or a (non-you) machine
i made a script to write the script
๐ ast.dump(ast.parse('0xfor 0', mode='eval').body)
'BoolOp(op=Or(), values=[Num(n=15), Num(n=0)])'
nice
@brisk zenith, it looks like you tried to attach a file type we don't allow. Feel free to ask in #community-meta if you think this is a mistake.
at least that ๐ Would want your editor if you had a 400mb file
this is a mistake!
I'd tell you to use paste but...
just create many pastes hahaha
what kind of file is it @brisk zenith
@edgy kelp you can use https://send.firefox.com or https://send.lambda.dance (the latter has higher upload limits)
it's a 400MB .py file. when compressed, it is only 7MB
text
@dense spire, it looks like you tried to attach a file type we don't allow. Feel free to ask in #community-meta if you think this is a mistake.
lol
yikes!
guess I'm not big enough staffer.
that sucks.
just put it somewhere and link it?
what a lawbreaker
you know what, it's fine. i'll find the script which generates the tictactoe script and stick it in a paste. :D
thanks for trying anyways lemon, much appreciated
I always find it surprising how fast files can get big when it's just some simple text generated by a program
fuck the generation script was on paste.seph.club. @vague gust 0/10 wouldn't use paste.seph.club ever again.
what is wrong with paste.seph.club
the url not looking like an url would be the first thing ๐
that is paste.pydis you are looking for isn'tt it
hm odd
https://github.com/iomintz/python-snippets/blob/master/list_append_assignment_target.py
Another dumb use caseโcopying a list:
l = [1,2,3]
copy = DumbList()
for copy.append in l:
pass
Someone just showed me that the Python 3.8 := operator provides a new way of coding a C-style for loop and I'm sad now.
show me
while i := locals().get('i', 100) - 1:
print(i)
while (i := locals().get('i', 0) + 1) < 100:
print(i)
lololo (technically you need to del i after the loop -- haven't found a cleaner way)
a C-style for loop that requires the un-declaration of a variable ๐ฆ
is there a jsfuck equivalent of python
ye
@rare juniper don't mind the del i at the endโpython has never had loop-local vars
there's also this which i quite like https://onelinepy.herokuapp.com/
challenge: how many characters are needed for python to be turing complete
without using eval or exec
while:=-1 is probably TC
I wonder if that can be improved
__import__("os").remove(__file__)```
@gilded orchid is that even valid syntax?
I'm saying how many distinct characters are needed
I was just listing the characters
(also I just realised I forgot newlines)
oh right okay. yeah, i can see that as being turing complete.
I think that's pretty optimal
since you need to be able to do infinite loops
(which you can't do without using way more characters with for)
unless maybe you could use recursive functions somehow
but even then you'd need def(): at a minimun, which is the same number of chars as while:
how is while:=-1 turing complete. im not seein it.
it's not on its own, but using any amount of just those characters is turing complete
right thats how i mean
you can basically make something which works like brainfuck
which is itself turing complete
any brainfuck program can be translated into python just by using the characters in while:=-1 and newlines.
making a translator from brainfuck to a python script which uses only those characters would be quite fun
can't forget the classic list comprehension interpreter: https://ideone.com/zrQWwa
feels more beautiful because it's one line
christ
jesus christ
also yeah, I was thinking of brainfuck for those chars
cells can be variables using the letters and =
+ can be var=var--1
- can be var=var-1
[ can be while var: and then indenting 1 more for next lines
] can be removing 1 indentation
(< and > obviously aren't needed due to how we're doing our vars)
why doesn't this work [*range(int(1E23))]
or at least, why does it output the error it outputs
because 99999999999999991611392 is bigger than 18446744073709551616
but can't they have any length? Works alone in a list
18446744073709551616 is the limit for floats I think
and when you do 1e23 it's a float that's bigger then that
the 1E23 is the only float there and don't think that's producing the problem as it works with ints after that
and setting a large step converts normally
for example [*range(0, int(1E23), int(1E21))]
limit for floats is in the order of 1e308
at least, python's double-precision floats
It's a problem with the range function.
I think it's because 1e23 > sys.maxsize
range is implemented in C
Python ints can be arbitrary size, but range converts its argument to a C int, which can't.
shouldn't [*range(0, int(1E23), int(1E21))] break too then?
Oh, right.
it may be the Py_ssize_t which holds the length of the list
although actually
you'd get a memoryerror before an overflowerror there
len definitely breaks with ranges that are too big.
I had to reimplement it at one point.
Don't ask.
why? :D
This is interesting, but why is range working in this way? Seems like a bug?
I don't expect it yields c integers.
With numbers that big I doubt it's a bug, just an implementation limit, but I do wonder where it breaks so that it ends with an overflow right away
I wonder as well.
i'll investigate tomorrow if you don't figure it out by then :D
I was writing a function to combine itertools.product with random.sample, designed to work with really large samples. In order to make it not need to generate every Cartesian product, I sample integers to be efficient. random.sample uses a more efficient method for range objects than any other collection, but still uses len. Thankfully, it's pure python, so I just copied and adjusted the code to find the length of ranges by simple arithmetic instead.
@gilded orchid Wouldn't space also be needed? Or is that implied?
https://discordapp.com/channels/267624335836053506/303934982764625920/639929009928536074 if anybody wants to take a crack at speeding this up i can pay you in at least 5 exposure and 1 gratitude
maybe a marshmallow
An alternative approach:
I had it mostly written
then it came to a screeching halt when I couldn't determine if a function was a classmethod
!e ```python
class A:
@classmethod
def b(): pass
print(isinstance(A.b, classmethod))
@distant wave :white_check_mark: Your eval job has completed with return code 0.
False
-.-
yep, inspect.ismethod + method.__self__ is cls seems to be solid though
Here's an alternate solution:
!e ```python
import inspect
from functools import wraps
def wrap_cls(cls):
def primary(cls_method):
@wraps(cls_method)
def wrapper(*args, **kwargs):
t = cls.init
cls.init = cls._old_init
res = cls_method(*args, **kwargs)
cls.init = t
return res
return wrapper
return primary
def error():
raise ValueError("Don't.")
def classmethods_only(cls):
cls._old_init = cls.init
cls.init = lambda self: error()
for attr in dir(cls):
method = getattr(cls, attr)
if callable(method) and inspect.ismethod(method) and method.self is cls:
setattr(cls, attr, wrap_cls(cls)(method))
return cls
@classmethods_only
class Test(object):
def init(self):
print("test")
@classmethod
def special_init(cls):
return cls()
def do_a_thing(self):
print(self)
print(Test.special_init())
print(Test())
@distant wave :x: Your eval job has completed with return code 1.
001 | test
002 | <__main__.Test object at 0x7f51cf222510>
003 | Traceback (most recent call last):
004 | File "<string>", line 47, in <module>
005 | File "<string>", line 25, in <lambda>
006 | File "<string>", line 20, in error
007 | ValueError: Don't.
instantiation without metaclass: 0.000424896000000001
instantiation with metaclass: 0.680442438
instantiation with classmethods_only: 0.001014326999999926
Do note that my solution does not support the following:
class A:
def __init__(self): pass
A.b = classmethod(lambda cls: cls())
Although if you do so, you could always call A = classmethods_only(A) after all the adjustments
I smell an alternate solution that's cleaner and faster, but I'm not going to write it
I suspect you can overwrite __self__ inside the classmethod decorated function
might have some threadsafety issues due to the swapping in/out of __init__ but that's a problem for another time
overwriting __self__ sounds like the darkest of dark magics
I mean, this code up there that swaps out __init__ whenever you call a classmethod is not what you'd call white magic >.>
tru ๐
Imo, best of cases would be a custom decorator that mimics @classmethod
With the proxy with a new init, or w/e
i hear ya
great work ๐
I have an evil idea
import inspect
from functools import wraps
def wrap_cls(cls, old_init):
def primary(cls_method):
@wraps(cls_method)
def wrapper(*args, **kwargs):
t = cls.__init__
cls.__init__ = old_init
res = cls_method(*args, **kwargs)
cls.__init__ = t
return res
return wrapper
return primary
def error():
raise ValueError("Don't.")
def classmethods_only(cls):
old_init = cls.__init__
cls.__init__ = lambda self: error()
for attr in dir(cls):
method = getattr(cls, attr)
if callable(method) and inspect.ismethod(method) and method.__self__ is cls:
setattr(cls, attr, wrap_cls(cls, old_init)(method))
return cls
@classmethods_only
class Test(object):
def __init__(self):
print("test")
@classmethod
def special_init(cls):
return cls()
def do_a_thing(self):
print(self)
i worry about the potential implications for super()
Now we bind the old init function into a functions namespace, so it's not lurking anywhere at all, mwhahaha
hm
What about it?
not sure, but i feel like something about it's bound to become royally fucked up
It was always special
potentially incorrect mro
Oh, not in this case at least
we're not touching the MRO, just the definitions of the current class
We're just overwriting the __init__ attribute at definition time
i like the name classmethods_only much better btw
glad you do :P
@brazen geyser I love #esoteric-python, everything here seems cool, but I don't understand a word of your code :p (like the last snippet you sent on #303934982764625920)
๐ well if there are parts you want me to explain let me know @thin trout
Okay I think I'm gonna take my breakfast, think a bit about it and I will probably have dozen of question about it ๐. I really appreciate the offer
juanita
how to obtain a specific type from a header file in cpython with ctypes
in Python-ast.h there is a struct named _expr/expr_ty and it contains all expressions
i want to get that struct without redefining everyting inside
anyone knows a way to do that
@steep mauve why do you not want to use the ast module?
auscompgeek Python-ast.c doesnt expose all of its API to ast module
also i need that struct not a ast.expr class
@steep mauve can you explain what you want to do?
there are internal functions used for AST with PyAST_ prefix
what i want is using them with ctypes
my_function = ctypes.pythonapi.PyAST_foobar
๐ค
but i need to set argtype to expr_ty / _expr struct defined in Python-ast.h
sure
pseudocode works too
import ctypes
myfunction = ctypes.pythonapi._PyAST_Optimize
myfunction.argtypes = [get_struct("mod_ty", "Python-ast.h"), ...]
get_struct(struct_name: str, header_file: PathLike) -> ctypes.Struct
๐ค
I think you'd have to either parse the header and dynamically recreate the struct in python as ctypes.Structure, or just manually create a ctypes.Structure
as long as it's the same format it should work just fine
it is kind a big struct (expr_ty)
it is union of all ast expression nodes
with all fields
๐ฆ
i was doing the spiral kata on codewars and i had a tuple of directions ((0, 1), (1, 0), (0, -1), (-1, 0)) and a variable direction that i would index the tuple with, and i kept doing the standard direction = (direction + 1) % 4 thing that one usually does, but then i thought i should just make a modtuple class:
class modtuple(tuple):
def __getitem__(self, key):
if isinstance(key, int):
return super().__getitem__(key % len(self))
if isinstance(key, slice):
start = key.start % len(self)
stop = key.stop % len(self)
if start < stop:
return super().__getitem__(slice(start, stop))
return super().__getitem__(slice(start, None)) + super().__getitem__(slice(None, stop))
but this only covers the cases i needed, how about a full fledged __getitem__ for this type of tuple
i realize that itertools has cycle, but i needed to index the tuple to look ahead, without calling next a bunch of times needlessly
In [197]: a = modtuple((1,2,3,4,5,6,7,8))
In [198]: a[10]
Out[198]: 3
In [199]: a[10:5]
Out[199]: (3, 4, 5)
In [200]: a[5:2]
Out[200]: (6, 7, 8, 1, 2)
sample output
width, height = 8,6
list(dict.fromkeys([point for dir_zip in zip(*(t(width, height)+[[(1,)]] for t in map(lambda p,q,q1,r,s: lambda w, h: [list(zip(*(map(q1(h), ex[::q]), [r(w,h,a)] * len(ex))[::s])) for a, ex in enumerate((lambda x: [range(a, b) for a, b in zip(range(x), range(x, -1, -1)) if len(range(a, b))])((h if s < 0 else w) - p))], (0,1,1,2), (1,1,-1,1), ( lambda x:lambda y:y, lambda h: lambda u: u + 1, lambda x:lambda y:y, lambda h: lambda u: h - u - 2 ), ( lambda w, h, x: x, lambda w, h, x: w - 1 - x, lambda w, h, x: h - 1 - x, lambda w,h, x: x ), (1,-1,1,-1) ))) for point_l in dir_zip for point in point_l if len(point) > 1]))
who says programmers don't know how to have fun
>>> what_are_you_doing_in_my_swamp = q("what_are_you_doing_in_my_swamp", "get out me swamp")
>>> what_are_you_doing_in_my_swamp
Use what_are_you_doing_in_my_swamp() or get out me swamp to exit
>>> type(what_are_you_doing_in_my_swamp)
<class '_sitebuiltins.Quitter'>
>>>
i hadn't thought about the exit message's implication, but it really is just an object that exists and has a repr
why would there even be a constructor that lets you provide a different set of strings
maybe you could use it for international purposes
but it still has the words "Use" and "or" hardcoded in so good luck using that for translation
I believe it's so different applications can provide different names and hotkeys for the quitter.
that's oddly specific for a dedicated constructor
especially when you can just
>>> exit = type("quitter 2 electric boogaloo",(object,),{"__repr__":lambda s:"exit is a function dummy","__call__":lambda s:__import__("sys").exit()})()
>>> exit
exit is a function dummy
>>> exit()
Ugh, that looks like the sort of thing that belongs in this channel.
well there's exit and quit ```py
exit
Use exit() or Ctrl-Z plus Return to exit
quit
Use quit() or Ctrl-Z plus Return to exit```
that'd explain the name part
since python makes two of them
and the other part is probably platform dependent
based on how whatever you're running that on is a different key combo
understandable
hey guys, someone posted a question from a contest in one of the help channels and i found it quite fun, so here it is:
write a function that finds out if a number is a 'vampire number': https://en.wikipedia.org/wiki/Vampire_number
it should be as fast as possible
they said you could even win discord nitro if you win!
here is the link with some more explanations:
https://github.com/albertopoljak/tortoise-discord-halloween-coding-event
i used this number to benchmark because all the examples they give are finished too fast.
24959017348650
in .2 seconds
is there something better than multiplying all combinations of half its digits
...or i guess you just run over permutations and split that in half?
i calculated the factors of the number with len num_digits/2 and then checked those
its a lot faster for large numbers
but not so much for small ones
i think
i'm making a multiset combination function
cause i can't find one in python
weird
nah, multiset combinations is gonna be the fastest
you only have to generate half of them too
can you send me the function if you come up with one?
i'll put it up
I got it in .5s using permutations, but different machines, so the numbers are meaningless
Moving from this theme, is it possible to create custom traceback message?
File "<stdin>", line 1, in <module>
ValueError: Hello``` at which point do you want the custom message?
@zealous widget and hows it going?
why are they called vampire numbers
they have 2 fangs
@proper vault I wanna show custom stuff in the traceback lol
Traceback (oh hey it is custom):
Oops! Some error occured...
ValueError: Hello```
Something like this

Thinking ASCII control characters in the error message may get you somewhere
you can do this quite simply
Or just with_traceback but I need to instantiate <class 'traceback'> or something
def is_number_small(x):
y = int(x*1.0)
return x is y
Hi, I would like to have an information, in the panda 3D engine, they would like to change the variable tp_dict to check for some typing. But in the documentation says that it's bad to tamper with tp_dict and they don't say why. Does someone know why using tp_dict is bad?
Btw, the docs about tp_dict is here: https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_dict
@proper vault that's cool! You can save a few characters and a temporary variable:
def is_number_small(x):
return x is x*1
after generating multiset combinations, i realize i'll also need multiset permutations and i'll have to handle special cases where 0 is at the beginning of a permutation
my code is quite lengthy already, problem is trickier than it seems if you want to do it efficiently
I did iterators
@marsh void ```py
import traceback, sys, colorama, termcolor
colorama.init()
def excepthook(ext, exc, tb):
tb_list = traceback.format_exception(ext, exc, tb)
tb_list[0] = tb_list[0].replace('Traceback', termcolor.colored('Traceback', 'blue', attrs=['bold']))
if 'File' in tb_list[0]:
tb_list[0] = termcolor.colored(tb_list[0], 'blue', attrs=['bold'])
for line in range(len(tb_list[1:-1])):
tb_list[line+1] = termcolor.colored(tb_list[line+1], 'blue')
tb_list[-1] = tb_list[-1].replace(ext.name, termcolor.colored(ext.name, 'red', attrs=['bold']))
tb_list[-1] = tb_list[-1].replace(exc.args[0], termcolor.colored(exc.args[0], 'yellow', attrs=['bold']))
print(*tb_list, end='')
sys.excepthook = excepthook``` i saw you were asking about custom exceptions, this code adds colors to them
Nice, even better look than IPython's implementation
There's a module colored-traceback on PyPi too
On the topic of excepthooks I dug up this script I made that lets you type bare words (doesn't work within functions though)
import sys, traceback
def excepthook(e_type, value, e_traceback):
if e_type is SyntaxError:
bare_words = traceback.format_exception(e_type, value, e_traceback)[-3].strip()
print(bare_words.upper())
else:
sys.__excepthook__(e_type, value, e_traceback)
sys.excepthook = excepthook
exec("very useful thing")
Do we know of ways to abuse sys.settrace yet?
I believe one of the challenges on GitHub, specifically the Maybe one, had a submission using it.
import sys,random
m='Maybe'
def t(f,e,a):
# 3.7 ONLY: f.f_trace_opcodes=True
if e=='call':
c=f.f_code
for i,o in enumerate(c.co_code[::2]):
x=c.co_code[i*2+1]
if o in b'Z[ab'and c.co_names[x]==m or o in b'}~'and c.co_varnames[x]==m:exit()
f.f_locals[m]=bool(random.choice([1,0]))
return t
sys.settrace(t)```
cool
not sure thats the word ๐
import random
def maybe(*a):
return random.choice([any, all])([*a])```How can I make this less chars? Aside from renaming the function to like `m`
import random
def maybe(*a):
return [any, all][random.randint(0,1)]([*a])```
dont know if thats shorter
maybe=lambda*a:random.choice((any,all))([*a])
why a tuple instead of a list here?
No real reason. Just something I use by default because it's not going to be mutated
the question should be why a list instead of a tuple ๐
My question though is why can't you use starred expressions with tuples
>>> (*range(5),)
(0, 1, 2, 3, 4)
it also works without the parenthses but in your case the tuple takes the parentheses around like its own I think
Yeah no I just had a brainfart
Today I learned:
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> a[:0] = a # Insert (a copy of) itself at the beginning
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
wow cool
I prefer a[0:0] = a because it looks like googly eyes
maybe=lambda*a:random.choice((any,all))([*a])
you can passaby itself here
so maybe=lambda*a:random.choice((any,all))(a)
Ah true
How random does it need to be?
Do you have a shorter char idea? Hopefully more random than this https://xkcd.com/221/ lol
I've used something like id(a)&8>0 in the past.
That gives 0 or 1
It's implementation dependent.
how bout just id(a)&1
No, I tried that
I think the lowest bits were always unset because it's byte-aligned
huh
TIL
>>> bin(id([1,2,3]))
'0b10110111111111101000011100011010110001000'
>>> bin(id([1,2,3]))
'0b10110111111111101000011100011011010001000'
>>> bin(id([1,2,3]))
'0b10110111111111101000001011010011001001000'
>>> bin(id([1,2,3]))
'0b10110111111111101000001111010111101001000'
>>> bin(id([1,2,3]))
'0b10110111111111101000011100011000100001000'
>>> bin(id([1,2,3]))
'0b10110111111111101000011100000110001001000'
>>>
highest bits seem to be pretty much always the same as well
oh yeah but then again thatd make sense as the id count goes up
oops ๐คฆ
Challenge: create Pyth's infinite_iterator function, that takes a number and endlessly iterates incrementing the number each time, eg:
for i in infinite_iterator(7):
print(i)
will start with 7 and endlessly output nubers adding 1 each time
(I don't really know how'd you do this, and maybe it'll be really easy)
wouldnt that just be a simple generator?
def infinite_iterator(n):
while True:
yield n
n += 1
looks like there's this too
https://docs.python.org/2/library/itertools.html#itertools.count
oh yeah wow I'm bad
@gilded orchid this does it with the new walrus py (lambda n,y=[]:map(lambda x:(y.append(x+1),y[-1])[1],(y:=y or [n])))
(lambda n:iter(lambda l=[n]:(l.append(l[0]+1),l.pop(0))[1],''))``` and this does it by abusing iter
abusing both
lambda n:((n,n:=n+1)[0] for _ in iter(int,1))
I love that iter(int, 1) lol
i think its the smallest infinite iterator
Why do you have (n,n:=n+1)[0]? n:=n+1 works by itself
infinite_iterator = (lambda n:map(lambda l:l[0],enumerate(iter(int,1),n)))``` another way to do it
I can't test this, but can't you do n or n:=n+1 instead of (n,n:=n+1)[0]
(to save 1 byte)
@brazen geyser
think thatll short circuit
the n:=n+1 wouldnt be calculated
yep
comes up as cannot use named assignment with operator for me
@gilded orchid itertools.count I win
with some parentheses around n:=n+1 thatll work i think
oh ok
oh yeah
n:=n+1 is gonna be computed first
so nevermind
>>> 1 and 2
2
>>> 3 and 1
1
>>>
seems to always return the rhs
Wait I still don't get why it doesn't iterate though
which one?
the one with and
just 7, any number
infinite_iterator = lambda n:(i for i,_ in enumerate(iter(int,1), n))``` this works too
and returns the left if it's false and the right if the left is ture
>>> v = lambda n:((n:=n+1) and n for _ in iter(int,1))
>>> k = v(7)
>>> next(k)
8
>>> next(k)
9
>>> next(k)
10
>>> next(k)
11
>>>
@lament ibex
>>> 0 and 'hello'
0
>>> '' and 'hello'
''
>>> 4 and 'hello'
'hello'
>>> 4 and 'goodbye'
'goodbye'```
nevermind I did a stupid with the brackets
another challenge: make is so you can index ints
like 1[1]?
(eg: 4522[1] would be 5)
lel ๐
it's worse if it gets you 2.3 docs where you can't just click to get to the newer
"what's new: sets" https://docs.python.org/2.3/whatsnew/node2.html
>>> class IndexableInt(int):
def __getitem__(self, item):
return int(str(self)[item])
>>> IndexableInt(12)[1]
2
>>>
does this count @gilded orchid
nah it's lame. i take it back.
it shouldnt count
I found an evil library that does this
>>> from forbiddenfruit import curse
>>> def intindex(self, x):
... return int(str(self)[x])
...
>>> curse(int, "__getitem__", intindex)
>>> 1234[2]
3
>>>
yeah forbiddenfruit is a thing
this is amazing why haven't I heard of it earlier
so many great methods I can add to built-ins now yayh
>>> from forbiddenfruit import curse
>>> def intiter(self):
yield from range(self)
>>> curse(int, '__iter__', intiter)
>>> for i in 3:
print(i)
Traceback (most recent call last):
File "<pyshell#285>", line 1, in <module>
for i in 3:
TypeError: 'int' object is not iterable
>>>
ffs
What do you mean by patched, it was working before?
when i saw your example i got my hopes up that it would work now
but i think __iter__ might be a special case so it might take some extra work to get going
>>> class Test:
def __iter__(self):
yield from ()
>>> iter(Test())
<generator object Test.__iter__ at 0x0000016FFD5394C8>
>>>
from ctypes import*
d=(v:=c_void_p*3)()
d[1]=cast(CFUNCTYPE(p:=py_object,p,p)(lambda s,i:int(str(s)[i])),v)
(v*52).from_address(id(int))[14]=cast(d,v)```
chronos@localhost ~ $ python
Python 3.8.0 (default, Oct 14 2019, 20:32:20)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from forbiddenfruit import curse
>>> curse(int,'__getitem__', lambda self, index:str(self)[index])
>>> 100[0]
'1'
>>> 100[3]
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 237, in 'calling callback function'
File "/usr/local/lib/python3.8/site-packages/forbiddenfruit/__init__.py", line 359, in wrapper
return func(*args, **kwargs)
File "<stdin>", line 1, in <lambda>
IndexError: string index out of range
Segmentation fault (core dumped)
chronos@localhost ~ $ ``` so forbiddenfruit works in 3.8. but python doesnt like exceptions in cursed methods
@lament ibex makes ints indexable
no libraries required except ctypes
also it's python 3.8
oh wait actually we messed it up
from ctypes import*
d=((v:=c_void_p)*3)()
d[1]=cast(CFUNCTYPE(p:=py_object,p,p)(lambda s,i:int(str(s)[i])),v)
(v*52).from_address(id(int))[14]=cast(d,v)```
there
slices work too ```py
from ctypes import*
d=((v:=c_void_p)3)()
d[1]=cast(CFUNCTYPE(p:=py_object,p,p)(lambda s,i:int(str(s)[i])),v)
(v52).from_address(id(int))[14]=cast(d,v)
125[1]
2
12345[2:]
<stdin>:1: SyntaxWarning: 'int' object is not subscriptable; perhaps you missed a comma?
345```
it doesn't work if it's out of range though
>>> 0[4]
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 237, in 'calling callback function'
File "<stdin>", line 1, in <lambda>
IndexError: string index out of range```
then segfault
lmao love that the warning comes up
weird that the syntax warning doesnt come up unless youre slicing
also how do you know the index on the c_void_p array?
@sick hound
@rugged sparrow docs https://docs.python.org/3/c-api/typeobj.html
@lament ibex to readable. try this!:
import math
from forbiddenfruit import curse
curse(int, {}.__getitem__.__name__, lambda self, x: [(self//(10**i))%10 for i in range(int(math.log10(self)+1)-1,-1,-1)][x])
146[1]
Out[5]: 4```
"tp slots" heh
I really want to get around to understanding this ctypes magic
oops. had some spaces in there ๐
lol
Can someone get iter working with that ctypes wizardry, I'd love to see it working
Random question, and not sure where to ask this but does anyone know of any entertaining (esoteric) Python talks? I'm thinking talks similar to Wat, PowerPoint turing machine/fractals and so on.
https://www.youtube.com/watch?v=pkCLMl0e_0k how about this one @lament ibex
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
David Beazley - Lambda Calculus from the Ground Up - PyCon 2019
Thanks I'll have a look
is there a faster hacky way to calculate int(log2(value))?
found it. int.bit_length - 1
though not hacky at all of course
@marsh void
Yeah
plus uhm, those _fields_ like damn xdd
And yeah that stuff is only CPython as far as I get it
seems like you cannot curse __call__
not with forbidden fruit
>>> from ctypes import*
>>> (c_void_p*52).from_address(id(int))[16]=cast(CFUNCTYPE(py_object,py_object,py_object,c_void_p)(lambda s,*_:s),c_void_p)
>>> 5()
<stdin>:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
5```
lmao
import ctypes
from forbiddenfruit import curse
class refStruct(ctypes.Structure):
_fields_ = [('refcnt', ctypes.c_long)]
def getRefStruct(obj):
return refStruct.from_address(id(obj))
def getPyObj(adr):
return ctypes.py_object.from_address(adr)
def __setitem__(self, index, val):
accindex = len(self) + index if index < 0 else index
if accindex > (len(self) - 1):
ctypes.pythonapi.PyErr_SetString(ctypes.py_object(IndexError), b'tuple index out of range')
return -1
else:
getRefStruct(self[accindex]).refcnt -= 1
getRefStruct(val).refcnt += 1
getPyObj(id(self) + 24 + accindex * 8).value = val
return 0
curse(tuple, '__setitem__', __setitem__)```
@sick hound any idea why this doesnt set an error properly?
>>> x = (0,)
>>> x[1] = 1
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 237, in 'calling callback function'
File "/usr/local/lib/python3.8/site-packages/forbiddenfruit/__init__.py", line 359, in wrapper
return func(*args, **kwargs)
File "<string>", line 16, in __setitem__
IndexError: tuple index out of range
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: error return without exception set
>>> ```
python might be messing with the error?
anywhere I can read up on how to do the ctypes hackery?
cpython docs
https://docs.python.org/3/c-api/typeobj.html this page is useful for messing with types
generally you'll want to use the id of whatever you want to edit as an address
*Mostly in CPython.
@zealous widget
!e ```py
from random import choices
from string import ascii_uppercase, digits
print('-'.join(['{}' * 4] * 4).format(*choices(ascii_uppercase + digits, k=16)))
@crystal mica :white_check_mark: Your eval job has completed with return code 0.
TXVW-TQZC-KZHH-JSSR
print(*("".join(choices(string.ascii_uppercase,k=4))for _ in"."*4),sep="-")
did i save any bytes
@zealous widget โ.โ*4 is shorter than โ....โ
one byte, nice
Why string. for ascii_uppercase, yet no random?
because of my imports
whenever i import choice or choices it's almost always from random import choice, choices
@zealous widget why not use py [*map(chr,range(65,91))] instead of string.ascii_uppercase
gross
๐
i dont think you have to unpack it to pass it to choices
i thought it unpacked it itself
>>> choices([*map(chr,range(65,91))],k=4)
['A', 'Y', 'C', 'T']
>>> choices(map(chr,range(65,91)),k=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/random.py", line 394, in choices
n = len(population)
TypeError: object of type 'map' has no len()
>>> ```
damn, choices is bugged, i'm writing my senator
print(*("".join(__import__('random').choices([*map(chr,range(65,91))],k=4))for _ in"."*4),sep="-")```
@zealous widget i think thats as small as i can get it
I have a new definition of dangerous people on the internet now
"People in #esoteric-python"
haha
just wait till tomorrow when im actually awake. cause i want to try and get it smaller
all my thinking is on a different project
@crystal mica i wrote code earlier today that makes tuples mutable like x[0] = 1
still gets a weird SystemError i need to debug before i oneline it
a=__import__('random').choices([*map(chr,range(65,91))],k=19)
a[4::5]='---'
print(''.join(a))
@rugged sparrow 5 shorter
a[4::5]='-'*3 not shorter, but looks more esoteric
Wouldn't import random as r be shorter
I doubt it if you just need to call it once
__import__('random')```vs```py
import random as r```and then call `r.`
roughly the same bytes I think
yeah but you can't exaactly do in one line, though it doesn't seem to be what you are doing
you cannot do it in one line, yep
from random import*?
Would that be shorter?py from random import* import random as rr.
oh it is shorter by 1 byte!
well, unless you count newlines as 2bytes
That does not count as a oneliner
why not
im pretty sure ; is seen as a newline in python
kinda like writing its all in a string with \n and then evaling that
no, someone showed recently that it breaks if you e.g. have while
for some reason
print(3); while False: print(1)
```that's invalid
yeah i think you can only have a expression after it
similarly to how this doesn't work:
lambda x: while True: pass```
https://docs.python.org/3/reference/compound_stmts.html
according to the ebnf here, if im understanding it right, you can only have either one 'compound statement' or a 'statement list'
per suite
oh wait thats just plain old bnf, not ebnf
>>> curse(int, '__matmul__', lambda x,y:range(x,y))
>>> [*0@10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ``` forbiddenfruit is so cool
is there a way to open a โcontextโ inline?
instead of having to do (e.g.) with context_func():
to do something inline do(context_func)
but still get the benefit of like finally: logic when the outer scope is exited
well you can pass the compound statements like above
for other ways I'm far from being esoteric enough ๐
what do you mean?
There might be a built-in that lets you pass it a function to put in with, but I can't think of any.
or is there any functionality to detect when the scope that an object was created in is being exited
you could just add an another with arg for a context manager that would only do that
and link the context manager object to the one where you want to know about it
you can do this with a with for the scope
class MyContext:
def __init__(self, tracked_obj):
self.tracked_obj = tracked_obj
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
print("with of", repr(self.tracked_obj), "at", hex(id(self.tracked_obj)), "exited")
def do_stuff(*_, **__): pass
with open("DELETEMELATERTHANKYOUVERYMUCH", "w") as obj,\
MyContext(obj):
pass
with MyContext(myvar := 5):
do_stuff(myvar)
if I understood you right you can just create a decorator that applies this
ah but you'd still need MyContext as the outer context though
I guess that works to only have to do it once
but how do we get it down to zero...
you don't really add it unless you want to track everything
Now that I think about it, it'd be easier and nicer for the tracked vars to just be almost that you can append to after the with instead of walrusing it in
@rugged sparrow @zealous widget contender from @red timber
print(*[(chr(__import__('random').randint(65,90)),'-')[1>>i%5]for i in range(1,20)],sep='')```
shut up dude
Come at me
-3-
It's a smart usage of modulus to get that -
print(*[(chr(__import__('random').randint(65,90)),'-')[1>>i%5]for i in range(1,20)],sep='')
print(*("".join(__import__('random').choices([*map(chr,range(65,91))],k=4))for _ in"."*4),sep="-")```shorter!
screw u discord
1>>i%5 -> i%5<1
Or, even better, 1>i%5
It's just the removal of a >
Then it's slightly more esoteric, but same length to do python print(*[(chr(__import__('random').randint(65,90))+'-')[1>-~i%5]for i in range(19)],sep='')
print(*[(chr(__import__('random').randint(65,90))+'-')[i%5>3]for i in range(19)],sep='')``` looks to be even shorter.
Not shorter, just weirder: python print(*[f"{chr(__import__('random').randint(65,90))}-"[i%5>3]for i in range(19)],sep='')
i&3>2 is a faster check
i&3>2 is similar to i % 3 == 0?
i % 4 == 3
since it's &, as the last two binary digits loop through 00, 01, 10, and 11, it returns 0, 1, 2, 3 ( masking the last two binary digits )
hm, that's wrong since it returns 3 true then 1 false
n=[chr(65+(i&25))for i in __import__('os').urandom(19)];n[4::5]='---';print(*n,sep='')
does this count
christ whats happening
Is there a way to override the behavior of pass?
n=[chr(65+i%26)for i in __import__('os').urandom(19)];n[4::5]='---';print(*n,sep='')
better?
@fallow storm im guessing youd have to find some way to intercept it at the compilation stage. pass doesn't result in any bytecode being generated.
tl;dr: most likely not
maybe using sys.settrace, go through the code of a function before it's executed, replace each pass with something else, recompile the function, then run that instead.
or a decorator that does the same, etc.
https://pymotw.com/3/sys/tracing.html#tracing-inside-functions cool, looks like there's a way to trace a function line by line
so there's your in for possibly intercepting pass
not sure if it'll actually be traced or not
Challenge: Solitaire
Recently, Zachtronics games have released their new game, MOLEK-SYNTEZ, and it includes a Solitaire variant (rules attached)
The input for your function will be a List[List[int]] where int is a number representing the value of the card (6-14, V=11, D=12, K=13, T=14) and the inner list is one of the columns. There are only 6 columns.
Note: when a stack is completed, the column becomes unusable.
The output should be the moves required to solve the board, if possible.
If impossible, return False.
Bonus: If possible without cheating, return a solution doing that.
Bonus: Fastest execution.
For any additional questions, feel free to send them to me.
I'll try making a PoC implementation
Think freecell would be nicer with the almost all solvable boards
@grave rover looks good to me, sure i can pin it. it'll be up to you to get people to notice it and stuff though :)
@slim pecan would this be suitable for #592000283102674944?
It's an event and organized by a community member :P
Ask in #community-meta, I would
I'm not exactly overlord of that system, I just make use of it
I guess, you can congratulate me.
I now officially own the Clash of Code bronze medal!
I stopped after having trouble to get games with players that weren't bots, how is it now?
I don't think I ever encounter bots, I usually play with real people only.
Are bots somehow marked explicitly?
I came 2nd in one round, and now I'm back at the 10th place :(
It's an online coding competition:
https://www.codingame.com/multiplayer/clashofcode
You compete in either speed or code-golfing.
There's also a bit of inductive reasoning for half of the speed challenges, because you don't get given a problem, just some valid outputs for certain inputs.
The other half of the speed challenges are normal.
I don't really get why they bunch all 3 together
Ooh codingame, I played at this thing
Tried one, no one got more than 50% on the first problem lol
The reverse mode is hard
It's not bad if the problem is hard, but I once saw a "reverse" problem where the I/O pattern was very ambiguous. All the test inputs were correct, but some of the hidden tests failed.
How does the leaderboard work? There's two numbers but no explanation for what they are, I assume the 2nd one is no. of games played but the first one idk
Score? Wins?
It's the "score". It depends on the amount of rounds you play and the place you take in the round-local leaderboards.
It also somehow decreases with time.
I guess it uses some smart algorithm so that if you become better over time, you get closer to the 1st place.
Ah interesting, cause I played for an hour-ish (got a bit sucked in lol) and somehow ended up 128th in the world, which didn't make sense to me at the time
If you are a new and active player and get decent results, you will get pretty high in short-term, I think.
It's not hard to get in the top 3 of your country.
If it is not Russia @formal sandal haha
Haha yep I'm in Australia and got first really quickly, we only have 25M people here
@formal sandal haha, I am probably gonna be around top 10 cuz probably not skilled enough yet
def is_even(n):
try:
eval('"' + '\\'*abs(n) + '"')
return True
except:
return False
I just understood a code snippet in #esoteric-python wooooooo!!!!
def is_even(n):
try:
eval('" '*abs(n))
return True
except:
return False
is the space necessary
no
Yes because of triple quotes?
still no
a single """ is still invalid syntax, whether you parse it as triple or not
having a pair """""" is valid syntax, whether you parse it as triple or not
so ultimately having a space there isn't necessary
"""" isn't a valid syntax but " " " " is
My favorite even/odd its still & 1
I'm partial to a recursive definition, but it's not so esoteric, and works a lot better in Scheme than Python.
a fun little experiment i did. kinda esoteric because it involves brainfuck.
trans-piling your bf code to python!
turns this unreadable code:
https://paste.pythondiscord.com/anifahudej.py
def oddeven(i, e=0):
if i==0:
return e
return oddeven(i-1, e^1)
@snow beacon here's my terrible recursive solution
slightly more readable
>>> def is_even(x):
... return not x & 1``` honestly `&1` is the best lol
Can someone explain why these aren't the same?
def oddeven(i, e=0):
if i==0:return e
return oddeven(i-1, e^1)
f=lambda i,e=0:[e,f(i-1,e^1)][i>0]
^
f(i-1,e^1)if i>0else e
Would there be some way to do that with short-circuiting?
as in and/or stuff?
>>> f=lambda i,e=0:i>0and f(i-1,e^1)or e
>>> f(0)
0
>>> f(1)
1
>>> f(2)
1
>>> f(3)
1
>>> f(4)
1
>>> f(5)
1``` if you do it like this it doesn't work properly
yeah, and and or stuff
why not just f=lambda x:x&1
IFcoltransG brung up the idea of a recursive solution
and I wanted to see how short I could make it
f=1 .__and__
Nice didn't know about that whitespace hack
it makes sense actually
- Is a float literal, 1 . is the . operator
!e
print(1..imag)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
0.0
lol
x=quit
y=x.__class__
y.__add__=print
y.__pos__=x
x+x++x+x```
Can someone explain to me how this works? It outputs something but idk how
heck
the last +x does nothing
x+x => print(quit)
+x => actually quit
yeah
other than that, it prints x, then adds +x to that. which is the __pos__ (unary +), which is quit
how is x+x print(quit)?
x = quit assigns the built-in quit to x
y = x.__class__ therefore becomes an instance of Quitter (due to the implementation)
Let's now skip and examine the line
x + x + +x +x which gets evaluated to x.__add__(x).__add__(x.__pos__()).__add__(x)
Now, we change __add__ on the class to be print, and __pos__ to quit, which makes it do
print(quit); quit()
because y.__add__ becomes print
and y is the class that x is an instance of
and the repr of quit is the message you see when you do quit without the parens
x + (+x) is x.__add(+x) which is x.__add__(x.__pos__())
Wait does that mean that Python could be TC without any brackets? Since you can basically call any builtin and do control flow with while loops?
wdym without any brackets
Without using any of ()[]{}
no
only if you count "haha I put the program in an overloaded operator" as turing complete
But like
You can do storage with vars
You can do control flow with while loops
And you can add and subtract from numbers
That sounds like it could easily make a 2 counter Minsky machine
Which is TC
It might be hard if you didn't have the site module.
@gilded orchid you should try brain fuck!
You have to write your own compiler but its pretty simple. Max 5min
Its tc but only has 8 operators
Brainfuck requires an infinite tape, and lists are hard to make without []. I think a Minsky machine would be easier.
!e ```python
This is syntactically correct!
s = "o;(b.b)-=o (a.a)"
compile(s, "", "exec")
@formal sandal :warning: Your eval job has completed with return code 0.
[No output]
poor a.a
What is the shortest way to define such o, a, b so that the expression can run?
!e
class x:a=b=1
a=b=x
o=abs
o;(b.b)-=o (a.a)
@formal sandal :warning: Your eval job has completed with return code 0.
[No output]
@formal sandal :warning: Your eval job has completed with return code 0.
[No output]
@grizzled cloak I messed around with brainfuck like 8 months ago and made https://pastebin.com/WJVxQnvp
It outputs the lyrics to the 12 days of christmas
(most of it is autogenerated by a script I wrote but it should be fairly efficient)
also yeah, brainfuck is by no means the easiest way to prove something TC
2 counter minsky machines and some weird esolangs (like Tip, Three Star Programmer, MINIMAX, or the waterfall model) are a lot better easier to use for proving turing completeness
Simulate a nand gate which you can nest
Though that can be non-trivial depending on context
Nesting it might not be enough, it doesn't automatically allow for self-reference
Like in a SR NAND latch.
There's no implicit iteration in nand gates.
!e
from functools import wraps
def inherit_from(parent):
def decorator(child):
@wraps(child)
def func(*args, **kwargs):
prepared_object = parent(*args, **kwargs)
child(prepared_object, *args, **kwargs)
return prepared_object
return func
return decorator
def base(*_, **__):
d = {}
d["self"] = d
return d
@inherit_from(base)
def animal(self, size, age, *_, **__):
self["size"] = size
self["age"] = age
dog = animal(25, 10)
print(dog)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
{'self': {...}, 'size': 25, 'age': 10}
O O P
LOL
@thin trout @lyric fog
!e ```py
print(import('functools').reduce(lambda m, x: m * x, [1, 2, 3, 4, 5]))
@crystal mica :white_check_mark: Your eval job has completed with return code 0.
120
Was this what you guys were looking for?
i was just joking
you got me haha
math.prod() looks super clean on 3.8 too, thanks @tame crow for showing me that there's one lol
it's functools.reduce()
Oh that's an handy function!
wah
Actually, reduce was built-in
(prod:=lambda m,x: m if len(x)==0 else prod(m*x[0],x[1:]))(1,[1,2,3,4,5,6,7])
no imports
walrus is much nicer than a Y combinator
!e
print(
(lambda r,a:r(r,a))(lambda f,x:1if x<2else x*f(f,x-1),5)
)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
120
Are classes with inheritance (let's assume multiple inheritance is not allowed) isomorphic to functions with composition?
wait, walrus operator lets you reference the name you're assigning to?
i wouldn't be too surprised if they were isomorphic, but i have no idea how one would construct the isomorphism
inheritance seems a lot messier to deal with
i suppose just prove it non-constructively by showing they're both turing complete or something
Well, you could formalize what a class is...
But having dictionaries is kinda cheating.
thats another way to do it
!e
from math import log, exp
print(
exp(sum(map(log, [1, 2, 3, 4, 5])))
)
@formal sandal :white_check_mark: Your eval job has completed with return code 0.
119.99999999999997
Only works for positive numbers, though.
reduce = lambda x, f, n=1: (all((n := f(i,n)) or True for i in x), n)[1]
@formal sandal in function composition you have id function
there isnt id class strictly speaking
unless we mean function composition in python only, in which case its kinda hard to say
You could have a class that inherits but with pass as the body. That'd be an identity.
it won't since it'll still be registered as its own class
its a class that does nothing yes,
for functions it's different since we can re-define function as Input -> Output (relevance to composition) <- i take this back
And for classes, parent -> child
While the parent and child compare unequal, they have the same behaviour.
idk about defining empty class as id
Would you like to elaborate? What meaningful change does it cause?
it doesn't add anything to the class, sure, but the inheritance exists still
can't replicate the mapping onto itself concept
you can say feature-wise, input+function in python and class+inheritance in python would have this isomorphism comparison
let me brainstorm a bit
ok i can put in better wordings as i'm thinking more about this:
- we're making morphism between: input - class, function - inheritance
- id function exists, id inheritance doesn't (strictly speaking)
- you make an empty class (would be equivalence to no input), in order to replicate an inheritance that adds nothing to the class behaviour, but it is still a separate inheritance
functions:
def id(x):
return x
def f(x):
return str(x)
id o f (x) ~~ id(f(x)) ~~ f(x)
e.g. id o f (1) = id(f(1)) = '1' = f(1)
class:
class Empty:
pass
class A(Empty): # inheritance is made by python
pass # implicitly A -> Empty not A -> A
class B(A): # now we have B -> A -> Empty
pass
??? what's the equivalence of id composition ???
I was imagining the reverse.
class Foo:
def __new__(x):
return str(x)
class FooComposedWithIdentity(Foo):
pass
now we're mapping class to function
Isn't that what we want to do?
see, in your example you have a class that does the equivalence of a function
effectively re-name function to class
i'd imagine op's question along the line of,
- since we can do composition typeA -> typeB -> typeC, which makes a typeA -> typeC function for functions,
- can we do classA inherits classB inherits class C (which makes classA inherits classC as a result of implicit composition)?
to which, would be my answers when i bring out id function
but your example is basically re-aliasing function to class, input -> output becomes argument -> object
which are 2 different cases
The __new__ function was just an example. The class could instead have, for instance, a property as its data.
yeah same point still
The point was to demonstrate that you can inherit from it without changing the data.
I think the important part is what aspects of functions need to be supported by the morphism to classes.
see op question wasn't that clear so idk
i might have misunderstood it and they meant your example
I can define a set of functions, where each one inputs a class, and returns another class that inherits from the parent, except with some attributes changed.
Each of those functions obviously has a direct mapping to a class inheritance.
if i take his sentence literally without intepreting,
class maps to function, inheritance between 2 classes map to composition between 2 functions
what would be an example,
for function you have input -> output, what is the equivalence of class, argument -> class instance?
or argument -> class behaviours
what would a normal inheritance i.e. composition look like
@snow beacon
If a composition uses a function to transform a python object into a python object, then inheritance uses a class body to turn a class into a class.
The equivalence relation between objects couldn't be the same as for classes
see we can't even cover the basic before getting to edge case
Classes aren't the same python objects as each other, but they can have the same behaviour.
What exactly do you mean by 'normal inheritance'?
normal -> any
like producing a new class with combined behaviours?
a function obviously has purpose: transform object to object as you said,
in which case compose becomes clear
i'm trying to find out the equivalence in terms of purpose when you literally make a class
so i know what we are composing (when we inherit classes)
I would say if their class dicts are the same, they are equivalent.
Ignoring anything trivially different like __name__
def BaseFunc():
return 1
def FunctionToCompose(x):
return x + 1
FunctionToCompose(BaseFunc())
class BaseClass:
x = 1
class ComposedBaseClass(BaseClass):
x = BaseClass.x + 1
this example is class makes property from argument (or lack of argument?)
I don't know what you mean, but this example demonstrates how to compose an incrementation function onto a function that returns a number, and also an incrementation class body onto a base class that stores a number.
composition between 2 morphisms, function o function -> new function
def BaseFunc(): # first function
return 1
def FunctionToCompose(x): # second function
return x + 1
FunctionToCompose(BaseFunc()) # this is the composition / composed function
equivalence should be inheritance between 2 classes
class BaseClass: # first class
x = 1
class ComposedBaseClass(BaseClass): # this is already the composed
x = BaseClass.x + 1
see i can't even see this class example as a composition
when you compose a function B -> C (input output objects), and a function A -> B, you get a function A -> C
now in order to apply to class i need to identify what is my class' equivalence of Input -> Output
what am I composing
The whole parent class is the input.
(That's why BaseClass has no parent; it doesn't take input.)
i don't think we're on the same page still
Composition is an operation, which takes a mapping of inputs to outputs, i.e. a function, and another function. It applies the mapping of inputs to outputs. Inheritance is an operation, which takes a mapping from base class to new class, i.e. a class body, and another class. It applies that mapping to the other class.
There's a modification you need to do to be able to refer to the parent class inside the class body, which is to insert the parent class name at pertinent points. Otherwise, it's the same.
which takes a mapping of inputs to outputs, i.e. a function, and another function
which takes a mapping from base class [missing equivalence of inputs -> outputs] to new class,
That's just a matter of terminology.
In the context of functions, an input is an argument, and output is a return value.
no it's a matter of the concept which is fundamental to all this
With classes, the input is the base class. The output is the newly define class.
now you're confused even the bare definition (before we even get to composition)
def f(x):
return str(x)
# a number -> a string reprenstation of said number
class A(randomArgs):
someProp = 1
def someMethod():
pass
# no equivalence, there is no base class newly class here
randomArgs is the base class, A is the new one.
so now classes have to take other class as argument for the analogy to work?
what if i take a number
So your point of contention is that classes can only transform certain python objects and not others?
my point is there isn't an isomorphism from function -> class
maybe injective
which is required before we start defining composition
I think I understand then.
Let's take the print function: it prints out its argument and returns None. The result None would need to be encoded into a class, as would the input, so let's say:
class input:
value = "hello"
class Printer(input):
print(input.value)
value = None
I've defined a class that does the same thing as the print function, except input and output are encoded as the .value of various classes.
i wouldn't argue against specific classes, since you can always find many types of classes, that you can make a homomorphism from composition -> inheritance
I guess I should write a program that transforms any function into a class inheritance then?
there are a lot of similarities you can draw between these 2
however it won't be isomorphic or homomorphic (include this as well cause i believe its relevant)
message i deleted ^
I think I was looking for a morphism between some subset of possible classes, and all functions.
yeah
i should get back to work tho ๐ฆ
thanks for the insights, i'm actually not an expert in python in many ways
You seem well versed in maths.
@lyric fog a class can return any object if you define __new__
class f:
def __new__(cls, x):
return str(x)``` also str itself is a class ๐
a class is just a kind of callable object, just like a function. you could build a parallel class system with another kind of object, though of course the objects would have to be instances of a real class as well (in python 2, such a thing actually exists with the classobj/instance types for old-style classes)
It seems like you can make injective mappings either way between classes and functions, but probably not anything bijective.
that was my initial thought, but i think just proving both turing complete is good enough
Functions are lambda calculus+
Classes can contain arbitrary code. Looks like both are TC
Is it possible to get/change the bytecode of a class before it's created?
Wdym by before it is created?
Well
Like before you create an instance of that class?
Before the class is created
Lemme give an example
@modify(b"d\x00", b"d\x01")
class x:
a = 1
b = 2
print(x.a) # -> 2
Decorators are executed after class creation ๐
Your example will be expanded by the interpreter to
class x:
a = 1
b = 2
x = modify(x, b"d\x00", b"d\x01")
print(x.a) ```
But this decorator can be easily created i think
Actually it looks a bit more complicated https://stackoverflow.com/questions/33348067/modifying-python-bytecode/40105522
maybe using a metaclass
Metaclass also doesn't have access to it
actually class body is a function
not a function
a code object
but inaccessible at the metaclass level iirc
metaclass only gets the evaluated params: (classname, baseclasses, dict)
Btw is there
gc.get_objects()thing for other implementations of Python?
Really wondering about this now lol
@marsh void does that just return all objects in the python instance?
Yeah
hmm
dir() will return everything in scope
in IPython:
%whos
Variable Type Data/Info
------------------------------
A type <class '__main__.A'>
a A <__main__.A object at 0x000001C042A90DA0>
sys module <module 'sys' (built-in)>```
vars() will print a lot more
Yeah I need some more Python's installed lol
@grizzled cloak I need to get object.__dict__ of type dict, thatโs why I am asking lol
len(gc.get_objects())
6557
Yea they are functions
i dont know what you are looking for
but this can alter class code by their metaclasses
praise the ฮป
That's pretty neat.
https://hastebin.com/exemugeqas.py I am wondering if there is a way to hack the thing I have made (I mean like, execute arbitrary code and stuff). Any suggestions?
I am lazy to write an actual calculator parser so lol
@marsh void if I understand correctly you abort the operation if any function call aren't in the env right?
i think i made one for codewars
@thin trout well, I am just restricting the eval, exec and breakpoint, and env is just for additional stuff
Yeah I am overriding exit but print isnโt required to override though
Oh yeah if there is an INVALID_CODE
class Calculator:
"""
Given the problem statement included parentheses in its list of operators, this version can parse them.
It will also take care of un-spaced input, so `.evaluate("(5*(3+2))/4")` is valid.
"""
def evaluate(self, my_string):
if isinstance(my_string, str):
my_string = "".join(i if i.isdigit() or i == "." else f' {i} '
for i in my_string).split()
my_string = [i if i in "()+-*/" else float(i) for i in my_string]
def check_for(operators, my_string):
op_dict = {"+":lambda x, y:x + y,
"-":lambda x, y:x - y,
"*":lambda x, y:x * y,
"/":lambda x, y:x / y}
while any(op in my_string for op in operators):
for i, op in enumerate(my_string):
if str(op) in operators:
my_string[i - 1:i + 2] = [op_dict[op](my_string[i - 1],
my_string[i + 1])]
break
return my_string
def find_matching_parens(my_string):
scope = start = 0
for i, symbol in enumerate(my_string):
if symbol == "(":
if not scope:
start = i
scope += 1
elif symbol == ")":
scope -= 1
if not scope:
return start, i
while "(" in my_string:
start, end = find_matching_parens(my_string)
my_string[start: end + 1] = [self.evaluate(my_string[start + 1:end])]
return check_for("+-", check_for("*/", my_string))[0]
my code was lengthy because i implemented parenthesis
You couldn't have used regex?
I made something similar with a lalr parser library.

