#internals-and-peps

1 messages Β· Page 58 of 1

grave jolt
#

>>= :: a -> (a -> m b) -> m b
can_fail :: (a -> m b) -> a -> b

paper echo
#

you could write can_fail, then implement a monadic_bind that accepts a particular monad, no?

#

hm

flat gazelle
#

ah, =<<, not >>=

grave jolt
#

yes

#

I was wrong

#

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

paper echo
#

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

flat gazelle
#

typeclasses in python sound like a fun project. Probably not too useful though

#

well, I guess things like __int__, __bytes__ and such are "typeclasses"

grave jolt
#

that's an old version, but whatever

#

@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

flat gazelle
#

the term you will want to search are monad laws

grave jolt
#

(that's a euphemism for google it :) )

red solar
#
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

grave jolt
#

Yes, it is. You have to define either of those.

#

Or both.

red solar
#

ohhh

#

makes sense

grave jolt
#

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.

unkempt rock
#

does anyone happen to know any free courses for backend development using python?

grave jolt
unkempt rock
#

alrighty ty

next epoch
#

behold, my cursed code

#
return lambda: (player.add_item(item, amount), player.money -= cost)```
flat gazelle
#

player.money -= cost as an expresion should not compile

next epoch
#

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

grave jolt
#

Why are there no asynchronous lambdas? lemon_thinking

minor sinew
#

because it sounds like a good way to not make friends

narrow kettle
#

C# has them, works out fine tbh

#

But i mean it just generates an async method, hardly something interesting

languid dagger
#

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

narrow kettle
#

Very true oc

#

Would be much less useful in py lambdas

grave jolt
pliant tusk
#

You can make asynchronous lambdas if you need them

mint forge
#

what is the use of django

dire mesa
#

a framework to build modern website, thats all

visual shadow
#

Backend for websites, yep.

true hollow
#

Why are there no asynchronous lambdas? lemon_thinking
@grave jolt yeah, we need an async lambda GWseremePeepoLife

torpid turret
#

Hey, are we able to ask for help in here?

brazen jacinth
torpid turret
#

Ahh okay, thanks πŸ™‚ new to py, so questions already coming from js.

brave badger
#

async lambda may be a bit unintuitive cause it already borders around the concept of an "anonymous generator" from how I see it

mossy drift
#

What app or website should I use for python?

lofty rover
#

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 πŸ™‚

slim island
#

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?

brave badger
#

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

unkempt rock
#

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?

mint forge
#

who can use django and what is django used for

slim island
#

@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

peak spoke
#

Does the annotations future import only affect the module it was imported in or all modules loaded after that?

buoyant skiff
#

How to convert [1,2,3] to [[1,2,3]] using numpy ?

cedar glen
#

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

odd ether
#

a = np.expand_dims(a, axis=0) also works

jovial oyster
#

a = a.reshape([1, -1])

unkempt rock
#

guys

#

i need help

#

im going to do a extension program for computer science

#

so i wanna learn python

#

can someone teach me basics?

tawny shoal
#

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

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

unkempt rock
#

okkokkkkkkkkk

violet galleon
#

Shop={'Apples':'2', 'Bananas':'5'}
Print(Shop)s

Why do we need a s after the parenthesis

cloud crypt
#

that's invalid syntax?

tawny shoal
#

I don't think you do yeah

cloud crypt
narrow kettle
#

that wont run lol

last pollen
#

@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?

red solar
#

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 :/

last pollen
#

I'm still not sure what you mean

#

you have a list of commands, then?

red solar
#

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?

last pollen
red solar
#

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 :/

brazen jacinth
#

just like fizzbuzz, you match the largest denominator first

red solar
#

^^ idk why I explained it so badly originally

torpid wolf
#

How do you call current-level methods in an inheritence chain, when you are calling super().init()?

flat gazelle
#

self.method()?

torpid wolf
#

that calls the child's method

brazen jacinth
#

super().method()?

#

what do you mean by current level methods

torpid wolf
#

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

brazen jacinth
#

you need parents to call child methods?

torpid wolf
#

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

flat gazelle
#

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?
torpid wolf
#

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()

flat gazelle
#

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.
torpid wolf
#

ok thank you I'll try this, that makes sense

unkempt rock
#

what is the use of ord()

brazen jacinth
#

i think it string characters to their number counterpart

#

utf-8* unicode*

#

inverse of chr()

unkempt rock
#

correct

#

but why would you use that in a proram

spice pecan
#

You're not going to need it most of the time

peak spoke
#

When you work with keyboard modules, you want the codepoint for lookups etc

brazen jacinth
#
>>> "".join(chr(i) for i in range(97, 97+25))
'abcdefghijklmnopqrstuvwxy'
#

why not πŸ€·β€β™‚οΈ

spice pecan
#

you're missing z

brazen jacinth
#

why need in python, we have assembly anyway

late quiver
#

hi

brazen jacinth
#

it's the factor of convenience πŸ˜›

spice pecan
#

also, from string import ascii_lowercase

brazen jacinth
#

you get my point

#

wouldn't be shocked if that's how it's implemented underneath

late quiver
#

how to use python

brazen jacinth
#

!resource

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

late quiver
#

i will use kali linux

brazen jacinth
#

not the right channel for it @late quiver

late quiver
#

oh

#

im new here

brazen jacinth
peak spoke
#

It's a simple literal underneath

spice pecan
#

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

flat gazelle
#

yes

paper echo
#

is collections.abc being unified with typing in 3.9? or just "builtin" collection types like list and dict

peak spoke
#

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

paper echo
#

feels bad

#

need to use collections.abc.Sequence for runtime checks and typing.Sequence for static checks

#

v unpleasant

peak spoke
spice pecan
#

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
magic python
#

is there anything that dictionaries can do that an attr class can't?

peak spoke
#

Use their methods directly

magic python
#

hrm - what's an example of that? Like pop and stuff?

peak spoke
#

setdefault as something you'd use on a single key

magic python
#

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 πŸ€”

flat gazelle
#

you have .get with getattr(obj, potential_attribute, fallback)

#

setdefault also creates the key if it is not present

magic python
#

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.
flat gazelle
#

.get is for dictionaries

#

getattr is the equivalent for attrs

magic python
#

ah , sorry

#

oh, i thought getattr was just standard python πŸ˜–

flat gazelle
#

it is a builtin

magic python
#

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

flat gazelle
#

ye, it works on any object and follows the proper attribute access thing with __getattribute__, __getattr__ and descriptors

magic python
#

is this a good thing to read to understand dunders and stuff?

#

or is there something better/more suitable πŸ€”

unkempt rock
#
for i, usuario, espaco in enumerate(zip(nomes_usuario, valor_usuario)):
flat gazelle
#

that is quite good I would say

unkempt rock
#

what's the syntax error here?

#

i cant cast enumerate + zip like this?

spice pecan
#

enumerate always yields tuples

#

You get a tuple with the index as the first element and a tuple of zipped values as the second

unkempt rock
#

how could i cast this to have the three values?

#

and an index from enumerate

flat gazelle
#

i, (va, vb) should work

spice pecan
#

yeah, that works

flat gazelle
#

you can nest unpackings

a, (b, c, [[d]]) = [1, [2,3,{(4,)}]]
magic python
#

i only recently realised that dict(zip(a, b)) works, instead of {x:y for x, y in zip(a, b)}

wide shuttle
#

that's quite a handy trick

flat gazelle
#

ye, it is quite neat

wide shuttle
#

I think it's mentioned in Fluent Python as well

magic python
#

how do you find out why this works though?

spice pecan
#

What, dict(zip(a, b))?

unkempt rock
#

i, (va, vb) should work
@flat gazelle i did not got it totally, what should i put in enumerate?

flat gazelle
#

the dict constructor can take an iterable of pairs as an argument to construct a dict

magic python
#

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

wide shuttle
#

dict accepts an iterable of key, value pairs and that's what you get when you zip two iterables like that

flat gazelle
#
dict([(1, 2), (3, 4)])```works as well
#

or even

dict((x, x+1) for x in range(100))
spice pecan
#

@unkempt rock ```py
for i, (usuario, espaco) in enumerate(zip(nomes_usuario, valor_usuario)):

flat gazelle
#

which you should do with a dict comp, but I digress

unkempt rock
#

oh, thanks guys

#

i thought it was necessary remove zip

spice pecan
#

nope, just gotta nest the unpacking

unkempt rock
#

but looking at it now does total sense

#

unpacking the values returned by zip

magic python
#

i guess this is the relevant section

 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v

brazen jacinth
#

you can nest unpackings

a, (b, c, [[d]]) = [1, [2,3,{(4,)}]]

@flat gazelle mindblown

cloud crypt
#

eh not much, haha

#

besides, what the hell that structure even is πŸ‘€

full jay
#

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

drowsy coyote
#

yo can anybody teach me python πŸ’― vscode

unkempt rock
#

!resources

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

flat gazelle
#

I really want dict and attr unpacking tbh

#

why can we not do {1: a, 2: b} = {1: 1, 2: 2}

spice pecan
#

That would be really nice to have

drowsy coyote
#

i dont understand any thing cause im trying to learn python xd

paper echo
#

@flat gazelle i like that better than the pattern matching

flat gazelle
#

both would be nice honestly.

grave jolt
#

You can do something like that with inspect

paper echo
#

@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

grave jolt
#
Unpack({1: "a", 2: "b"}) <= {1: 1, 2: 2}
flat gazelle
#

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
paper echo
#

@flat gazelle at least you can do a, b = {1: 1, 2: 2}.values()

grave jolt
#
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})
flat gazelle
#

ye, that seems reasonable.

grave jolt
#

But that won't work if you don't create the dict immediately

deft pagoda
#
globals().update(mydict)
grave jolt
#

πŸ‘€

#

πŸ‘€

pliant tusk
#

@flat gazelle you can implement something like that by hooking dict.__iter__ and using inspect

pliant tusk
#
@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
>>> ```
spice pecan
#

Does this break regular iteration over keys?

pliant tusk
#

yes

paper echo
#

@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
pliant tusk
#

but you can always do dict.keys() @spice pecan

spice pecan
#

I know, and I usually do because it's more explicit, but I was still curious

pliant tusk
#

but yea you're right it does break key iteration

#

it prob also breaks some other stuff too, havent tested it much

spice pecan
#

I guess it could break some internal usage

pliant tusk
#

probably

#

to be fair, my entire py_future module tends to break things so

#

Β―_(ツ)_/Β―

unkempt rock
tacit hawk
#

@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

paper echo
#

hm

tacit hawk
#

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
paper echo
#

i see

#

whereas if you simply used raise from it would chop off chain A

#

right?

tacit hawk
#

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

unkempt rock
#
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

tacit hawk
#

@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
paper echo
#

right, that's what i was encountering as well

#

this is pretty useful

tacit hawk
#

specially in async code

#

when using callbacks to handle a task exit

#

and handling its possible exception

paper echo
#
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?

tacit hawk
#

yes

#

it emulates an exception being raised from an except block

#

handle_exc is the except block

paper echo
#

!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())

