#internals-and-peps
1 messages Β· Page 58 of 1
you could write can_fail, then implement a monadic_bind that accepts a particular monad, no?
hm
ah, =<<, not >>=
this actually raises the question of how would you write such a "monad wrapper" like can_fail in haskell for a custom monad
also i have to run but this is interesting and i'll read any follow up conversation
typeclasses in python sound like a fun project. Probably not too useful though
well, I guess things like __int__, __bytes__ and such are "typeclasses"
I actually made a small library for typeclasses https://repl.it/@int6h/Haskell-greatergreater-Python#main.py
that's an old version, but whatever
I think it's okay to share this here: https://medium.com/@decorator_factory/typeclasses-in-python-3c21ae9327af (not monetized or anything)
@paper echo
Well, a monad is a type m which defines two functions: return :: a -> m a and >>= :: m a -> (a -> m b) -> m b that obey some common sense laws
So for lists,
def return_(x: A) -> List[A]:
return [a]
def bind(ma: List[A], f: Callable[[A], B]) -> List[B]:
return sum((f(a) for a in ma), [])
So return_(2) == []
and bind([1, 3, 5], (lambda x: [x, x+1])) == [1, 2, 3, 4, 5, 6]
so the first common sense law is that bind(xs, return_) == xs
other ones I don't remember
the term you will want to search are monad laws
(that's a euphemism for google it :) )
class Eq a where
(==) :: a -> a -> Bool
x == y = not (x /= y)
(/=) :: a -> a -> Bool
x /= y = not (x == y)
@grave jolt idk much haskell, but how is this not a circular reference? operator== relies on operator/= and vice versa
and for an Optional[T]:
def return_(x: A) -> Optional[A]:
return x
def bind(ma: Optional[A], f: Callable[[A], Optional[B]]) -> Optional[B]:
if ma is None:
return None
else:
return f(ma)
One problem with subclassing built-in types in Python is that you'll have to redefine every god damn method because none of the methods are defined in terms of each other.
does anyone happen to know any free courses for backend development using python?
@unkempt rock check out #βο½how-to-get-help, or maybe ask in #python-discussion
This is not a help channel.
alrighty ty
behold, my cursed code
return lambda: (player.add_item(item, amount), player.money -= cost)```
player.money -= cost as an expresion should not compile
oh shoot, you're right
thanks
you have it backwards
for future reference, use a help channel
although that was an easy one
addedInches = int(feet*12)```
should just be that
Why are there no asynchronous lambdas? 
because it sounds like a good way to not make friends
C# has them, works out fine tbh
But i mean it just generates an async method, hardly something interesting
C# and Python lambdas are different though because in Python you can only have a single statement essentially (ignoring #esoteric-python ) whereas in C# you can define whole functions inside the lambda
ignoring #esoteric-python
I feel personally attacked
You can make asynchronous lambdas if you need them
what is the use of django
a framework to build modern website, thats all
Backend for websites, yep.
Why are there no asynchronous lambdas?
@grave jolt yeah, we need anasync lambda
Hey, are we able to ask for help in here?
no, preferably #βο½how-to-get-help
Ahh okay, thanks π new to py, so questions already coming from js.
async lambda may be a bit unintuitive cause it already borders around the concept of an "anonymous generator" from how I see it
What app or website should I use for python?
Visual Studio Code is a popular IDE to use for python (and other languages). You can google it on how to set it up for python π
Dataclasses are very cool - especially as they're easy to serialise. It seems to me that if Python leaned into dataclasses, they could replace the need for stuff like Marshmallow with relatively minimal work. But it makes me wonder - are there disadvantages to leaning on dataclasses too heavily?
I guess having boilerplate written for you takes away some customization that honestly really isn't needed for modeling dataclasses
It may also take a bit of time to mentally parse given how different the syntax is
How does python handle additions to the standard modules?
Specifically name clashes with pypi packages
Can a pypi package be named the same as a builtin package? And if so, how would you import/use it?
who can use django and what is django used for
@mint forge you'll probably have better luck asking in #web-development or possibly just asking Google then if you're not sure, asking about some of the specific areas your unsure about
Does the annotations future import only affect the module it was imported in or all modules loaded after that?
How to convert [1,2,3] to [[1,2,3]] using numpy ?
there are like 5 ways probably
numpy seems to be like that
SO suggests X = X[:, None] or something
nope, that's not it
a = a[None, ...] or a = a[None, :]
and there's probably 7 more
a = np.expand_dims(a, axis=0) also works
a = a.reshape([1, -1])
guys
i need help
im going to do a extension program for computer science
so i wanna learn python
can someone teach me basics?
How to convert [1,2,3] to [[1,2,3]] using numpy ?
I don't understand, isn't it just a = [a]
@unkempt rock This isn't a help channel actually, but
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
okkokkkkkkkkk
Shop={'Apples':'2', 'Bananas':'5'}
Print(Shop)s
Why do we need a s after the parenthesis
that's invalid syntax?
I don't think you do yeah

that wont run lol
@red solar (foobar|foo) on foobarbaz matches foobar and not bar, I'm not sure what you mean by checking them from largest to smallest?
lets say you have the commands[he, hello, wassup, hell] - if you get input and want to get the shortest match, you just run through the list sorted in reverse ([wassup, hello, hell, he]
sorry not the shortest, the longest
sometimes i explain myself badly :/
I've made the assumption that this is for checking which command a user meant to trigger on a bot - left that out in the explanation - let me look at my bot and find a good example
wait are you talking about regex or string comparison?
whatever you're talking about here
ah i see where my explanation was poor
you have commands !tag username and !tag id, and !tag, and all 3 are followed by arbitrary text - since !tag is a subset of the other two, you can't check if the input starts with !tag first, you need to check if it starts with the longest command string, and work your way down
the explanation earlier was poor because I just said matching :/
just like fizzbuzz, you match the largest denominator first
^^ idk why I explained it so badly originally
How do you call current-level methods in an inheritence chain, when you are calling super().init()?
self.method()?
that calls the child's method
lol yeah I suppose that would work, but would break that particular class because if you instantiate it, it will now be calling ITS parent's method
I just have this chain of inheritence and they all call super().init() and then the inits() in the higher level modules need to also call methods that are overriden in lower level classes
very confusing
I didn't design this by the way
lol
you need parents to call child methods?
no, I'm trying to prevent that
they are calling the child methods, because the method is overridden, and I'm instantiating the lowest level classes, but calling super().init()
and in the init() for those, they call overridden methods so I end up just calling the child's methods every time
ah, so you want to do something like
class A:
def u(self):
print('a')
def m(self):
self.u()
class B(A):
def u(self):
print('b')
B().m() # b
``` to print a instead?
yes, but I'm instantiating B, which in its init() calls super().init(), and in the init() for A it needs to call u,() but it currently calls B's u()
you have to do
class A:
def u(self):
print('a')
def m(self):
A.u(self)
class B(A):
def u(self):
print('b')
B().m() # a
``` afaik.
ok thank you I'll try this, that makes sense
what is the use of ord()
i think it string characters to their number counterpart
utf-8* unicode*
inverse of chr()
You're not going to need it most of the time
When you work with keyboard modules, you want the codepoint for lookups etc
>>> "".join(chr(i) for i in range(97, 97+25))
'abcdefghijklmnopqrstuvwxy'
why not π€·ββοΈ
you're missing z
why need in python, we have assembly anyway
hi
it's the factor of convenience π
also, from string import ascii_lowercase
how to use python
!resource
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
i will use kali linux
not the right channel for it @late quiver
np, lemme redirect you to #python-discussion , or if you need help with anything specifically #βο½how-to-get-help
It's a simple literal underneath
Does range only have .count because it implements the Sequence ABC? Because I can't imagine a range having the same value more than once, and in that case, __contains__ should be enough really
yes
is collections.abc being unified with typing in 3.9? or just "builtin" collection types like list and dict
builtins and some stdlib objects that have hints in typing will be generics directly, but I don't think that affects abcs in any way
feels bad
need to use collections.abc.Sequence for runtime checks and typing.Sequence for static checks
v unpleasant
That may fall under the stdlib types, but would have to check the pep/docs as abcs are a bit special https://www.python.org/dev/peps/pep-0585/#implementation
Don't the typing classes implement hooks to unify instance checking?
>>> from typing import Sequence
>>> isinstance([], Sequence)
True```
>>> class Thing(abc.Sequence):
... def __getitem__(self, index):
... pass
... def __len__(self):
... pass
...
>>> isinstance(Thing(), t.Sequence)
True```
Seems to work fine
is there anything that dictionaries can do that an attr class can't?
Use their methods directly
hrm - what's an example of that? Like pop and stuff?
setdefault as something you'd use on a single key
setdeault is nice tho i never use it - this just means that if i do some d[x] where x is not in d it'll return a default value
that's handy i guess actually π€
you have .get with getattr(obj, potential_attribute, fallback)
setdefault also creates the key if it is not present
how can i find .get, as dir() doesn't return information on it
getattr(...)
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
it is a builtin
right - so when you say it's the equivalent for attr - it's also for other objects i guess?
or is there some dunder that means they can use this method
In [37]: getattr(1, 'hey', 2)
Out[37]: 2
TIL
ye, it works on any object and follows the proper attribute access thing with __getattribute__, __getattr__ and descriptors
is this a good thing to read to understand dunders and stuff?
or is there something better/more suitable π€
for i, usuario, espaco in enumerate(zip(nomes_usuario, valor_usuario)):
that is quite good I would say
enumerate always yields tuples
You get a tuple with the index as the first element and a tuple of zipped values as the second
i, (va, vb) should work
yeah, that works
you can nest unpackings
a, (b, c, [[d]]) = [1, [2,3,{(4,)}]]
i only recently realised that dict(zip(a, b)) works, instead of {x:y for x, y in zip(a, b)}
that's quite a handy trick
ye, it is quite neat
I think it's mentioned in Fluent Python as well
how do you find out why this works though?
What, dict(zip(a, b))?
i, (va, vb)should work
@flat gazelle i did not got it totally, what should i put in enumerate?
the dict constructor can take an iterable of pairs as an argument to construct a dict
presumably there's some methods which need to be in place for the objects, but idk what dict is doing when it does dict(), why it works with zip() etc
dict accepts an iterable of key, value pairs and that's what you get when you zip two iterables like that
@unkempt rock ```py
for i, (usuario, espaco) in enumerate(zip(nomes_usuario, valor_usuario)):
which you should do with a dict comp, but I digress
nope, just gotta nest the unpacking
i guess this is the relevant section
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
you can nest unpackings
a, (b, c, [[d]]) = [1, [2,3,{(4,)}]]
@flat gazelle mindblown
I could see it being in a rather complex JSON
A poorly laid out one, mind
But I could see it still coming into play
yo can anybody teach me python π― 
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
I really want dict and attr unpacking tbh
why can we not do {1: a, 2: b} = {1: 1, 2: 2}
That would be really nice to have
i dont understand any thing cause im trying to learn python xd
@flat gazelle i like that better than the pattern matching
both would be nice honestly.
You can do something like that with inspect
@drowsy coyote first of all this isnt the right channel. second, i recommend Practical Python by David Beazley and Automate The Boring Stuff (up to chapter 10 or so) by Al Sweigart. Both are in the resources page
@magic python check out the datamodel section of the docs as well as collections.abc
Unpack({1: "a", 2: "b"}) <= {1: 1, 2: 2}
that would only work with globals though, or it would have to be sth like
a, b = Unpack...
I know you can do
from operator import itemgetter, attrgetter
from Pathlib import Path
a, b = itemgetter(1, 2)({1:1, 2:2})
suffix, parent = attrgetter('suffix', 'parent')(Path(__file__))
```but that is pretty unwieldy
@flat gazelle at least you can do a, b = {1: 1, 2: 2}.values()
@flat gazelle #esoteric-python message
def destructure(obj):
if not isinstance(obj, dict):
raise TypeError(f"{obj} is not a dict")
parent_frame = inspect.currentframe().f_back
line = inspect.getframeinfo(parent_frame).code_context[0]
var_names = map(str.strip, line.split("=")[0].split(","))
for var_name in var_names:
yield obj[var_name]
a, c, b = destructure({"a": 1, "b": 2, "c": 3})
ye, that seems reasonable.
But that won't work if you don't create the dict immediately
globals().update(mydict)
@flat gazelle you can implement something like that by hooking dict.__iter__ and using inspect
@utils.edit(dict, 'tp_iter')
@utils.nullwrap
def dict_iter(self):
last_frame = inspect.currentframe().f_back
for instruction in dis.Bytecode(last_frame.f_code):
if instruction.opname in ['STORE_FAST', 'STORE_GLOBAL', 'STORE_NAME', 'STORE_DEREF']:
yield self.get(instruction.argval)``` this uses my py_future module (basically forbidden fruit but lets you hook more)
>>> from py_future import expdict
>>> d = {'a':1, 'b':2, 'c':5}
>>> a,b,c = d
>>> a
1
>>> b
2
>>> c
5
>>> ```
Does this break regular iteration over keys?
yes
@tacit hawk
def append_exception_tail(e_chain, e_new):
head = e_chain
while head.__context__ is not None:
head = head.__context__
head.__context__ = e_new
return head
try:
try:
raise ValueError('1')
except:
raise ValueError('2')
except Exception as e:
echain = ValueError('3')
enew = TypeError('hi')
e3 = append_exception_tail(echain, enew)
raise e3
doesn't do what i was expecting
TypeError: hi
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 14, in <module>
raise e3
ValueError: 3
but you can always do dict.keys() @spice pecan
I know, and I usually do because it's more explicit, but I was still curious
but yea you're right it does break key iteration
it prob also breaks some other stuff too, havent tested it much
I guess it could break some internal usage
probably
to be fair, my entire py_future module tends to break things so
Β―_(γ)_/Β―

@paper echo
head = Exception("I am the chain head")
body = Exception("... I am the chain body ...")
tail = Exception("I am the chain tail")
body.__context__ = head
tail.__context__ = body
raise tail
Exception: I am the chain head
During handling of the above exception, another exception occurred:
Exception: ... I am the chain body ...
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 9, in <module>
raise tail
Exception: I am the chain tail
That is what I was expecting
hm
def make_chain(name):
head = Exception(f"I am the {name}'s head")
body = Exception(f"... I am the {name}'s body ...")
tail = Exception(f"I am the {name}'s tail")
body.__context__ = head
tail.__context__ = body
return tail
chain_a_tail = make_chain('Chain A')
chain_b_tail = make_chain('Chain B')
# join the two chains
head = chain_b_tail
while head.__context__ is not None:
head = head.__context__
head.__context__ = chain_a_tail
raise chain_b_tail
Exception: I am the Chain A's head
During handling of the above exception, another exception occurred:
Exception: ... I am the Chain A's body ...
During handling of the above exception, another exception occurred:
Exception: I am the Chain A's tail
During handling of the above exception, another exception occurred:
Exception: I am the Chain B's head
During handling of the above exception, another exception occurred:
Exception: ... I am the Chain B's body ...
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 19, in <module>
raise chain_b_tail
Exception: I am the Chain B's tail
since __cause__ is set only when raise from is used, part of the chain could be lost
__context__ is always set to the previous exception
count_ocurrence = lambda x, result: sum(1) for x in result
what's wrong here?
i want to sum 1 for each time x appears in result array
@paper echo when using __cause__ to join the chains I get
Exception: I am the Chain A's head
During handling of the above exception, another exception occurred:
Exception: ... I am the Chain A's body ...
During handling of the above exception, another exception occurred:
Exception: I am the Chain A's tail
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 19, in <module>
raise chain_b_tail
Exception: I am the Chain B's tail
specially in async code
when using callbacks to handle a task exit
and handling its possible exception
def extend_exception_chain(e1, e2):
head = e1
while head.__context__ is not None:
head = head.__context__
head.__context__ = e2
return head
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
exc = extend_exception_chain(e1, e2)
raise exc
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
so you'd want to do something like this?
yes
it emulates an exception being raised from an except block
handle_exc is the except block
!e ```python
import asyncio
async def foo():
raise ValueError('from foo')
def do_something():
raise RuntimeError('from handler')
def extend_exception_chain(e1, e2):
head = e1
while head.context is not None:
head = head.context
head.context = e2
return head
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
exc = extend_exception_chain(e1, e2)
raise exc
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...r('from foo')>) at <string>:16
002 | handle: <Handle handle_exc(<Task finishe...r('from foo')>) at <string>:16>
003 | Traceback (most recent call last):
004 | File "<string>", line 19, in handle_exc
005 | File "<string>", line 7, in do_something
006 | RuntimeError: from handler
007 |
008 | During handling of the above exception, another exception occurred:
009 |
010 | Traceback (most recent call last):
011 | File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ipoyagohox
nice, it works
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
raise RuntimeError('from handler')
def extend_exception_chain(e1, e2):
head = e1
while head.context is not None:
head = head.context
head.context = e2
return head
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
exc = extend_exception_chain(e1, e2)
raise exc
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:19
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:19>
003 | Traceback (most recent call last):
004 | File "<string>", line 22, in handle_exc
005 | File "<string>", line 10, in do_something
006 | RuntimeError: from handler
007 |
008 | During handling of the above exception, another exception occurred:
009 |
010 | Traceback (most recent call last):
011 | File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/hekufokoye
the 'from foo 2' one isn't retained here
change head to e2 in extend
yes, that is finding for e2's head
aha
right
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
raise RuntimeError('from handler')
def extend_exception_chain(e1, e2):
head = e2
while head.context is not None:
head = head.context
head.context = e1
return head
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
exc = extend_exception_chain(e1, e2)
raise exc
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:19
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:19>
003 | Traceback (most recent call last):
004 | File "<string>", line 5, in foo
005 | ValueError: from foo 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 7, in foo
011 | ValueError: from foo 2
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/zocaveruva
nice
asynchronous except block
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
def extend_exception_chain(e1, e2):
head = e2
while head.context is not None:
head = head.context
head.context = e1
return head
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
exc = extend_exception_chain(e1, e2)
raise exc
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:22
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:22>
003 | Traceback (most recent call last):
004 | File "<string>", line 25, in handle_exc
005 | File "<string>", line 13, in do_something
006 | RuntimeError: from handler 2
007 |
008 | During handling of the above exception, another exception occurred:
009 |
010 | Traceback (most recent call last):
011 | File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ibocoyuhor
that one cut off all the foo errors
return e2 in extend
let me make sure i understand what extend is doing
hi anyone know how to use variables in a sqlite query?
def extend_exception_chain(e1, e2):
head = e2
while head.__context__ is not None:
head = head.__context__
head.__context__ = e1
return e2
@royal mantle hi, this isn't the right channel. you should ask in #databases or refer to #βο½how-to-get-help
Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:22
handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:22>
Traceback (most recent call last):
File "<string>", line 25, in handle_exc
File "<string>", line 13, in do_something
RuntimeError: from handler 2
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
self._context.run(self._callback, *self._args)
File "<string>", line 28, in handle_exc
File "<string>", line 11, in do_something
RuntimeError: from handler 1
"from handler 2" is the __context__ for "from handler 1"
you need to raise the exception's tail, e2's tail is the tail of the entire joined chain
alright
ahhhhhh i see
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
def extend_exception_chain(e1, e2):
head = e2
while head.context is not None:
head = head.context
head.context = e1
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
extend_exception_chain(e1, e2)
raise e2
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:21
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:21>
003 | Traceback (most recent call last):
004 | File "<string>", line 5, in foo
005 | ValueError: from foo 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 7, in foo
011 | ValueError: from foo 2
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/laxaqutozo
got it
do the eval without chaining the exceptions @paper echo
it will probably just return all the handler errors right?
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
def extend_exception_chain(e1, e2):
head = e2
while head.context is not None:
head = head.context
head.context = e1
def handle_exc(task):
if (e1:= task.exception()) is not None:
try:
do_something()
except Exception as e2:
raise e2
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:21
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:21>
003 | Traceback (most recent call last):
004 | File "<string>", line 11, in do_something
005 | RuntimeError: from handler 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
011 | self._context.run(self._callback, *self._args)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/acaqotodas
here e1 was not raised because you consumed it, if you remove task.exception() will see that it gets raised at the end
right
!e ```python
import asyncio
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
def extend_exception_chain(e1, e2):
head = e2
while head.context is not None:
head = head.context
head.context = e1
def handle_exc(task):
try:
task.result()
except Exception as e1:
do_something()
async def amain():
task = asyncio.create_task(foo())
task.add_done_callback(handle_exc)
asyncio.run(amain())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Exception in callback handle_exc(<Task finishe...'from foo 2')>) at <string>:21
002 | handle: <Handle handle_exc(<Task finishe...'from foo 2')>) at <string>:21>
003 | Traceback (most recent call last):
004 | File "<string>", line 5, in foo
005 | ValueError: from foo 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 23, in handle_exc
011 | File "<string>", line 7, in foo
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/virisulito
task.result() is implicitly joining the chains
ah, that's from task.result() and not from the try/except itself?
it re-raises the task exception
wait how would that be possible
there is no chain to join when the exception is raised by task.result()
well there is 1 chain
it gets raised
then the except is clearly chaining the exceptions from do_something correctly
def handle_exc(task):
try:
do_something()
except Exception as e1:
raise e1
re-raising the task's exception was my first solution, I did
def handle_exc(task):
try:
task.result()
except:
do_something()
raise
else:
do_something()
yes
out of curiosity, you couldn't use finally for this?
... lol yes
the try finally would be equivalent to
def handle_exc(task):
try:
task.result()
except:
do_something()
raise
else:
do_something()
but I forgot that the exception raised in finally is chained
is it?
!e ```python
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
try:
foo()
finally:
do_something()
@paper echo :x: Your eval job has completed with return code 1.
001 | <string>:14: RuntimeWarning: coroutine 'foo' was never awaited
002 | RuntimeWarning: Enable tracemalloc to get the object allocation traceback
003 | Traceback (most recent call last):
004 | File "<string>", line 9, in do_something
005 | RuntimeError: from handler 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 16, in <module>
011 | File "<string>", line 11, in do_something
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/layacanola
seems like not
!e ```python
async def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
try:
foo()
except:
raise
finally:
do_something()
@paper echo :x: Your eval job has completed with return code 1.
001 | <string>:14: RuntimeWarning: coroutine 'foo' was never awaited
002 | RuntimeWarning: Enable tracemalloc to get the object allocation traceback
003 | Traceback (most recent call last):
004 | File "<string>", line 9, in do_something
005 | RuntimeError: from handler 1
006 |
007 | During handling of the above exception, another exception occurred:
008 |
009 | Traceback (most recent call last):
010 | File "<string>", line 18, in <module>
011 | File "<string>", line 11, in do_something
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/cimimacayo
π€·ββοΈ
oh
async
!e ```python
def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
try:
foo()
except:
raise
finally:
do_something()
@paper echo :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in foo
003 | ValueError: from foo 1
004 |
005 | During handling of the above exception, another exception occurred:
006 |
007 | Traceback (most recent call last):
008 | File "<string>", line 14, in <module>
009 | File "<string>", line 5, in foo
010 | ValueError: from foo 2
011 |
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/yobubenuho
!e ```python
def foo():
try:
raise ValueError('from foo 1')
except:
raise ValueError('from foo 2')
def do_something():
try:
raise RuntimeError('from handler 1')
except:
raise RuntimeError('from handler 2')
try:
foo()
finally:
do_something()
@paper echo :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in foo
003 | ValueError: from foo 1
004 |
005 | During handling of the above exception, another exception occurred:
006 |
007 | Traceback (most recent call last):
008 | File "<string>", line 14, in <module>
009 | File "<string>", line 5, in foo
010 | ValueError: from foo 2
011 |
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/luseholehu
nice
π€¨
your discovery is still interesting @tacit hawk, it feels better to have direct access to language behavior without relying on special syntax
Can you summarise the discovery? that's a lot of backlog to read
look at the "full output" in the last eval
see how it "chains" the exceptions from foo and do_something?
they figured out how to take 2 exception chains and manually concatenate them without relying on try/finally, raise, etc
the try/finally is really the way to go for what I need
huh - i think this is beyond me
so
def make_chain(name):
head = Exception(f"I am the {name}'s head")
body = Exception(f"... I am the {name}'s body ...")
tail = Exception(f"I am the {name}'s tail")
body.__context__ = head
tail.__context__ = body
return tail
chain_a_tail = make_chain('Chain A')
chain_b_tail = make_chain('Chain B')
def extend_exception_chain(e1, e2):
head = e2
while head.__context__ is not None:
head = head.__context__
head.__context__ = e1
extend_exception_chain(chain_a_tail, chain_b_tail)
raise chain_b_tail
should be equivalent to
def make_chain(name):
head = Exception(f"I am the {name}'s head")
body = Exception(f"... I am the {name}'s body ...")
tail = Exception(f"I am the {name}'s tail")
body.__context__ = head
tail.__context__ = body
return tail
chain_a_tail = make_chain('Chain A')
chain_b_tail = make_chain('Chain B')
try:
raise chain_a_tail
finally:
raise chain_b_tail
...i think
actually no
this is making my head hurt i have to get back to work
why isnt it doing it here π€ or do i need to raise the head of chain b in finally?
seems like not
@paper echo
def handle_exc(task):
try:
task.exception()
except:
do_something()
raise
else:
do_something()
by replacing task.result() by task.exception() you have the case where task has no exception
if there is no exception, task.exception() is just None. i made the mistake of not awaiting foo, unrelated
its just a crappy version of try/finally lol
hah
@red solar basically if you raise exceptions in try then your code in finally also raises exception(s), they all get chained together nicely
why try/finally did not worked for manually crafted chain
oh cool π
why this works?
try:
try:
raise Exception(f"I am the Chain A's head")
except:
try:
raise Exception(f"... I am the A's body ...")
except:
raise Exception(f"I am the A's tail")
except:
try:
raise Exception(f"I am the Chain B's head")
except:
try:
raise Exception(f"... I am the B's body ...")
except:
raise Exception(f"I am the B's tail")
replacing except by finally works as expected
ah I got it
the chain only happens if __context__ of the raised exception is None
inside the except/finally block
def make_chain(name):
head = Exception(f"I am the {name}'s head")
body = Exception(f"... I am the {name}'s body ...")
tail = Exception(f"I am the {name}'s tail")
body.__context__ = head
tail.__context__ = body
return tail
chain_a_tail = make_chain('Chain A')
chain_b_tail = make_chain('Chain B')
try:
raise chain_a_tail
finally:
raise chain_b_tail
but here I think chain_b_tail.__context__ is set to chain_a_tail so part of chain b is lost
but why the same does not happens for the example above since raise Exception(f"I am the B's tail") is technically chain_b_tail
hm
do if statements really bog down a program's speed?
not really, no
there's an idea of branchless programming, but it's a bit overblown and more relevant to languages that are jitted or traditionally seen as compiled I think
doodspav@doodspav-laptop:~$ cat t.py
def straight():
a, b = 5, 7
return a
def branchy():
a, b = 5, 7
return a if a > b else b
def branchless():
a, b = 5, 7
return (a > b) * a + (a <= b) *b
doodspav@doodspav-laptop:~$ python3 -mtimeit -s"import t" "t.straight()"
5000000 loops, best of 5: 90.5 nsec per loop
doodspav@doodspav-laptop:~$ python3 -mtimeit -s"import t" "t.branchy()"
2000000 loops, best of 5: 110 nsec per loop
doodspav@doodspav-laptop:~$ python3 -mtimeit -s"import t" "t.branchless()"
2000000 loops, best of 5: 163 nsec per loop
an example
that's not about branching - those functions are just doing different things. You can probably see that if you dis.dis() them
branchy adds a conditional, and branchless does it without a branch π€·
i don't see how this isn't about branching
ofc they're doing different things, one has branching and two don't
Python is too high level to consider it like that, it does checks all over in the C code
lol whenever i write a C extension, i spend more time parsing and validating arguments than actually doing C stuff
besides, that is a predictable branch, so it is pretty much free. Desktop CPUs guess what the outcome of a branch is, and if they are right, it is a fast branch, but if they are wrong, it is more expensive. It can be demonstrated like so:
In [144]: a, b = [random.randint(0, 1) for x in range(10000)], [0 for _ in range(10000)]
In [145]: %timeit [x for x in a if x]
420 Β΅s Β± 33.4 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each)
In [146]: %timeit [x for x in b if x]
251 Β΅s Β± 3.53 Β΅s per loop (mean Β± std. dev. of 7 runs, 1000 loops each)
``` (not sure if it is entirely due to branch prediction though)
I would argue the differing variance could be explained as branch prediction doing its best
(374259022687109120, 'hola', '2020-07-22 23:17:00')
(374259022687109120, 'hola', '2020-07-22 23:17:00')
how i can acces to " '2020-07-22 23:17:00')" with [2] not found
Are you sure you're not forgetting to grab the actual row out of that?
because that looks like a list of tuples
where you'd need to do a for loop, and then a [2]
i do type() and get list @torpid bridge
Yes. If you need more of an explanation try opening a help channel via #βο½how-to-get-help , because this isn't really the channel for this
okay thanks
do if statements really bog down a program's speed?
@devout kelp are you doing something performance critical?
You guys can talk over this. @grizzled vigil how do i get a bpo number for my commit?
It should just be your issue number at bugs.python.org (bpo for short)
ohhh
I take it you're talking about https://bugs.python.org/issue41371
yeah
So bpo-41371
so i open an issue, and then add my PR with that bpo, and link it to the issue once i've made it?
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.at.html
i don't really see the point in this when .loc exists and does exactly the same thing
Use at if you only need to get or set a single value in a DataFrame or Series
@magic python i think theoretically it does less work in trying to infer whether the argument is a "single value" or not
if you use df.loc[ x, y ] you'll get a single tho π€
which theoretically means it's faster
hrm
if you're doing it in a hot loop for example... idk how effective it is
i was wondering whether there was some multiindex jazz i was unaware of
fair, i'm also unsure of the order things were added in , so maybe loc was after but they left this in
or maybe it is actually loads faster for some things
it's a pretty old part of the API
i use it in several places just for clarity
when i want to indicate unambiguously to the reader that i am getting a single value
DataFrame.lookup is analogous to indexing a numpy array with two 1-d vectors
print( inspect.getsource( df.lookup )) has more info π€
welcome to pandas
given that we are in #internals-and-peps , it is a great example of how messy developing a DSL can be
π so is this something that's on the way in - or on the way out?
neither
lookup that is, oh
Label-based "fancy indexing" function for DataFrame
fancy apparently, idk what that means tho
yes by analogy to numpy's "fancy indexing"
horrible docstring lol
it's like INDEX in excel actually
...kinda
x_np = np.arange(9).reshape((3, 3))
print(x_np)
print(x_np[[0, 2], [0, 2]])
x_pd = pd.DataFrame(x_np, columns=['x', 'y', 'z'], index=['a', 'b', 'c'])
print(x_pd)
print(x_pd.lookup(['a', 'c'], ['x', 'z']))
print(x_pd.loc[['a', 'c'], ['x', 'z']])
k = pd.read_json('{"PassengerId":{"0":1,"1":2,"2":3,"3":4,"4":5},"Survived":{"0":0,"1":1,"2":1,"3":1,"4":0},"Pclass":{"0":3,"1":1,"2":3,"3":1,"4":3},"Name":{"0":"Braund, Mr. Owen Harris","1":"Cumings, Mrs. John Bradley (Florence Briggs Thayer)","2":"Heikkinen, Miss. Laina","3":"Futrelle, Mrs. Jacques Heath (Lily May Peel)","4":"Allen, Mr. William Henry"}}')
k.lookup(row_labels= [0,1], col_labels=['Survived', 'Pclass'])
returns array([0, 1])
In [11]: k
Out[11]:
PassengerId Survived Pclass Name
0 1 0 3 Braund, Mr. Owen Harris
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th...
2 3 1 3 Heikkinen, Miss. Laina
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel)
4 5 0 3 Allen, Mr. William Henry
I expected a subset of the df for some reason
k.lookup(row_labels=[0,1], col_labels=['Survived', 'Pclass'])
is equivalent to
np.array([
k.at[0, 'Survived'],
k.at[1, 'Pclass']
])
does that clarify at all
(also this should be in #data-science-and-ml probably)
yea it does - cool
also you might as well .set_index('PassengerId'), no?
idk - just have that in memory for all ipython sessions
@devout kelp are you doing something performance critical?
@boreal umbra
I'm running a discord bot, and I just wanna make sure that if by some miracle it becomes really popular, it won't get bottlenecked by my code. As far as I'm aware it doesn't matter, but I want to be sure
a discord bot will not be affected by if statements enough to matter
parsing the websocket messages coming from discord is too expensive for trivial optimalizations like that to matter
Is discord.py pure python?
seems like a good #discord-bots question, no? π
but i believe it all is, yes
i dont see why they'd have a c extension in there
ok there is a libopus dll in there
i guess for playing audio on windows
Optimization, I guess. Though we make our bot do a lot of work and it seems to handle it just fine.
the bottleneck is all network requests
so optimization would have to be algorithmic instead of just using a "faster" language
Makes sense
the http itself is handled by aiohttp
and im pretty sure that uses the low-level async networking features that ship with asyncio, underneath
My friend who hates python said that python is terrible for web development because of the speed, but idk if that's true.
ah no that one does use cython
terrible for web development because of the speed
it really depends
the cpython runtime is significantly slower than, say, go
therefore you might need to be more aggressive about using things like threads, processes, etc.
or about having multiple servers deployed w/ load balancing
you need to be very large scale before your web application becomes CPU bound rather than IO bound
and honestly, I do not believe that you can write code such that it will handle that scale in reasonable time when you do not have the budget that comes with that scale regardless
I see
it's not exactly standard web dev, but sometimes latency is important, and in those cases python might just not be fast enough π€·
ye, there are some cases where it would matter.
The reason I bring it up is because I feel like a lot of people get preoccupied with microoptimizing Python at the cost of readability
lol i just moved to C++
do you explain to them that generally it's not the best course of action?
If you have a function that returns an object, and you call the function in a print statement, does the object disappear after the print statement executes?
Yes
(Unless itβs referenced elsewhere, e.g. also stored in a class instance, and the function was a class method)
thank you
It doesn't necessarily disappear immediately after the print statement. If it is no longer referenced by any variables it will eventually be garbage collected, but if it's part of a reference cycle that could happen arbitrarily far in the future
And some implementations of the Python language use garbage collection for all objects (as opposed to CPython which collects most objects using reference counting)
good morning, i read a txt.file on windows with into the program, i encoded with utf8. Now i figured out that a value (str) is in unicode...any idea why or how this happened?
@unkempt rock better to use a help channel where you can share the code and output
I am using a library that returns objects to the query statements. Would it be preferable to alter the code to write to a database, or to keep the program intact and parse the objects to the database instead?
if this is the wrong channel for this, let me know
Yes, you should ask in an available help channel. See #βο½how-to-get-help
i will do that then, thanks
?help
@ashen coyote see #βο½how-to-get-help
Hey everyone, I am pretty confused with my code here. I am trying to loop the number of canteen drinks until it goes 0, once it's 0 I want to print the error. What am I doing wrong here?
canteen = 3
done = False
while done == False:
choice = input("choice :")
try:
if choice == "a" and canteen>0:
canteen-=1
thirst=0
print("You have ",canteen," drinks left")
except Exception:
print("error")
this is not the right channel for help
which channel should I go to for help?
You can see how to claim a help channel in the #βο½how-to-get-help channel
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':11, 'Queen':12, 'King':13, 'Ace':14}
suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
class Card:
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
self.value = values[rank]
def __str__(self):
return self.rank + ' of ' + self.suit
class Deck:
def __init__(self):
self.all_cards = []
for suit in suits:
for rank in ranks:
card = Card(suit,rank)
self.all_cards.append(card)
def shuffled(self):
shuffle(self.all_cards)
def get_one(self):
return self.all_cards.pop(0)
class Player:
def __init__(self,name):
self.name = name
self.all_cards = []
def remove_one(self):
return self.all_cards.pop(0)
def add_cards(self,new_cards):
if type(new_cards) == type([]):
self.all_cards.extend(new_cards)
else:
self.all_cards.append(new_cards)
def __str__(self):
return f'Player {self.name} has {len(self.all_cards)} cards.'
my_deck = Deck()
get_card = []
for i in range(0,10):
get_card.append(my_deck.get_one())
my_player = Player('chinu')
print(my_player)
my_player.add_cards(get_card)
print(my_player)
print(get_card)```
why am I getting output like [<main.Card object at 0x00937400>, <main.Card object at 0x02D870B8>]
@mighty hound please see the message right above yours
yes
yes
@mighty hound because "get_card" is a list of objects
so what happens when we print a list of objests @wicked socket
you print out the memory location of the object.
try to break it down a bit. it will help with debug.
for i in range(0,10):
card_value=my_deck.get_one()
get_card.append(card_value)
then look at card_value. is that what you want?
instead of print(get_card)
try
for x in get_card:
print(x)
i think thats what you're looking for.
well got to go.
see all of you.
hi umm i had a bot working a week ago and now it suddenly stopped working does anyone know what changed? btw im using python 3.5.4
This isn't a help channel. It sounds like you're asking about a Discord bot, so #discord-bots. If not, then #βο½how-to-get-help
I want to ask, Python has a lot of functions, so is it important to remember all?
not massively
You'll remember the important ones as you learn because you'll use them often, for the rest you can just roughly remember that they exist and what their purpose/location in the stdlib is and google the rest of the details
Is it weird to break up a decorator on several lines?
Mine is starting to grow...
@tinker_command(alias='v', fileinfo=FileInfo(mode='w'), pass_slice=True, overwrite_returned=False)
Something like a
@decorator(
arg1=...
arg2=...
)
...```should be PEP8 compliant
Yeah, just so it doesn't look unnatural, I haven't really seen "big" decorators used in the real world
Ye
You need to write regex that will validate a password to make sure it meets the following criteria:
At least six characters long
contains a lowercase letter
contains an uppercase letter
contains a number
I try but I can't so Please tell me regex
@pure orchid this isn't the right channel. You'll have better luck in a help channel, see #βο½how-to-get-help for that
Where would i send libaries errors, I cannot find a fix for like 2 weeks, I tried sending the error to help channels like 5 times, never got a answer, even if I did i got asked if my pip is uptodate. I'm trying to pip install pyrebase, and I've upgraded my setuptools
You are not allowed to use that command here. Please use the #bot-commands channel instead.
Hi, so I started programming using python not too long ago, and I understand the basics and a bit more, is there anything that could be suggested for me to do to increase my skill in Python?
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
@mild grove
Thank you @broken egret
Hi, what's the reasoning behind something like a = [1] ; [s] = a - somehow i feel this is related to Python's C innerworkings.
That is called unpacking
yes ok, but isnt it more readable doing s = a[0]
It is mostly useful to do a, b = (1, 2)
Unpacking just one is mainly useful with sets, though you can also use pop there
ok let me ask this differently - which is more encouraged, pythonic? if a = [1] ; [s] =a or s = a[0]
I would say it depends on the context. They have different semantics, as [s] =[1,2] errors while s = [1,2][0] does not. Either is fine in most cases
ok thanks! that really helped.
if your function received e.g. a tuple (a, b) and you will be accessing both elements a lot it may make sense to first unpack it:
a, b = my_tuple
then you can just refer to them as a and b rather than my_tuple[0] and my_tuple[1], and of course instead of a and b you can give them descriptive names that will self-document your function, i.e. name, age = user
in other cases, however, if you just want to grab something once by index, it probably makes more sense to just do that rather than unpack the whole thing
you can also come across a case where you receive a set with 1 element and you want to assign it to a name, which is tricky because sets arent subscriptable
so you may come across unpacking as you have shown
>>> my_set = {'cat'}
>>> [animal] = my_set
>>> animal
'cat'
>>> my_set[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
hey guys i am a begginer pls tell some cool things you can do
how to import MONGODB?
hey guys i am a begginer pls tell some cool things you can do
@safe cliff discord.py?
lots of lists of project ideas out there, look through and see what grabs your interest imo. here's one you could start with https://github.com/karan/Projects
also, obligatory, this isn't really the right channel for that kind of question, maybe try python-general next time
Either #python-discussion or a help channel would be more appropriate for these questions please
[animal] = {'cat'}
so does this still classify as a tuple unpacking or is it something different
Just normal iterable unpacking
internally it's still just an unpack sequence, yea just looked it up
how come dis doesn't support dissasembly of builtins?
They are implemented in C and aren't compiled as bytecode
Aaa
They call internal C code yeah
π€
Can I name my own attributes with the __varname__ pattern or should I stick to _varname? Say I have a base abstract class that internally uses these dunder __attributes__ but I would like to sort of communicate to people that implement subclasses to only override single underscore _attributes.
Uh. Your convention seems to be off
Conventionally, names with a single leading underscores are understood to be "do not touch" territory
Conventionally, names with a single leading underscores are understood to be "do not touch" territory
@visual shadow Yes, but does that go for external uses of the class. What about subclasses?
same
The person making the subclass is someone else, yes?
So instead I should rather rename the attributes I expect subclasses to override without underscores and that's it
Double leading underscores do name mangling: good for signaling that this is safe to redefine while keeping the original implementation safe.
Dunders on both sides however, you shouldn't be using much. It denotes usually some kind of behaviour close to pythons data model.
The devs used dunders so you don't have to.
usually for building your own framework
new dunders shouldn't be created by users, they are reserved for python
false
Double leading underscores do name mangling: good for signaling that this is safe to redefine while keeping the original implementation safe.
@visual shadow I've considered it, but I'm using a metaclass to inject default attributes into the subclasses at definition time and doing some weird mro() stuff to keep them cleaner.
It's a sort of StateMachine framework
I suppose just avoid the single leading underscore name, that's the one thing I can vouch for. Breaks convention, would lead to confusion.
can also use init_subclass sometimes instead of meta
Beyond that I don't have a good opinion of what you should do instead.
salt https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers, nobody's stopping you from using them but they have a clear meaning and things will break if you do use them and the implementation decides they need that dunder
can also use init_subclass sometimes instead of meta
@deft pagoda Yes, but I wanted to extract defined attributes of subclasses without the attribute resolution of parent classes
why would they break
why would they break
@deft pagoda Newer python versions might define new__attrs__without caring for your code
that wouldn't overwrite what i had in my class
The thing is, I wanted to have special class attributes that are supposed to be overridden by subclasses, but at the same time be sort of private to external users of the classes.
that wouldn't overwrite what i had in my class
@deft pagoda What if they add a new__slots__sort of thing?
another slots?
No it wouldn't overwrite what you had, but you overwrite the behaviour which could be called internally somewhere now
One of the beauties of Python, they refused to turn a lot of these into keywords. I didn't understand it at first but it makes sense now. The fact that you're able to freely overwrite a lot of stuff in python means codes that were created in the past to use some names will simply shadow and keep working within the expected usage.
i've propose similar of kivy framework with __KV__ dunder to automatically load kv files for widgets, which i think is fair use
And there's still the thing that dunders have a clear meaning as being specific to the datamodel
this loading happens in the meta, so it's data-model-like behavior
i just find dunders easier to remember in frameworks
well, probably they'd use lowercase
tbf, i never addressed issues with unloading kv files for parent widgets
So, say I have my StateMachine class. It already has its own metaclass to do "magic" stuff. I want to have an optional machine_type class attribute, that when defined in a subclass, gets picked up by the metaclass and stored in a dictionary, so that I can have an utility function that does build_state_machine_by_type(...). I wouldn't want users to override machine_type after class definition, that would mean it doesn't match with the mapping anymore. And AFAIK you cannot use properties for class variables.
i think you can take care of that in a meta init
well, honestly, could do it in __new__ too
@peak spoke dunders are used by a handful of 3rd party libraries, eg attrs. I think they are OK if designed judiciously
@peak spoke dunders are used by a handful of 3rd party libraries, eg attrs. I think they are OK if designed judiciously
@paper echo It still feels wrong IMO.
I think for my case I'm gonna go with the class decorator approach
He's just saying in general. Not specific to your case
I know
And sounds like a plan. Go for it
Some use it, but I don't particularly like it. If they need to avoid name collisions then __ prefix name mangling is there exactly for that
registrar = {}
class Meta(type):
def __new__(meta, name, bases, methods, **kwargs):
registrar[name] = methods['prop']
del methods['prop']
return super().__new__(meta, name, bases, methods, **kwargs)
class Sub(metaclass=Meta):
prop = 'some prop'
something like this would register then delete the attribute
Hmm. Interesting approach
something like this would register then delete the attribute
@deft pagoda I think I have a similar use case exactly for this. Thank you
np, you could alternatively use kw-args in the class definition
not many people do that
i've only made one toy class that does
it was this neat enum:
In [5]: class Fruit(Enum, start=10, step=15):
...: APPLE
...: BANANA
...: KIWI
...:
...: print(Fruit.APPLE, Fruit.BANANA, Fruit.KIWI)
10 25 40
Weird. The last time I subclassed Enum was to make the constructor accept the attribute name instead of the int to return the enum instance. This way I could serialize/deserialize them keeping readability.
this was a custom enum, so you don't have to actually assign values to the names
the lazy-man's enum
Doesn't enum.auto() take care of that?
using weird defaultdict-like dicts in metas is really fun
@strange fog you can't fix ```py
def load_lists(self, some_argument = self.something):
...
problem in a simple way, because already existing code in Python relies on the fact that expressions inside function headers are evaluated once.
@peak spoke
The least it would need is making self a special name, which it isn't
i think self is a ubiquitous enough name that it wouldnt be too weird to implement this check specifically for method signatures
Then there's the cost of doing that behaviour every time the function is bound/called
no, it would only happen once when the method code is parsed
Another thing is, what should that even mean? Should some_argument equal the value self.something had at the moment of creating the method, or should it point to that attribute
I see
Methods are functions, you can't do that when it is parsed because self doesn't reference anything special and is only bound on attr access
my idea is that the compiler would replace the default value with None, then generate the necessary bytecode to take care of it, place said bytecode at the start of the method code
I think it can already be done perhaps, let me think of a way
the question isnt one of whether it can already be done or not
Because first of all you could do this: py class MyClass: def load_lists(self, some_argument = MyClass.something):
just thought it might be an interesting conveniency for the interpreter to handle
but then renaming the class forces you to replace its name in multiple places
that's not the same. class attributes are not instance attributes
But you said you want it to be what it was at the moment of creating the method
which happens before any instance of the class exists
youve entirely misunderstood my point then.
@strange fog Maybe #esoteric-python could make a decorator for that
The thing is, if I understand your point in another way, it becomes an invalid point in a different way
It is a question whether it can be done without sacrificing speed or referencing normal names as the default value
Sometimes mutable default args are used for a (mutable) cache, so that wouldn't really work.
Yea, but he doesn't want to make the expression evaluate each time, he wants to be able to access self at the moment of creating the function
which makes sense only as a way to access the class attributes, because no instance yet exists at the moment of creating a function
what im saying is that it could be cool if the interpreter automatically turned this:
def some_method(self, arg=self.default_value):
pass
into this
def some_method(self, arg=None):
if arg is None:
arg = self.default_value
at parsing time
just some conveniency
I wouldn't want that conveniency
ok, that's fine. it's just an idea. you can calm down now.
I am calm. π€
You can use inspect to inspect and change the function's default arguments.
Then make some kind of decorator
import esoteric as e
@e.transform
def some_method(self, arg=e.self_getattr("default_value")):
...
equivalent to:
import esoteric as e
def some_method(self, arg=e.self_getattr("default_value")):
if e._is_esoteric(arg):
arg = e.evaluate(arg, self)
again, i dont doubt that it's already doable through ways like that
nice, I was thinking about something like this, but likewise couldn't you make a decorator which would set self so that you can do arg = e.self.default_value ?
yes, that's possible as well
def attr(arg, attr):
def inner(fun):
return Desc(fun, arg, attr)
return inner
class Desc:
def __init__(self, fun, arg, attr):
self.fun = fun
self.arg = arg
self.attr = attr
def __get__(self, inst, own):
return lambda *args, **kwargs: self.fun(inst, *args, **{self.arg: getattr(inst, self.attr)}, **kwargs)
class A:
def __init__(self):
self.default = 8
@attr('arg', 'default')
def some_method(self, arg):
print(arg)
```would also be an option (adjusted to support multiple naturally), perhaps even `attr.default('arg')` which is easier to type, but not as clear
@strange fog i wrote a utility function to do this
im not concerned with whether it's already doable or not
i dont think it makes sense
just thinking that it might be something the interpreter could handle
what if None is a valid value?
then it wont make a difference
you can use something other than None as the default placeholder
some special object
it would make the function descriptor quite complex
and it would differentiate functions and methods
ok i can see that. @flat gazelle no reason not to use it for functions too
presumably it would be "scoped" to include the names of function parameters as well as the enclosing scope
R actually has this, arguments can be omitted leading them to be missing
I think if Python were to change its behavior in this regard, there's probably better ways to achieve that, like with a new keyword - I know that Python devs want to avoid introducing new keywords, but it seems way better than an obscure underlying logic.
I guess something like
def fun(arg1, arg2=arg1 + 3):
...
```is not impossible, but it then means the default arg has to be recomputed
missing can be used to test whether a value was specified
as an argument to a function.
which would make default args more complex, whereas now they are just in a tuple/dict
yeah implementation would be significantly more complicated
as far as i can tell python mostly does not have the ability to capture unevaluated expressions
again, compared to R, which does and does so regularly
would it not still be tuple/dict? just now the dict value is a closure?
the dict value is an expression
The point is to just convert arg = self.something into arg = None, and then prepend additional opcodes to check if arg is None, and if so, assign it to self.something (which I find weirdly obscure)
which is inserted above the function body
python cannot store expressions, even comps use essentially functions
or if arg is MissingArgument
so it would make every default arg into another function.
no i don't think this is tied to self at all @south pumice . the idea is to capture an expression on the RHS with some funky scoping rules, then assign to the parameter using the value ot the expression evaluated at runtime
I'm referring to this example: https://discordapp.com/channels/267624335836053506/709904092280914030/735848651041144885
@paper echo if arg is MissingArgument exactly. and the MissingArgument singleton should not be accessible through conventional means. maybe through some ctypes fuckery. but anyone who does it is at their own peril.
def f(x, y=x+2):
return x, y
f(3) # 3, 5
f(3, 10) # 3, 10
@south pumice this would be a more general version
i personally hate it and think it has no place in python. but i think it's interesting from a language design perspective
@paper echo if it is about capturing the expression, then it breaks backward compatibility (well it does so anyways), but I made that point earlier, before the example linked above
it's really about 2 things
that seems like there would be some weird edge cases
That leads me to the question, what if 2 default args refer to each other?
- capturing the expression
- a new
MissingArgumentsingleton that is automatically passed when a kwarg is omitted
2 is minimally necessary to eliminate the mutable default argument trap and the if kwarg is None idiom
1 is just fun and expands the scope of cases that 2 can cover
It's about
- evaluating expressions in function header at call time vs current function object creation time
- being able to access an earlier argument, by the latter argument.
no it has nothing to do with self
yea let me fix that
it cannot work with self specifically, that has too many edge cases
accessing self is a special case of 1
it should be generic across all args
@south pumice those are 1a and 1b imo
def func(x,y=x+z,z=x+y):pass
you could just raise UnboundLocal there
^
note that MissingArgument by itself doesn't solve much of anything without delayed evaluation:
def f(x, l=[]):
pass
without delayed evaluation, the kwarg default is still a single [] shared by all invocations of f
But where would the error raise from?
Cause if z=x+1 instead of y then itβs able to evaluate
then kwargs are order sensitive, which is inconvenient
right
my idea was that the evaluation would happen at the start of the function. the interpreter would automatically inject the necessary bytecode into function body @pliant tusk
@paper echo however, abjadd specifically clarified he's not interested in accessing self as in the Class, and an instance doesn't exist at the point of creating a method, so it indeed is about delaying/repeating that expression, but in the way he later clarified, he means for Python to do kind of preprocessing, to convert code to something different (which would show on printing the code by inspection for example)
Itβs definitely doable with a decorator
accessing attributes of self is just one application thereof
Etherlord, with due respect, I don't think you understood what I was going for, so please don't speak for me.
see my above snippet with a decorator that does this
Oh I was thinking even to extract the default args from the original signature
right, one limitation of my with_default decorator is that the default arg still can't access other parameters
My advisor gave me a regular expression with like a dozen instances of (.*?), and it's taking way longer than another regex I wrote that was more specific (but was pulling the wrong info, also I think it's 2GB of text)
I guess lots of instances of (.*?) make it difficult to determine when a given string is a non-match?
This is the reason why your regular expression takes forever, or crashes your program.
@boreal umbra ^
I might switch to iterating over each line and checking if the two critical substrings are in the line, and if they are, use the regex to pull out what I wanted.
I assume that would be faster in this case?
probably? hard to say without seeing the text and the regex
you can always debug with regex101.com
they have a python mode
I usually use pythex
however my advisor is really into perl so I want to assume that her regex is great
i have bad news for you
what
re: perl & code quality π
oh I can't even look at perl
more seriously i assume your expressions are something like thing-i-idont-need(.*?)other-thing-i-dont-need?
looks like the program actually finished at some point but my ssh connection went wrong and made it look like it was frozen
ah
yeah personally i much prefer processing data by line if that makes sense for your data format
or breaking it into "pieces" whatever the pieces might be
my uncle is a developer and perl used to be his favorite
but a combination of factors (including myself) caused him to see the light of Python
hmm random thought, what if <> could denote sets instead of {}
for what?
Not likely
and it's easy to know which one you're looking it.
but they also represent dicts, so you cant create an empty set with brackets afaik
though I admit that having to use set() to create an empty set is a bit unfortunate.
When you have a stand alone < or >, it's going to be assumed it's an operator in most contexts
you have to do foo = set()
Sure, but that's a miniscule timeloss
no its not a pressing issue whatsoever
it actually makes sense that dicts and sets would both use curly braces though
Both being hashmaps, yeah
they both rely on hashing to be a collection of unique objects
true
but dicts are a mapping
<> should probably not be braces as a < b, c > d would be extremely ambiguous
hmm, you cant change it now but ```py
foo = {} #set
bar = {:} #dict
^ is that really a thing? Okay welp
obviosuly thats a horrible breaking change
I think {:} would be confusing for learners
Especially when sat near slices
most learners don't even know about sets or have a need for them.
i mean how is that any more confusing then anyother py stuff
I'd rather go with {,} for sets than change the literal for dicts
I don't think it would be a breaking change to allow {:}, but the parser won't like that for sure
set == set(), dict == {}
False, False
Well played
{,} and such are just unnecesarry tbh
the discussion is how having to do set() is unfortuante
its not a big deal
but it does feel a bit odd imo
I mean... how often are you having to make a set compared to any other container type?
cuz you have such nice options for lists and dicts
there have been a few other instances of people suggesting <> as a new kind of enclosure
I think set() is fine, but if we were to introduce a literal for empty sets, I'd rather use {,} than {} for sets and {:} for dicts
I remember seeing it suggested for multi-line lambdas
ohh i like that
lambdas are best used sparingly
^
lambda foo: <
print('hi')
print(foo)
>
and if you need one with more than one expression, chances are that's not sparing
ya python doesnt really lend itself to that, its more work then its worth with indentation errors
What benefits do you get from a multiline lambda that you don't from a standard function definition?
Technically being able to create an empty dict using {:} would be faster than dict() (one less function call)
its nice in langs with { } cuz you can just organize it how you want
@undone hare But it would break EVERYTHING
yeah this is one of those conversations where i say "just use a different language"
as much as i love python
a few extra clock cycles π
it has limits
Why though
making comparators in Java using an anonymous class makes me want to smash my computer
I don't see what would break here
@undone hare Existing code?
{:} isn't parsing right now, right?
thanks
That's a major level change you're proposing. Correct, but if you're moving the {} to be a set, you're going to break everything that expects it to be a dict
streams are nice, they finally got linq
{:}isn't parsing right now, right?
I think it's a syntaxerror
!e
my_dict = {:}
@boreal umbra :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | my_dict = {:}
003 | ^
004 | SyntaxError: invalid syntax
Yeah, so nobody is using it, so no breaking changes 
ye
No, again
the idea is to change what {} means to set()
lol
as well as introduce {:} for dict()
Exactly
i like {,} the best personally
You're not just adding a second option for dict
very idiomatic
Sure but I don't find myself using sets enough to worry about the function call cost
Oh yeah, I'm a big dumby
isn't that creating a set with one empty tuple or something?
!e
my_set = {,}
print(my_set)
@boreal umbra :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | my_set = {,}
003 | ^
004 | SyntaxError: invalid syntax
() is an empty tuple
i mean yea, but not like that
!e print(())
@flat gazelle :white_check_mark: Your eval job has completed with return code 0.
()
don't think (,) is valid either though
Considering all the extra work () does, I still prefer to do tuple()
so there already is precedent for {,}
you cannot have leading comma in an enumeration
you need a comma for a one member tuple
Yup you can't
sorry, I think I was thinking of making a one-tuple
(true,)
ye, one tuple needs a trailing comma
vs (true) which is just an expression
heck, True, is enough
it parses the same when it works
some cases do need the () though, like when passed as an arg
I would think (True,) would be easier to parse because it doesn't have to account for the possibility that it's separating kwargs or list elements or something
the () only play a part at compile time though right?
Probably
so there should be no performance implications
>>> [a] = {1,}
>>> type(a)
<class 'int'>
>>> [a] = {(1,)}
>>> a
(1,)
Yeah my confusion was more about:
x = 1,
# vs
y = (1,)
you mean parsing-wise?
Si
!e
import dis
def test1():
return True,
def test2():
return (True,)
dis.dis(test1)
dis.dis(test2)
@visual shadow :white_check_mark: Your eval job has completed with return code 0.
001 | 3 0 LOAD_CONST 1 ((True,))
002 | 2 RETURN_VALUE
003 | 6 0 LOAD_CONST 1 ((True,))
004 | 2 RETURN_VALUE
looks like the dis are exactly the same for both
Interesting
bytecode it returns the same yea
Yeah it's the getting to the bytecode
Yeah, no performance hit in running it, but not sure about the step where the bytecode itself is being generated
To be honest, i don't even know where to find out something like that
now I'm wondering in what situation would one even use the empty tuple literal
maybe to compare against something that may be an empty tuple
but then you'd probably look at the len of it
That's.... actually a really good point
considering tuples are immutable, usually used to represent some collection of information about an item, i honestly would be surprised to find empty tuples in the wild.
maybe when passing them to a function that takes an iterable
Or returned
or as a default param
But yeah, just having them...
stuff that coerces things or makes tuples out of things perhaps.
you could end up in such a state if you were relying on the "sequence" itself being generated based on some matches or some other source
Could be useful in switch cases or the dict equivalent.
Actually Reason has unit which is just ()
For that same reason
So I guess I could see the merit in it
the ast for the 2 examples are the same
but for the parsing itself, wouldn't know tbh
!e
print(
{*()}
)
# ^ empty set
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
set()
the lexer obviously has more work (constants ofc), but good question how the parser handles it
is it more work or less
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
set()
I'm trying to iterate over a slice and create a dict based on the order of that slice. The first element of the slice becomes a key of the dict. The next element becomes its value and so on. The last element of the slice should get a value that I can assign later on.
Here is my current approach: https://bpa.st/NLAA
Got any advice? I have no idea what I'm doing π
And {} is the wrong value at the end
@gusty breach This is not a help channel, check out #βο½how-to-get-help
I see
print( {*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{}}}}}}}}}}}}}}}} )
```wut is this abomination π
{} is an empty dict
{*{}} is an empty set (unpacking syntax works in sets like it does in lists)
{*{*{}}} -- unpacking empty set inside another set
and, by induction...
an empty set. i thought everyone wrote empty sets this way!
to make it one byte shorter, you could define a global _