fallen slateBOT
#

@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

paper echo
#

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())

fallen slateBOT
#

@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

paper echo
#

the 'from foo 2' one isn't retained here

tacit hawk
#

change head to e2 in extend

paper echo
#

k

#

swap e1 and e2?

tacit hawk
#

yes, that is finding for e2's head

paper echo
#

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())

fallen slateBOT
#

@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

paper echo
#

nice

tacit hawk
#

asynchronous except block

paper echo
#

!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())

fallen slateBOT
#

@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

paper echo
#

that one cut off all the foo errors

tacit hawk
#

return e2 in extend

paper echo
#

let me make sure i understand what extend is doing

royal mantle
#

hi anyone know how to use variables in a sqlite query?

tacit hawk
#
def extend_exception_chain(e1, e2):
    head = e2
    while head.__context__ is not None:
        head = head.__context__
    head.__context__ = e1
    return e2
paper echo
#
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"

tacit hawk
#

you need to raise the exception's tail, e2's tail is the tail of the entire joined chain

royal mantle
#

alright

paper echo
#

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())

fallen slateBOT
#

@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

paper echo
#

got it

tacit hawk
#

do the eval without chaining the exceptions @paper echo

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())

fallen slateBOT
#

@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

paper echo
#

yep

#

beautiful

tacit hawk
#

here e1 was not raised because you consumed it, if you remove task.exception() will see that it gets raised at the end

paper echo
#

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())

fallen slateBOT
#

@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

paper echo
#

wait, this works fine as-is

#

πŸ€”

tacit hawk
#

task.result() is implicitly joining the chains

paper echo
#

ah, that's from task.result() and not from the try/except itself?

tacit hawk
#

it re-raises the task exception

paper echo
#

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

tacit hawk
#
def handle_exc(task):
    try:
       do_something()
    except Exception as e1:
        raise e1
paper echo
#

oh, where do_something is unconditional

#

and not just part of the except

#

?

tacit hawk
#

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()
paper echo
#

ah i see

#

so do_something needs to run unconditionally

tacit hawk
#

yes

paper echo
#

out of curiosity, you couldn't use finally for this?

tacit hawk
#

... lol yes

paper echo
#

it might actually be tricky

#

you'd still need to do the chaining right?

tacit hawk
#

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

paper echo
#

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()

fallen slateBOT
#

@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

paper echo
#

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()

fallen slateBOT
#

@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

paper echo
#

πŸ€·β€β™‚οΈ

#

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()

fallen slateBOT
#

@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

paper echo
#

!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()

fallen slateBOT
#

@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

paper echo
#

nice

red solar
#

🀨

paper echo
#

your discovery is still interesting @tacit hawk, it feels better to have direct access to language behavior without relying on special syntax

red solar
#

Can you summarise the discovery? that's a lot of backlog to read

paper echo
#

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

tacit hawk
#

the try/finally is really the way to go for what I need

red solar
#

huh - i think this is beyond me

paper echo
#

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?

tacit hawk
#

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

paper echo
#

if there is no exception, task.exception() is just None. i made the mistake of not awaiting foo, unrelated

tacit hawk
#

its just a crappy version of try/finally lol

paper echo
#

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

tacit hawk
#

why try/finally did not worked for manually crafted chain

red solar
#

oh cool πŸ™‚

tacit hawk
#

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

paper echo
#

hm

devout kelp
#

do if statements really bog down a program's speed?

slim island
#

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

red solar
#
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

slim island
#

that's not about branching - those functions are just doing different things. You can probably see that if you dis.dis() them

red solar
#

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

peak spoke
#

Python is too high level to consider it like that, it does checks all over in the C code

red solar
#

lol whenever i write a C extension, i spend more time parsing and validating arguments than actually doing C stuff

flat gazelle
#

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)
torpid bridge
#

I would argue the differing variance could be explained as branch prediction doing its best

hoary orbit
#

(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

torpid bridge
#

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]

hoary orbit
#

i do type() and get list @torpid bridge

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

hoary orbit
#

okay thanks