!e
_ = ()
print({*_})
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
set()
isnt there a set theoretical way to construct integers with things like {} = 0, {{}} = 1, etc?
or did i dream that
so```
0 = {}
succ n = n U {n}
there are also Church numerals:
0 = f -> (x -> x)
1 = f -> (x -> f(x))
2 = f -> (x -> f(f(x)))
3 = f -> (x -> f(f(f(x))))
...
in python, you would have to use frozensets
right, because normal sets aren't hashable
how to hash
LMAO
!ot You can talk about good quality herbs over here
Off-topic channels
There are three off-topic channels:
β’ #ot0-psvmβs-eternal-disapproval
β’ #ot1-perplexing-regexing
β’ #ot2-never-nesterβs-nightmare
Their names change randomly every 24 hours, but you can always find them under the OFF-TOPIC/GENERAL category in the channel list.
my_list = [[123, 456, 789, 50], [234, 567, 890, 100], [345, 678, 901, 150], [456, 789, 123, 30], [567, 890, 234, 70]]
output = []
for i in my_list:
output.append(i[-1])
len(output)
eo=[]
for ele in range(4):
if ele == 0:
eo.append(output[ele]+output[ele+1])
else:
eo.append(output[ele-1]+output[ele]+output[ele+1])
print("Expected Output - ", eo)
Not able to get the last element in eo list
getting output as below - [150, 300, 280, 250]
@heady scroll This is not a help channel. Use #βο½how-to-get-help to acquire help.
can someone help me with this, i know it's surely something stupid but the line of sort() doesn't work, when i remove it it work...
.sort returns None and modifies the original list
yup when i print it it prints None
sorted can be used to return a new sorted list like sorted(some_list)
yeah, that's how it works, it sorts the list in-place
okay, so i'm just dumb, i forgot that sorted() exists
You can use sorted, or copy the list yourself and apply .sort, or just sort it in-place if you don't need the original order
thx a lot, take care !