boreal umbra
#

do if statements really bog down a program's speed?
@devout kelp are you doing something performance critical?

red solar
#

You guys can talk over this. @grizzled vigil how do i get a bpo number for my commit?

wide shuttle
red solar
#

ohhh

wide shuttle
red solar
#

yeah

wide shuttle
#

So bpo-41371

red solar
#

so i open an issue, and then add my PR with that bpo, and link it to the issue once i've made it?

magic python
#

Use at if you only need to get or set a single value in a DataFrame or Series

paper echo
#

@magic python i think theoretically it does less work in trying to infer whether the argument is a "single value" or not

magic python
#

if you use df.loc[ x, y ] you'll get a single tho πŸ€”

paper echo
#

which theoretically means it's faster

magic python
#

hrm

paper echo
#

if you're doing it in a hot loop for example... idk how effective it is

magic python
#

i was wondering whether there was some multiindex jazz i was unaware of

paper echo
#

nope

#

at least not that im aware of either

magic python
#

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

paper echo
#

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

magic python
#

oh right - fair enough

#

seems to documentation for this is off

paper echo
#

DataFrame.lookup is analogous to indexing a numpy array with two 1-d vectors

magic python
#

print( inspect.getsource( df.lookup )) has more info πŸ€”

paper echo
#

welcome to pandas

#

given that we are in #internals-and-peps , it is a great example of how messy developing a DSL can be

magic python
#

πŸ™ƒ so is this something that's on the way in - or on the way out?

paper echo
#

neither

magic python
#

lookup that is, oh

paper echo
#

people use it, it has its place in the world

#

i've used it

magic python
#

Label-based "fancy indexing" function for DataFrame

#

fancy apparently, idk what that means tho

paper echo
#

yes by analogy to numpy's "fancy indexing"

#

horrible docstring lol

#

it's like INDEX in excel actually

#

...kinda

magic python
#

oh right, i've not used numpy enough

#

or excel πŸ˜† just pandas

paper echo
#
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']])
magic python
#
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

paper echo
#
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

magic python
#

yea it does - cool

paper echo
#

also you might as well .set_index('PassengerId'), no?

magic python
#

idk - just have that in memory for all ipython sessions

devout kelp
#

@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

flat gazelle
#

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

boreal umbra
paper echo
#

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

boreal umbra
#

Optimization, I guess. Though we make our bot do a lot of work and it seems to handle it just fine.

paper echo
#

the bottleneck is all network requests

#

so optimization would have to be algorithmic instead of just using a "faster" language

boreal umbra
#

Makes sense

paper echo
#

the http itself is handled by aiohttp

#

and im pretty sure that uses the low-level async networking features that ship with asyncio, underneath

boreal umbra
#

My friend who hates python said that python is terrible for web development because of the speed, but idk if that's true.

paper echo
#

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

flat gazelle
#

you need to be very large scale before your web application becomes CPU bound rather than IO bound

paper echo
#

but terrible? hardly

#

yes exactly

flat gazelle
#

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

boreal umbra
#

I see

red solar
#

it's not exactly standard web dev, but sometimes latency is important, and in those cases python might just not be fast enough 🀷

flat gazelle
#

ye, there are some cases where it would matter.

boreal umbra
#

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

red solar
#

lol i just moved to C++

#

do you explain to them that generally it's not the best course of action?

nova dock
#

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?

unkempt rock
#

Yes

#

(Unless it’s referenced elsewhere, e.g. also stored in a class instance, and the function was a class method)

nova dock
#

thank you

raven ridge
#

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)

unkempt rock
#

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?

spark magnet
#

@unkempt rock better to use a help channel where you can share the code and output

unkempt rock
#

okay thanks!

#

and sorry!

nova dock
#

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

languid dagger
nova dock
#

i will do that then, thanks

unkempt rock
#

ok

ashen coyote
#

?help

boreal umbra
weary bolt
#

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")

deft pagoda
#

this is not the right channel for help

weary bolt
#

which channel should I go to for help?

last pollen
mighty hound
#
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>]
north root
#

@mighty hound please see the message right above yours

prime shuttle
#

yes

north vector
#

yes

wicked socket
#

@mighty hound because "get_card" is a list of objects

mighty hound
#

so what happens when we print a list of objests @wicked socket

wicked socket
#

you print out the memory location of the object.

mighty hound
#

any rason for that @wicked socket

#

reason**

wicked socket
#

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.

silver drum
#

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

charred wagon
vernal sapphire
#

I want to ask, Python has a lot of functions, so is it important to remember all?

radiant fulcrum
#

not massively

prime shuttle
#

Yes

#

It depends what the purpose is

spice pecan
#

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

open trout
#

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)

undone hare
#

Something like a

@decorator(
    arg1=...
    arg2=...
)
...```should be PEP8 compliant
open trout
#

Yeah, just so it doesn't look unnatural, I haven't really seen "big" decorators used in the real world

prime shuttle
#

Ye

pure orchid
#

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

slim island
torpid terrace
#

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

fallen slateBOT
#

You are not allowed to use that command here. Please use the #bot-commands channel instead.

mild grove
#

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?

broken egret
#

!resources

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

broken egret
#

@mild grove

mild grove
#

Thank you @broken egret

unkempt rock
#

Hi, what's the reasoning behind something like a = [1] ; [s] = a - somehow i feel this is related to Python's C innerworkings.

flat gazelle
#

That is called unpacking

unkempt rock
#

yes ok, but isnt it more readable doing s = a[0]

flat gazelle
#

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

unkempt rock
#

ok let me ask this differently - which is more encouraged, pythonic? if a = [1] ; [s] =a or s = a[0]

flat gazelle
#

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

unkempt rock
#

ok thanks! that really helped.

sacred tinsel
#

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
safe cliff
#

hey guys i am a begginer pls tell some cool things you can do

crisp fiber
#

how to import MONGODB?

#

hey guys i am a begginer pls tell some cool things you can do
@safe cliff discord.py?

lone prairie
#

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

sacred tinsel
#

Either #python-discussion or a help channel would be more appropriate for these questions please

brazen jacinth
#
[animal] = {'cat'}

so does this still classify as a tuple unpacking or is it something different

peak spoke
#

Just normal iterable unpacking

brazen jacinth
#

internally it's still just an unpack sequence, yea just looked it up

#

how come dis doesn't support dissasembly of builtins?

peak spoke
#

They are implemented in C and aren't compiled as bytecode

brazen jacinth
#

Aaa

undone hare
#

They call internal C code yeah

red solar
#

which is wonderful because i think it makes them all atomic πŸ™‚

#

(wrt python)

radiant fulcrum
#

πŸ€”

cold forum
#

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.

visual shadow
#

Uh. Your convention seems to be off

#

Conventionally, names with a single leading underscores are understood to be "do not touch" territory

cold forum
#

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?

deft pagoda
#

same

visual shadow
#

The person making the subclass is someone else, yes?

cold forum
#

So instead I should rather rename the attributes I expect subclasses to override without underscores and that's it

visual shadow
#

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.

deft pagoda
#

usually for building your own framework

peak spoke
#

new dunders shouldn't be created by users, they are reserved for python

deft pagoda
#

false

cold forum
#

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

visual shadow
#

I suppose just avoid the single leading underscore name, that's the one thing I can vouch for. Breaks convention, would lead to confusion.

deft pagoda
#

can also use init_subclass sometimes instead of meta

visual shadow
#

Beyond that I don't have a good opinion of what you should do instead.

peak spoke
cold forum
#

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

deft pagoda
#

why would they break

cold forum
#

why would they break
@deft pagoda Newer python versions might define new __attrs__ without caring for your code

deft pagoda
#

that wouldn't overwrite what i had in my class

cold forum
#

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?

deft pagoda
#

another slots?

peak spoke
#

No it wouldn't overwrite what you had, but you overwrite the behaviour which could be called internally somewhere now

deft pagoda
#

that's fine

#

it's not disallowed

visual shadow
#

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.

deft pagoda
#

i've propose similar of kivy framework with __KV__ dunder to automatically load kv files for widgets, which i think is fair use

peak spoke
#

And there's still the thing that dunders have a clear meaning as being specific to the datamodel

deft pagoda
#

this loading happens in the meta, so it's data-model-like behavior

#

i just find dunders easier to remember in frameworks

brazen jacinth
#

_KV_?

#

unconventional...but it's mostly just a preference

deft pagoda
#

well, probably they'd use lowercase

#

tbf, i never addressed issues with unloading kv files for parent widgets

cold forum
#

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.

deft pagoda
#

i think you can take care of that in a meta init

cold forum
#

I.e. pass the machine_type in class SubClass(...)?

#

Use a decorator?

deft pagoda
#

well, honestly, could do it in __new__ too

paper echo
#

@peak spoke dunders are used by a handful of 3rd party libraries, eg attrs. I think they are OK if designed judiciously

cold forum
#

@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

visual shadow
#

He's just saying in general. Not specific to your case

cold forum
#

I know

visual shadow
#

And sounds like a plan. Go for it

peak spoke
#

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

deft pagoda
#
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

cold forum
#

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

deft pagoda
#

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
cold forum
#

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.

deft pagoda
#

this was a custom enum, so you don't have to actually assign values to the names

#

the lazy-man's enum

cold forum
#

Doesn't enum.auto() take care of that?

deft pagoda
#

sure, but then you have to type it for every attribute

#

doesn't really save time

cold forum
#

The lazy-lazy-man's enum then

#

πŸ™ƒ

deft pagoda
#

using weird defaultdict-like dicts in metas is really fun

south pumice
#

@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.
strange fog
#

@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

peak spoke
#

Then there's the cost of doing that behaviour every time the function is bound/called

strange fog
#

no, it would only happen once when the method code is parsed

south pumice
#

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

peak spoke
#

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

strange fog
#

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

south pumice
#

I think it can already be done perhaps, let me think of a way

strange fog
#

the question isnt one of whether it can already be done or not

south pumice
#

Because first of all you could do this: py class MyClass: def load_lists(self, some_argument = MyClass.something):

strange fog
#

just thought it might be an interesting conveniency for the interpreter to handle

south pumice
#

but then renaming the class forces you to replace its name in multiple places

strange fog
#

that's not the same. class attributes are not instance attributes

south pumice
#

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

strange fog
#

youve entirely misunderstood my point then.

grave jolt
south pumice
#

The thing is, if I understand your point in another way, it becomes an invalid point in a different way

peak spoke
#

It is a question whether it can be done without sacrificing speed or referencing normal names as the default value

grave jolt
#

Sometimes mutable default args are used for a (mutable) cache, so that wouldn't really work.

south pumice
#

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

strange fog
#

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

south pumice
#

but what's the point

#

can't you make IDE do that?

strange fog
#

just some conveniency

peak spoke
#

Those two are also functionally different

#

(if it referenced normal self)

south pumice
#

I wouldn't want that conveniency

strange fog
#

ok, that's fine. it's just an idea. you can calm down now.

south pumice
#

I am calm. πŸ€”

grave jolt
#

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)
strange fog
#

again, i dont doubt that it's already doable through ways like that

south pumice
#

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 ?

grave jolt
#

yes, that's possible as well

flat gazelle
#
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
paper echo
#

@strange fog i wrote a utility function to do this

strange fog
#

im not concerned with whether it's already doable or not

paper echo
#

i dont think it makes sense

strange fog
#

just thinking that it might be something the interpreter could handle

paper echo
#

what if None is a valid value?

strange fog
#

then it wont make a difference

paper echo
#

?

#

what if None is not the default, but valid?

strange fog
#

you can use something other than None as the default placeholder

#

some special object

flat gazelle
#

it would make the function descriptor quite complex

#

and it would differentiate functions and methods

paper echo
#

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

south pumice
#

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.

flat gazelle
#

I guess something like

def fun(arg1, arg2=arg1 + 3):
    ...
```is not impossible, but it then  means the default arg has to be recomputed
paper echo
flat gazelle
#

which would make default args more complex, whereas now they are just in a tuple/dict

paper echo
#

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

red solar
#

would it not still be tuple/dict? just now the dict value is a closure?

paper echo
#

the dict value is an expression

south pumice
#

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)

paper echo
#

which is inserted above the function body

flat gazelle
#

python cannot store expressions, even comps use essentially functions

paper echo
#

or if arg is MissingArgument

flat gazelle
#

so it would make every default arg into another function.

paper echo
#

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

south pumice
strange fog
#

@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.

paper echo
#
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

south pumice
#

@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

paper echo
#

it's really about 2 things

flat gazelle
#

that seems like there would be some weird edge cases

pliant tusk
#

That leads me to the question, what if 2 default args refer to each other?

paper echo
#
  1. capturing the expression
  2. a new MissingArgument singleton 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

south pumice
#

It's about

  1. evaluating expressions in function header at call time vs current function object creation time
  2. being able to access an earlier argument, by the latter argument.
paper echo
#

no it has nothing to do with self

south pumice
#

yea let me fix that

flat gazelle
#

it cannot work with self specifically, that has too many edge cases

paper echo
#

accessing self is a special case of 1

flat gazelle
#

it should be generic across all args

paper echo
#

@south pumice those are 1a and 1b imo

pliant tusk
#

def func(x,y=x+z,z=x+y):pass

flat gazelle
#

you could just raise UnboundLocal there

paper echo
#

^

#

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

pliant tusk
#

But where would the error raise from?

#

Cause if z=x+1 instead of y then it’s able to evaluate

paper echo
#

it would read left to right

#

so x can't refer to z but z can refer to x

flat gazelle
#

then kwargs are order sensitive, which is inconvenient

paper echo
#

right

strange fog
#

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

south pumice
#

@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)

paper echo
#

that's what my (1) was

#

we are saying the same thing

pliant tusk
#

It’s definitely doable with a decorator

paper echo
#

accessing attributes of self is just one application thereof

strange fog
#

Etherlord, with due respect, I don't think you understood what I was going for, so please don't speak for me.

paper echo
flat gazelle
#

see my above snippet with a decorator that does this

pliant tusk
#

Oh I was thinking even to extract the default args from the original signature

paper echo
#

right, one limitation of my with_default decorator is that the default arg still can't access other parameters

boreal umbra
#

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?

paper echo
#

@boreal umbra ^

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?

paper echo
#

probably? hard to say without seeing the text and the regex

#

they have a python mode

boreal umbra
#

I usually use pythex

paper echo
#

regex101 tells you the steps

#

more features

boreal umbra
#

however my advisor is really into perl so I want to assume that her regex is great

paper echo
#

i have bad news for you

boreal umbra
#

what

paper echo
#

re: perl & code quality πŸ˜‰

boreal umbra
#

oh I can't even look at perl

paper echo
#

more seriously i assume your expressions are something like thing-i-idont-need(.*?)other-thing-i-dont-need?

boreal umbra
#

looks like the program actually finished at some point but my ssh connection went wrong and made it look like it was frozen

paper echo
#

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

boreal umbra
#

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

narrow kettle
#

hmm random thought, what if <> could denote sets instead of {}

boreal umbra
#

for what?

narrow kettle
#

which is commonly used as a dict

#

foo = <>

boreal umbra
#

oh I see

#

curly braces are already used to represent sets in general

full jay
#

Not likely

boreal umbra
#

and it's easy to know which one you're looking it.

narrow kettle
#

but they also represent dicts, so you cant create an empty set with brackets afaik

boreal umbra
#

though I admit that having to use set() to create an empty set is a bit unfortunate.

full jay
#

When you have a stand alone < or >, it's going to be assumed it's an operator in most contexts

narrow kettle
#

you have to do foo = set()

full jay
#

Sure, but that's a miniscule timeloss

narrow kettle
#

no its not a pressing issue whatsoever

boreal umbra
#

it actually makes sense that dicts and sets would both use curly braces though

full jay
#

Both being hashmaps, yeah

boreal umbra
#

they both rely on hashing to be a collection of unique objects

narrow kettle
#

true

boreal umbra
#

but dicts are a mapping

flat gazelle
#

<> should probably not be braces as a < b, c > d would be extremely ambiguous

narrow kettle
#

hmm, you cant change it now but ```py
foo = {} #set

bar = {:} #dict

undone hare
#

^ is that really a thing? Okay welp

narrow kettle
#

obviosuly thats a horrible breaking change

boreal umbra
#

I think {:} would be confusing for learners

full jay
#

Especially when sat near slices

boreal umbra
#

most learners don't even know about sets or have a need for them.

narrow kettle
#

i mean how is that any more confusing then anyother py stuff

spice pecan
#

I'd rather go with {,} for sets than change the literal for dicts

narrow kettle
#

that would work too

#

the literal for dicts isnt an option oc, breaking change

undone hare
#

I don't think it would be a breaking change to allow {:}, but the parser won't like that for sure

brazen jacinth
#

set == set(), dict == {}

flat gazelle
#

False, False

full jay
#

Well played

brazen jacinth
#

{,} and such are just unnecesarry tbh

narrow kettle
#

the discussion is how having to do set() is unfortuante

#

its not a big deal

#

but it does feel a bit odd imo

full jay
#

I mean... how often are you having to make a set compared to any other container type?

narrow kettle
#

cuz you have such nice options for lists and dicts

boreal umbra
#

there have been a few other instances of people suggesting <> as a new kind of enclosure

spice pecan
#

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

boreal umbra
#

I remember seeing it suggested for multi-line lambdas

narrow kettle
#

ohh i like that

full jay
#

No

#

I hate it

boreal umbra
#

lambdas are best used sparingly

brazen jacinth
#

^

full jay
#

Exactly

#

Python isn't built for it

narrow kettle
#
lambda foo: <
  print('hi')
  print(foo)
  >
boreal umbra
#

and if you need one with more than one expression, chances are that's not sparing

full jay
#

But WHY do that

#

There's no good or practical reason to do that example

narrow kettle
#

ya python doesnt really lend itself to that, its more work then its worth with indentation errors

full jay
#

What benefits do you get from a multiline lambda that you don't from a standard function definition?

undone hare
#

Technically being able to create an empty dict using {:} would be faster than dict() (one less function call)

narrow kettle
#

its nice in langs with { } cuz you can just organize it how you want

full jay
#

@undone hare But it would break EVERYTHING

paper echo
#

yeah this is one of those conversations where i say "just use a different language"

#

as much as i love python

brazen jacinth
#

a few extra clock cycles πŸ˜›

paper echo
#

it has limits

undone hare
#

Why though

boreal umbra
#

making comparators in Java using an anonymous class makes me want to smash my computer

undone hare
#

I don't see what would break here

full jay
#

@undone hare Existing code?

undone hare
#

{:} isn't parsing right now, right?

narrow kettle
#

making ___ in Java using an ____ makes me want to smash my computer

#

fixed

boreal umbra
#

thanks

brazen jacinth
#

Java is comfy tbh

#

at least java8+

full jay
#

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

narrow kettle
#

streams are nice, they finally got linq

sacred tinsel
#

{:} isn't parsing right now, right?
I think it's a syntaxerror

boreal umbra
#

!e

my_dict = {:}
fallen slateBOT
#

@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
undone hare
#

Yeah, so nobody is using it, so no breaking changes lemon_thinking

boreal umbra
#

ye

full jay
#

No, again

sturdy timber
#

That would be weird though

#

It doesn't really make any sense

flat gazelle
#

the idea is to change what {} means to set()

undone hare
#

I mean, you'd still have {} be the current implementation

#

Oh wait

narrow kettle
#

lol

flat gazelle
#

as well as introduce {:} for dict()

full jay
#

Exactly

narrow kettle
#

i like {,} the best personally

full jay
#

You're not just adding a second option for dict

narrow kettle
#

very idiomatic

full jay
#

Sure but I don't find myself using sets enough to worry about the function call cost

undone hare
#

Oh yeah, I'm a big dumby

boreal umbra
#

isn't that creating a set with one empty tuple or something?

#

!e

my_set = {,}
print(my_set)
fallen slateBOT
#

@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
brazen jacinth
#

can you make an empty tuple?

#

i don't think that parses

#

yea

flat gazelle
#

() is an empty tuple

boreal umbra
#

yes, with (,)

#

there has to be a comma though

brazen jacinth
#

i mean yea, but not like that

flat gazelle
#

!e print(())

fallen slateBOT
#

@flat gazelle :white_check_mark: Your eval job has completed with return code 0.

()
sacred tinsel
#

don't think (,) is valid either though

full jay
#

Considering all the extra work () does, I still prefer to do tuple()

narrow kettle
#

so there already is precedent for {,}

flat gazelle
#

you cannot have leading comma in an enumeration

narrow kettle
#

you need a comma for a one member tuple

undone hare
#

Yup you can't

boreal umbra
#

sorry, I think I was thinking of making a one-tuple

narrow kettle
#

(true,)

flat gazelle
#

ye, one tuple needs a trailing comma

narrow kettle
#

vs (true) which is just an expression

visual shadow
#

heck, True, is enough

full jay
#

Yarp

#

Actually does that incur any extra cost?

#

Vs (True,)?

flat gazelle
#

it parses the same when it works

#

some cases do need the () though, like when passed as an arg

boreal umbra
#

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

full jay
#

Makes sense

#

And more explicit to the reader

sacred tinsel
#

the () only play a part at compile time though right?

full jay
#

Probably

sacred tinsel
#

so there should be no performance implications

full jay
#

Only on first run

#

Potentially

brazen jacinth
#
>>> [a] = {1,}
>>> type(a)
<class 'int'>
>>> [a] = {(1,)}
>>> a
(1,)
full jay
#

Yeah my confusion was more about:

x = 1,
# vs
y = (1,)
brazen jacinth
#

you mean parsing-wise?

full jay
#

Si

visual shadow
#

!e

import dis
def test1():
    return True,

def test2():
    return (True,)

dis.dis(test1)
dis.dis(test2)
fallen slateBOT
#

@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
visual shadow
#

looks like the dis are exactly the same for both

full jay
#

Interesting

brazen jacinth
#

bytecode it returns the same yea

full jay
#

Yeah it's the getting to the bytecode

visual shadow
#

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

sacred tinsel
#

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

full jay
#

That's.... actually a really good point

visual shadow
#

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.

sacred tinsel
#

maybe when passing them to a function that takes an iterable

full jay
#

Or returned

sacred tinsel
#

or as a default param

full jay
#

But yeah, just having them...

visual shadow
#

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

full jay
#

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

brazen jacinth
#

the ast for the 2 examples are the same

#

but for the parsing itself, wouldn't know tbh

grave jolt
#

!e

print(
    {*()}
)
# ^ empty set
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

set()
brazen jacinth
#

the lexer obviously has more work (constants ofc), but good question how the parser handles it

#

is it more work or less

grave jolt
#

also {*{}}

#

!e

print( {*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{}}}}}}}}}}}}}}}} )
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

set()
gusty breach
#

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

grave jolt
gusty breach
#

I see

narrow kettle
#
print( {*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{}}}}}}}}}}}}}}}} )
```wut is this abomination πŸ˜‚
grave jolt
#

{} 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...

visual shadow
#

an empty set. i thought everyone wrote empty sets this way!

grave jolt
#

^

#

duh

narrow kettle
#

The more * you use the emptier the set is

#

Everyone knows this

grave jolt
#

to make it one byte shorter, you could define a global _

narrow kettle
grave jolt
#

!e

_ = ()
print({*_})
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

set()
paper echo
#

isnt there a set theoretical way to construct integers with things like {} = 0, {{}} = 1, etc?

#

or did i dream that

grave jolt
#

I think there is

#

I don't see why not

#

well, almost

paper echo
#

ah so it's {{}, {{}}} = 1

#

very intuitive thanks

grave jolt
#

so```
0 = {}
succ n = n U {n}

paper echo
#

"von Neumann ordinals"

#

and "zermelo ordinals"

#

those are the search terms i guess

grave jolt
#

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))))
...
flat gazelle
#

in python, you would have to use frozensets

grave jolt
#

right, because normal sets aren't hashable

unkempt orchid
#

how to hash

flat gazelle
#

depends on what you want to do with the hash

#

there is no one size fits all hash

paper echo
#

well first you need some good quality herb..

#

oh

unkempt rock
#

LMAO

crisp dawn
#

!ot You can talk about good quality herbs over here

fallen slateBOT
heady scroll
#

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]

crisp dawn
#

this channel isnt for questions

#

read description

low lagoon
sullen citrus
#

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...

flat gazelle
#

.sort returns None and modifies the original list

sullen citrus
#

yup when i print it it prints None

flat gazelle
#

sorted can be used to return a new sorted list like sorted(some_list)

spice pecan
#

yeah, that's how it works, it sorts the list in-place

sullen citrus
#

okay, so i'm just dumb, i forgot that sorted() exists

spice pecan
#

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

sullen citrus
#

thx a lot, take care !