#internals-and-peps

1 messages ¡ Page 63 of 1

gleaming rover
#

I just want simple lambda functions

grave jolt
#

what is the "context" here
So the way the computations can be evaluated is:

  1. you perform one bind and get another IO container
  2. you might switch to a different task
  3. some time in the future you can return to that particular result (IO container) and compute it further
    this way, cooperative multitasking (like async stuff) can be achieved
gleaming rover
#

Callable[[Tuple[int, str], Optional[int], Mapping[FrozenSet[str], int], bool]

#

I see absolutely nothing wrong here

teal yacht
#

I'm screaming internally

grave jolt
#

you haven't seen TypedDict

gleaming rover
#

I use it a fair bit actually

grave jolt
#

inline typed dict

gleaming rover
#

because I'm working on my startup's REST API that returns almost entirely JSON

#

:)))))

#

you know what I miss?

#

case classes

grave jolt
#

TypedDict("Hello", {"hey now": Callable[int, float], "lorem ipsum": TypedDict("Hello", {"dolor": str, "sit": int})})

gleaming rover
#

or...normal data, in Haskell

teal yacht
#

are these - yeah

gleaming rover
#

stop

#

please

grave jolt
#

sorry

paper echo
#

yeah i see how Awaitable is a monad

#

what is it's bind implementation?

#

await?

gleaming rover
#

perhaps we should have stuck to "if [] should execute"

paper echo
#

heh

#

case classes are another terminology mystery to me

grave jolt
#

@paper echo
the bind implementation is written in C in the event loop somehow :)
await is just syntax sugar for calling it

paper echo
#

right

gleaming rover
#

case classes are another terminology mystery to me
@paper echo I understand it's because they're great for pattern matching

#

match case

paper echo
#

that's what i figured

#

@attr.s(slots=True)

gleaming rover
#

personally I just think they sound coool

paper echo
#

good enough for me

gleaming rover
#

but then you need lenses

#

which I have foolishly attempted to reimplement in Python because...

#

...sigh.

paper echo
grave jolt
#

_[0].attr[42].hello[3:5]

gleaming rover
#

I got so distracted my side project (a game) spawned its own sided project (a sliceable list where the slices update based on the original)

grave jolt
#

like slice thingy in go?

gleaming rover
teal yacht
#

so like a numpy array :p

paper echo
#

@grave jolt so in the monad interpretation, await means something like "take an Awaitable thing, and represent the result of future computations on that thing as an Awaitable"

#

is that close-ish?

gleaming rover
#
>>> l = Sliceable2DList([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> l
[[1, 2, 3]
 [4, 5, 6]
 [7, 8, 9]]
>>> sub_l = l[1:, 1:]
>>> sub_l
[[5, 6]
 [8, 9]]
>>> sub_l.apply(lambda x: x * 2)
>>> l
[[1, 2, 3]
 [4, 10, 12]
 [7, 16, 18]]
#

so like a numpy array :p
@teal yacht yes, like a numpy array, BUT a list

paper echo
#

yeah glom is great for hacking apart deeply nested data structures

grave jolt
#

@paper echo await is an ad-hoc implementation of do-notation from haskell

gleaming rover
#

i.e. not really useful anywhere except in the side project that spawned it but really fun to work on

#

a few hours just disappeared

teal yacht
#

I mean, views on arrays can be super useful

gleaming rover
#

numpy, yes

#

I meant what I did

teal yacht
#

Yeah, what you did is a view

gleaming rover
#

yeah, I mean like it's kind of restricted in this case because it has to be 2D and it doesn't support changing dimensions so honestly I should just have used a numpy array

teal yacht
#

pretend the fact that it's a list has other benefits that you really needed

gleaming rover
#

oh I remember why now

teal yacht
#

like O(1) append

gleaming rover
#

I didn't want numpy to be a dependency just for this

#

and I wanted to build something cool

grave jolt
#

also, constructing a numpy array from a list comes at some cost (for me it's on microsecond level)

pseudo cradle
#

honestly I think numpy should just be stdlib

paper echo
#

i kinda feel like monads in python might not work because you need to somewhat-strictly enforce the return value of the function being bound

#
class Option(Monad, Generic[T]):
    def __init__(self, value: Optional[T]):
        self._value = value

    def __bind__(f: Callable[[T], Option[T]]) -> Option[T]:
         return Option(None) if self._value is None else f(self._value)

like this

teal yacht
#

except for the fact that it'd mean slower releases @pseudo cradle

paper echo
#

what if f doesnt return Option[T]?

#

does the program crash?

pseudo cradle
#

Yeah, that's fair

paper echo
#

if anything, start taking stuff out of the stdlib

teal yacht
#

something something users should know what they're doing something something

grave jolt
#

numpy only makes sense because it's powered by a C extension, which can't be attached to the spec

teal yacht
#

(I don't agree with that statement, that's why I'll never prefer dynamic typing)

pseudo cradle
#

Maybe it's just me but anything besides a config file is importing numpy

teal yacht
#

depends on what you're working on

grave jolt
pseudo cradle
#

Doesn't everyone work on algorithms? 😄

grave jolt
#

no, I work on monads 🙂

pseudo cradle
#

I don't know what that is, but it sounds fancy

teal yacht
#

I'm not sure if it's a joke or sarcasm or something tbh

grave jolt
#

@pseudo cradle Basically, you flatten the nested monad and that's it

pseudo cradle
#

Sounds painful

grave jolt
#

yeah, sometimes it binds

paper echo
#

@grave jolt to be fair, topological sort is a basic necessity for package management, which is a basic necessity for a programming language that isnt stupid. so i'll give that one a pass

#

i suppose you could say the same about having http and ftp clients for actually fetching packages

gleaming rover
#

don't think it would work as a language feature

#

but yes IMO there is a ton of nonsense in the standard library

#

although perhaps I just don't understand some of it

#

why do we even need stuff like curses?

teal yacht
#

wdym we don't need turtle ?

gleaming rover
#

(I chose it specifically because I'm actually using it for my side project but it is literally something I have never looked at ever otherwise)

#

wait

#

turtle is part of stdlib?

#

my god

teal yacht
#

I personally think curses is much higher on the list than some other modules tbh

gleaming rover
#

no wonder I have never seen anyone complain about being unable to install it

teal yacht
#

but yeah, it could still be an external package

gleaming rover
#

WELL

#

I guess it's the philosophy "have something for everybody"

#

honestly I don't really have a problem with stuff like that as long as it 1. doesn't take a commonly used name and 2. doesn't replicate functionality

paper echo
#

look at all the beginners here

#

now imagine you have to make them install stuff?

#

into environments?

#

that's the main argument for keeping the stdlib big and fat

gleaming rover
#

that was a real quick edit

teal yacht
#

if at least it was complete, colorsys has like 6 functions

#

I'm sure I can name more color spaces than that

#

(nvm i can't)

raven ridge
#

that's a fairly silly one to have in the standard library because it's implemented in Python

#

it may cover some of the most heavily used colorsystems, but I'd expect just about any color conversion logic to be done in a loop, at which point having the whole thing implemented in Python rather than C is likely to quickly become a bottleneck

#

after all, who converts just one pixel? Heh

white edge
#

does anyone happen to have any historical insight into why python went with the fugly lambda x: x syntax instead of arrow syntax like most other languages?

#

even if it's not arrow, rust is like |x| x iirc, lambda x: is like have a sentence ffs

feral cedar
#

lambda calculus

languid dagger
#

Wanting lambda as a keyword might be one reason and to make it similar syntax to a function def

gloomy rain
#

Lambdas have been part of Python since version 1.0, which was released in 94. I can imagine there wasn't really an accepted standard for what anonymous function syntax should look like back then.

#

I don't personally think it matters much, since lambdas aren't all that useful in Python.

prime estuary
#

Python usually has a preference for keywords over symbols (and for example). That's because they're more easily searchable and identifiable than a symbol.

undone hare
#

And it leads to more natural language looking code

gloomy rain
#

In the case of control structures and logical expressions, that holds true, but I don't think the word "lambda" fits naturally into most sentences.

honest plover
#

Hello!

unkempt rock
#

is it possible to change the color of the output of the ide thinkmon

feral cedar
#

@unkempt rock yes, the colorama module. secondly, this isn't a help channel

unkempt rock
#

UwU Thanks 😊 Too short for help channel

#

it would just waste a channel

languid dagger
#

Doesn't matter, we prefer it that way than conversations happening in on topic channels

undone hare
#
map(lambda x, y: x + y, list(1, 2, 3))```Could be read as "map the lambda function x + y to the list 1, 2, 3"
#

So I guess it can be inserted in some sentences?

#

But I agree with you, the lambda syntex isn't great

deft pagoda
#

i've seen the different proposals for changes to the lambda syntax on python-ideas and the generator syntax was my favorite

#
(x + y for x, y)

or

(x + y from x, y)

and wouldn't need new keywords

languid dagger
#

Personally I prefer parameters first

gleaming rover
#

me too

#

back to Haskell using the wrong order

#

🥴

#

but honestly that for thing looks pretty good

feral cedar
#

i agree ^

languid dagger
#

Idk if you can use with without breaking the parser

(with x, y: x + y)```
gleaming rover
#

I would also like tuple destructuring in lambdas, as long as we're hoping

#

Idk if you can use with without breaking the parser

(with x, y: x + y)```

@languid dagger I was thinking more about the colon

#

because if you wanted arguments first you'd need something to separate arguments and body, right

#

colon is the most intuitive but I am not sure how that would work

feral cedar
#

use the -> from other languages

languid dagger
#

C# and JavaScript uses =>

#

Only issue I find with that is you can mix up >=

slim island
#

-> is already used for typing. => is pretty clear, seems pretty hard to mix it up with >=

languid dagger
#

Oh right I forgot that it's used for typing, perhaps they can reuse it then

gleaming rover
#

use the -> from other languages
@feral cedar then no need for a keyword

#

just x, y -> x + y

#

honestly I would also like that for function typing

feral cedar
#

it's already there for type hints

gleaming rover
#

imagine (int, str) -> bool instead of Callable[[int, str], bool]

feral cedar
#

yeah ig

zealous oriole
#

whats the idea behind yield

slim island
#

that is infinitely nicer for typing

zealous oriole
#

how does it work

languid dagger
#

As in why does Python have a yield?

zealous oriole
#

not on that

#

like whats the idea behind it

#

well maybe why would give context

languid dagger
#

What does it do?

zealous oriole
#

i know what it does

#

but how is it implemented

gleaming rover
#

how low level do you want to go

#

that's a complex question

zealous oriole
#

beginner friendly

#

if possible

#

otherwise blast at me

languid dagger
#

When the parser sees yield in your function it creates it as a generator function instead

gleaming rover
#

well, in simple terms, then, when your function hits yield, it pauses execution and returns control to whatever called it

languid dagger
#

Rather than a typical function, so the behavior is slightly different

zealous oriole
#

parser being python?

gleaming rover
#

but without releasing the variables that are in scope

#

compare that to a normal function, where all the variables in scope can be taken to disappear once return is hit

languid dagger
#

Yes, Python parses your code into bytecode. That's how you get syntax errors without running anyway

#

Then that bytecode is run in the Python interpreter

zealous oriole
#

hmm so what happens if you return a gen comp

#
def something(x):
  return (x*x for x in range(x))
#

idk if that even works

gleaming rover
#

that would be a normal function, not a generator

zealous oriole
#

so it exhausts the gen?

gleaming rover
#

or rather, it would be a normal function returning a generator

#

okay, example...

languid dagger
#

No, the generator is constructed but returned as is

gleaming rover
#
>>> def a():
...     print('called')
...     return
...
>>> def b():
...     print('called')
...     yield
...
>>> a()
called
>>> b()
<generator object b at 0x00000279681AA1A8>

you see that 'called' is not printed when b is run

languid dagger
#

If you were to print it you'd see "generator object"

zealous oriole
#

so its still "optimal code"?

languid dagger
#

I don't know what you mean by "optimal code"

gleaming rover
#

compare to:

>>> def c():
...     print('called')
...     return (x for x in range(1))
...
>>> c()
called
<generator object c.<locals>.<genexpr> at 0x00000279682C7468>
zealous oriole
#

so yield doesn't allow prints()

#

?

gleaming rover
#

no

zealous oriole
#

why

gleaming rover
#

no, that is not correct

#

not no, it doesn't

languid dagger
#

Your function does not continue to the yield call until requested (i.e next is used)

gleaming rover
#

when you call an ordinary function (with return), it starts execution at the head and runs until it hits an error or return.

zealous oriole
#

shouldn't it go through first iteration by default?

deft pagoda
#

no

zealous oriole
#

wow this is some crazy stuff

languid dagger
#
def gen():
    print('g 1')
    yield 1
    print('g 2')
    yield 2
    print('g 3')

>>> g = gen()
>>> next(g)
g 1
1
>>> next(g)
g 2
2
>>> next(g)
g 3
StopIteration```
zealous oriole
#

so you can use yield infinitely many times?

#

as compared to once for return

deft pagoda
#

yes

languid dagger
#

Yes, hence "generator" you can generate values

gleaming rover
#

yes, the point of a generator is that you can pause execution and return to it, and each time it will yield a value

languid dagger
#

Usually they get exhausted eventually but they can be infinite

gleaming rover
#

and the work done to produce the next value is only started when requested

zealous oriole
#

going back to my code thingy:

languid dagger
#

itertools.cycle is one such

deft pagoda
#
In [3]: def infinite(): 
   ...:     n = 0 
   ...:     while True: 
   ...:         yield n 
   ...:         n += 1 
   ...:                                                                                                                                                                                                                

In [4]: a = infinite()                                                                                                                                                                                                 

In [5]: next(a)                                                                                                                                                                                                        
Out[5]: 0

In [6]: next(a)                                                                                                                                                                                                        
Out[6]: 1

In [7]: next(a)                                                                                                                                                                                                        
Out[7]: 2
zealous oriole
#
def something(x):
  yield (x*x for x in range(x))

what happens here?

languid dagger
#

You yield a generator object

gleaming rover
#

in other words, something is a generator that produces a generator

zealous oriole
#

so you can do?

for val in something(13254):
  print(val)
gleaming rover
#

as opposed to infinite, which is a generator that produces int

#

you can do that, but you're just going to get <generator object...

zealous oriole
#

oh

languid dagger
#

!e

def f(x):
    yield (x*x for x in range(x))

fgen = f(3)
print(fgen)
g = next(fgen)
print(g)
for i in g:
    print(i)
fallen slateBOT
#

@languid dagger :white_check_mark: Your eval job has completed with return code 0.

001 | <generator object f at 0x7f05db2b6890>
002 | 0
003 | 1
004 | 4
gleaming rover
#

because now val is (x * x for x in range(x)

zealous oriole
#

ok so nested for loop then?

gleaming rover
#

but you could do:

for g in something(10):
    for val in g:
        print(val)
zealous oriole
#

yeah

gleaming rover
#

incidentally, you can flatten with yield from

zealous oriole
#

!e

def f(x):
    yield (x*x for x in range(x))

for gen in f(10):
  for num in gen:
    print(num)
fallen slateBOT
#

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

zealous oriole
#

WHAT

feral cedar
#

helper flex

deft pagoda
#
def flatten(iterable):
    for item in iterable:
        if isinstance(item, list):
            yield from item
        else:
            yield item
zealous oriole
#

what does that do?

#

check if its a nested thing

#

?

languid dagger
#

Given an iterable containing lists nested to any depth will give back a generator only containing the elements

#

So it removes all nesting regardless of depth

zealous oriole
#

ok

languid dagger
#

Wait, no. Only 2d since it's not recursive

zealous oriole
#

what does yield from do

#
a = []
a.append(a)
#

this is very interesting lol

languid dagger
#

short hand for

yield from iterable

for ele in iterable:
    yield ele```
zealous oriole
#

ok

#

thats big brain

deft pagoda
#

it's actually better than that

zealous oriole
#

wait how?

languid dagger
#

I think there's other situations as well

#

Such as nested generators

deft pagoda
#

something something error catching

zealous oriole
#

which is this case no?

deft pagoda
#

and async

#
In [14]: list(flatten([[1, 2, 3], 2, 4, [5, 6, 7]]))                                                                                                                                                                   
Out[14]: [1, 2, 3, 2, 4, 5, 6, 7]
#

that's flatten

zealous oriole
#

did u use ur function?

deft pagoda
#

yep

zealous oriole
#

so it can flatten stuff

#

interesting

deft pagoda
zealous oriole
#

so if i pass a nested list with lists randomly inside aswell, this function does that?

#

recursively

#
def flatten(iterable):
    for item in iterable:
        if isinstance(item, list):
            yield from item
        else:
            yield item
deft pagoda
#

no not this one

languid dagger
#

while 1 such blasphemy

zealous oriole
#

while 1 such blasphemy
@languid dagger what is that

deft pagoda
#

that's for flavor

languid dagger
#

As opposed to while True which do the same thing

zealous oriole
#

while true more cleaner and obvious tho

#

so why while 1

undone hare
#

I wonder if there is a smaller way to define an infinite loop than while 1:

zealous oriole
#

wtf does that mean

#

u guys can calculate infinity nvm

languid dagger
deft pagoda
#

i don't think so

gleaming rover
#

well

feral cedar
#

copy paste code until you hit infinity lines

gleaming rover
#

anything smaller would have to use for since 1 is a single character

feral cedar
#

that's 0 chars in the while loop definition

gleaming rover
#

and I don't think you can put a full condition in 4 characters...?

spice pecan
#

I'm pretty sure you just can't get shorter than while 1

zealous oriole
#
while (1):
# yes write some code here u big brain boi yes u
feral cedar
#

that's not that much better than while True though

zealous oriole
#

#bot-commands we go

#

its definitely ```py
while 1:

gleaming rover
#

hm

#

instead of while 1

#

how about while [()]

feral cedar
#

oh wow

deft pagoda
#

that's not shorter though

gleaming rover
#

yes

#

that wasn't the point

feral cedar
#

it looks cooler

spice pecan
#

idk if it's just me but that looks vaguely inappropriate

deft pagoda
#

the coolest throwaway variable is:

for {}[()] in range(100):
  ...
zealous oriole
#

wtf is that

feral cedar
#

oh dear

spice pecan
#

I mean yeah

deft pagoda
#

probably off-topic though

zealous oriole
#
for _ in range(of_my_door):
  ...
spice pecan
#

that's a true throwaway, _ still stores the value, {}[()] should get gc'd as soon as the loop ends

weak river
#

discord bot handle api hto ?

zealous oriole
#

whats {}[()]

feral cedar
#

apparently valid

spice pecan
#

empty dict literal, accessing its () (empty tuple) key

zealous oriole
#

bruhhhh

spice pecan
#

it should only exist as long as the loop exists

zealous oriole
#

so can you even access that thing

gleaming rover
#

it's basically

for i in range(100):
    d = {}
    empty_tuple = ()
    d[empty_tuple] = i
    del i
    del d
    del empty_tuple
    # ...do stuff...
spice pecan
#

from your code? nah

zealous oriole
#

lol thats evil

spice pecan
#

it's a bit over the top compared to, say, py for _ in iterable: pass del _
but yeah, it's a true throwaway, unlike _

narrow kettle
#

Have true throwaways been proposed as a language feature?

spice pecan
#

I'm not sure actually

#

_ acts as a true throwaway in the match-case pep

#

both for the default case and as filler variable

narrow kettle
#

Are they throwaways? Or just wild card patterns

brave badger
#

They're wild cards I believe

spice pecan
#

the other names get a value assigned to them, but _ are just ignored

#

so a mix of both I guess

narrow kettle
#

Ya standard oattern match wildcard, but that doesn’t mean they have “throw away” semantics how would that work anyways?

#

I haven’t paid much attention to the python pattern match thing so i could be very wrong

spice pecan
#

case Point(x, y) assigns the values to x and y

#

case Point(_, _) matches any Point

#

and throws away the values

narrow kettle
#

Does it instantly gc x and y?

spice pecan
#

x and y stay valid names throughout the case body and after the match block too iirc

narrow kettle
#

So it deletes x and y?

brave badger
#

Does it instantly gc x and y?
@narrow kettle Why would they be cleaned up if they're still being referred to by the structure you're matching against? pithink

spice pecan
#

no, it doesn't

#

case Point(_, _) just skips the assignment part afaik

narrow kettle
#

My question exactly pure

spice pecan
#

I'm not sure I understand what you mean

narrow kettle
#

Ya so it’s just a wildcard, I’m not seeing how that’s analogous to a throwaway variable

#

A throwaway or a discard is a variable that doesn’t exist, it’s never actually allocated

#

Or it’s allocated and instance deleted

slim island
#

what are the usecases of that? Is it not roughly the same as just del?

#

like, the examples I can think of are using it in loops

#

and that only seems like a tiny advantage over the current method

narrow kettle
#

Use case is that it allows you to be smarter with your allocations, which in normal py code isn’t a big deal, but could prob be useful in an embedded system

slim island
#

and not worth introducing the extra complexity for

brave badger
#

I gotta read the specification again

narrow kettle
#

Well also tuple returns

#

(/, /, foo) = bar()

slim island
#

for an embedded system, you're already probably messing about with garbage collection and del

#

it seems like a mild convenience in some niche cases - but also another thing that people are forced to be aware of

#

which adds extra complexity to the language for not that much utility

#

I guess in that respect, it's kinda like the walrus - although throwaways seem far less relevant than the walrus

narrow kettle
#

C# has throwaways ik for sure

#

And i think Haskell

spice pecan
#

I think if _ is going to get special treatment in the pattern matching pep, we might as well make it an actual throwaway everywhere

narrow kettle
#

But like Haskell has everything

slim island
#

it's not throwaway in pattern matching though

narrow kettle
#

C# is a discard in pattern matching

peak spoke
#

I don't think it should be made into a real throwaway in all contexts, it's still a widely used name for things like i18n functions

spice pecan
#

Currently _ is a valid name, and any name other than _ gets values assigned to it, while _ is a wildcard that doesn't get assigned to, effectively discarding the value

narrow kettle
#

I18n ?

spice pecan
#

internationalization

narrow kettle
#

Ahh

#

Ya i mean it’s probably a breaking change

#

Could do 2

#

__

spice pecan
#

that could work

slim island
#

I'm not sure if extra builtin stuff like that is what python needs - operator/keyword soup has a real cost to beginners

spice pecan
#

then again, del _ isn't much of a hassle

narrow kettle
#

It’s not a pressing issue oc but it does make it easier to manage your memory

spice pecan
#

true

narrow kettle
#

I mean beginners would never really touch this

slim island
#

at some point you have to touch this

narrow kettle
#

This is more of a bone to embedded systems devs etc

slim island
#

and beginners will stumble across it

languid dagger
#

When you say _ doesn't get assigned to is this just for match statements?

slim island
#

I don't think adding this utility for a tiny % of people is worth the cost of adding another thing to the language

narrow kettle
#

I mean they already stumble across _ =

spice pecan
#

@languid dagger yeah, in the context of match-case

narrow kettle
#

This isn’t really all that different practically

spice pecan
#

in other contexts it's a valid name

#

that keeps the value

slim island
#

something having semantic meaning is different to something having syntactic meaning

narrow kettle
#

It just has diff memory semantics

slim island
#

it's more easily ignored

narrow kettle
#

But it’s not REALLY relevant to a beginner, you can explain them the same way

#

“It’s a throwaway values”

slim island
#

I dunno - i'm not like super against it, it just doesn't seem to pose that much utility anywhere

#

and it does have a cost - it's not 0 cost

#

extra syntax is never free

languid dagger
#

What if they used Ellipsis instead? ... too annoying to type?

slim island
#

elipsis already has semantic meaning in python

#

that's completely different

languid dagger
#

Where is it even used?

slim island
#

I guess it also has syntax associated with it as well

#
In [1]: print(...)
Ellipsis
spice pecan
#

... is used as a filler for multidimensional slices

slim island
#

it's an object

#

it's similar to pass

spice pecan
#

I don't think I've seen it anywhere outside of numpy slices and stub files tbh

languid dagger
#

pass is a keyword though, ... is an Ellipsis type which is treated as a constant

slim island
#

it already has meaning - I don't think that should be changed or built upon

#

and it gets used the same as Pass

languid dagger
#

But ... wasn't added for numpy, numpy would have just used it as a placeholder for its own syntax

spice pecan
#

The were no uses for ... in the stdlib until (relatively) recently AFAIK, it's used in typing and that's about it

slim island
spice pecan
#

yeah, multidimensional slices

languid dagger
#

Hmm, so intended for custom containers

slim island
#

also - ... has completely different meanings in other languages - using it in python for throwaways just adds confusion when _ is the standard for throwaways

spice pecan
#

I think using * for throwaways could work

slim island
#
  • is used for spreading
spice pecan
#

both throwaways and match-case wildcards

slim island
#

that would be terrible

spice pecan
#

how so?

slim island
#

it already has associated meaning with it

#

and it's not even close to the meaning of throwaways

#

why would you ever bother? _ has the semantics of a throwaway, just not the implementation - if you want a throwaway, that's the only sensible choice

#

or possibly doubling it to avoid breaking changes (although that doesn't stop breaking changes, so that doesn't help)

spice pecan
#

While I'm not against using _ as a throwaway, it's going to be a fairly breaking change and giving it special treatment in some contexts and not others feels way too inconsistent imho

slim island
#

that's literally what you're proposing with * though

#

it having multiple completely different meanings

narrow kettle
#

I mean biting the bullet and saying make _ a true discard doesn’t seem THAT bad

spice pecan
#

it already has several - it separates kw-only args from regular args, it's used for unpacking and is used for multiplication, which are all completely separate meanings

narrow kettle
#

How often is one underscore being used as a variable anyway

slim island
#

using * is just straight up very confusing in some contexts

#

In [4]: a, **, b = [1,2,2,3] just looks silly

narrow kettle
#

_ is a pretty standard throwaway syntax

slim island
#

and it's not at all clear what it's doing

#

and is a very common use of _ as a throwaway

#

having 2 of the same symbol next to each other - where they're doing completely different things - is unbelievably confusing and silly from a beginner's perspective

spice pecan
#

That is true

#

I'm just pressing the idea that we should either go all the way and make _ a true throwaway regardless of the context, or use something else entirely, as having it be a valid name in some cases and a special character in others feels inconsistent to me

flat gazelle
#

I mean, you don't even need throwaway syntax in a pattern match, you can just use a is this value of class object match (iirc object() as per the PEP)

slim island
#

many symbols in python have different meanings in different contexts

#

which is fine

unkempt rock
#

Hello, can someone explain this in simpler terms. I don't understand what np.linspace(0,5,10) actually does , Outputted array:

       2.77777778, 3.33333333, 3.88888889, 4.44444444, 5.        ])```
flat gazelle
#

it creates a 10 elements long array such arr[0] is 0 and arr[-1] is 5 and differences of neighboring elements are equal

unkempt rock
#

Oh! thanks, didn't realize lol

#

Have a good day, sir 🙂

paper echo
#

@unkempt rock the numpy documentation is sometimes hard to read, but if you make it all the way through one of their documentation pages it can be very rewarding

pseudo cradle
#

I live in numpy and am still learning new tricks with it

paper echo
#

yep

#

i finally figured out how axis= works

#

or at least, in a way that sticks

#

plenty of lessons to be learned on language design here

pseudo cradle
#

Nice!

#

I think I once just swapped axes before I understood that, haha

arctic scaffold
#

This is some advanced stuff 👍

unkempt rock
#

is there anyone that knows about pillow?

pseudo cradle
#

Probably, but not me

narrow kettle
#

is there a way to make a singleton WITHOUT having to call the class with ()```py
class Foo:
def init():
self.a = 1

print(Foo.a)

spark magnet
#

singletons are bad ideas 😦

unkempt rock
#

Probably, but not me
@pseudo cradle well....

narrow kettle
#

in this case its for singleton of events

pseudo cradle
#

Why are singletons bad? It's a useful design structure

spark magnet
#

i don't know what that means?

narrow kettle
#
class Events(metaclass= Singleton):
    """Class that defines what events are exposed at the bot level"""
    @property
    def on_broadcast_designated_channel(self):
        """
        Published when a reqeust to broadcast a message to all registered channels
        in all servers is sent

        Args:

            channel_type (str) The designated channel to broadcast the message to
            message (union[embed, str]) the message to be sent to the channels
        """
        return '_on_broadcast_designated_channel'
#

as an example

spark magnet
#

Classic singletons are classes that lie when you ask them to make an object.

narrow kettle
#

these are all constants anyway

spark magnet
#

Even "just one object" classes that don't lie are hiding a global, with the usual problems.

unkempt rock
#

can someone pls explain this code: "**" is unpacking. lambda *x, **y: self.do_response(self.init_response)

narrow kettle
#

these are all globals

#

its just a list of string events

spark magnet
#

@narrow kettle maybe just define some variables in the module?

narrow kettle
#

then i cant put pydoc comments on them

spark magnet
#

Or an Enum?

narrow kettle
#

can you put pydoc comments on enums?

spark magnet
#

why call them singleton when you mean constants?

narrow kettle
#

i did properties cuz thats the only thing vsc would show in the pydoc box

#

i mean its just one singleton

#

the events class

#

that contains many constants

#

essentially i want a way to write Events.on_some_event

#

so enum

#

but i didnt think you could put pydoc comments on enums

spark magnet
#

i'm not sure, you'd have to experiment.

teal yacht
#

Why are singletons bad? It's a useful design structure
@pseudo cradle singletons are only useful when you feel bad about making a global variable so you pretend it's not

narrow kettle
#

i dont think you can

#

hmm

pseudo cradle
#

rofl

#

Singletons still have valid applications

spark magnet
#

@pseudo cradle tell us why it's useful

pseudo cradle
#

Okay, you're designing a class you only want one instance of

teal yacht
#

Not any more valid applications than global variables

#

Just make a global

narrow kettle
#

yep you cant

spark magnet
#

why not just make only one? Why does the class have to enforce it?

teal yacht
#

(Or better yet, design your program better)

narrow kettle
#
class DesignatedChannels(Enum):
    """Enum that defines possible designated channels for the bot to use"""

    @property
    def message_log(): 
        """[summary]
        """
        return auto()
print(DesignatedChannels.message_log)
pseudo cradle
#

So you don't have to worry about passing it around?

narrow kettle
#

>>> <property object at 0x1070241d0>

pseudo cradle
#

Like, it's still a useful design structure that's taught in CS

spark magnet
#

that sounds like laziness

#

You can't just say "it's useful" you have to back it up

#

and "taught in CS" doesn't mean much

pseudo cradle
#

Laziness is a valid reason

narrow kettle
#

they are less useful in langs with dedicated DI

#

python doesnt really have that

teal yacht
#

I disagree

#

We already have more than enough issues in this industry with technical debt

#

Laziness should be eradicated

spark magnet
#

@pseudo cradle you had to have access to the class to call its constructor. However you got the class, just get the one object.

narrow kettle
#

does anyone know how to attach a pydoc comment to a variable

#

thats basicalyl what i want

pseudo cradle
#

You had access to the class, you didn't necessarily have access to the object.

narrow kettle
#

i want a way to document my constants

spark magnet
#

@pseudo cradle why didn't you have access to the object?

pseudo cradle
#

Why did you?

spark magnet
#

we're going in circles. write your program so that you have the object.

peak spoke
#

You can assign __doc__ if that's what you need

spark magnet
#

You said, "I don't want to pass it around" you don;'t have to,

pseudo cradle
#

Or use a singleton when it's valid

spark magnet
#

Can you give an example of a valid singleton?

pseudo cradle
#

We're disagreeing on design choices

spark magnet
#

I'm asking you to justify your choice

pseudo cradle
#

Let's say you have multiple people working on the code and you want to prevent more than one instance being generated

spark magnet
#

@pseudo cradle you said, "Okay, you're designing a class you only want one instance of". That means the user of the class wants only one. Why is that an essential characteristic of the class?

pseudo cradle
#

Sure, code better, code more thoroughly, etc. etc.

#

Or prevent it from happening

spark magnet
#

give them a convenient way to get the one instance. Why make it be a lying constructor?

narrow kettle
#

generally id say make that a module then

pseudo cradle
#

constructing the class seems like a pretty convenient way to get the instance while also preventing more than instance from being made

spark magnet
#

MyClass.get_the_one() is also convenient.

#

and is clear what it's doing.

#

there's no reason to write lying constructors.

#

why hide that aspect of the class from your callers?

narrow kettle
#

thats what i do for singletons generally

#

get_instance

#
class Foo:

  @property
  def bar():
    return 1
  
print(Foo.bar)``` tho does anyone know how to make something like this work
#

this is basically what i want

pseudo cradle
#

Sure but MyClass.get_the_one() requires you to know that method, whereas someone with less knowledge/access can just create the class

spark magnet
#

@pseudo cradle your callers need to know how to use the class, absolutely.

#

when did you last write a lying constructor in Python?

narrow kettle
#
class Foo:

    __instance = None

    @staticmethod 
    def get_instance():
        """ Static access method. """
        if Foo.__instance is None:
            Foo()
        return Foo().__instance

    def __init__(self):
        """ Virtually private constructor. """
        if Foo.__instance is not None:
            raise Exception("Foo is in singleton scope")
        else:
            Foo.__instance = self
paper echo
#

what about something like asyncio's event loop or loggers? where you don't explicitly use the class, you call a function to get an instance?

narrow kettle
#

there ya go, you enforced the singleton

spark magnet
#

@narrow kettle at least use @classmethod

#

@narrow kettle that will really suck to use.

#

(if people try to construct it)

pseudo cradle
#

loggers, caching, thread pools, config settings, device driver objects...

spark magnet
#

@pseudo cradle you've written those?

narrow kettle
#

that will really suck to use.
how so

#

i mean how is that any diff then any other singleton wiht an explicit get method

pseudo cradle
#

Write I actually write in my day to day are algorithms

spark magnet
#

@narrow kettle sorry, if they try to use the constructor, since it will only work once

narrow kettle
#

yes

pseudo cradle
#

But what I do in my day to day is irrelevant to this conversation

narrow kettle
#

thats kinda the whole point

spark magnet
#

@pseudo cradle in Python, logging is: logger.getLogger(), not a constructor

narrow kettle
#

you are enforcing that you DONT use the ctor

spark magnet
#

yes, i see, sorry

#

@pseudo cradle you seem convinced of the utility of singletons, so I'm asking for your personal experiences with them. where you have found them good.

#

@narrow kettle it's still a hidden global that makes things like isolated testing difficult.

pseudo cradle
#

Well, I've written drivers in ASM and have done config files in basically every language I've used

narrow kettle
#

you gotta make some stuff global, esp configs

spark magnet
#

i find more and more that I can avoid that if i try

narrow kettle
#

in the absence of DI in python your options are modules or a singleton

spark magnet
#

or passing things around

#

or making them attributes on an application class

pseudo cradle
#

passing things around is a design choice, not one I'd always find optimal

spark magnet
#

yeah, that gets awkward

narrow kettle
#

when everything is decouple thourghly attributes on a single class wont work super well

#

and passing things around is not fun, and is a ROYAL pain to refactor

pseudo cradle
#

Out of curiosity ned, how do you feel about factory design patterns?

teal yacht
#

it's also a pain to debug and test misused globals

narrow kettle
#

if i was writing in say c#, id just inject an instance in singleton scope

#

easy peasy

spark magnet
#

i'm not sure what a factory pattern is in Python: every function returns objects.

#

my problem with patterns is that the gang of four wrote a book based on C++ and Java, and now everyone talks about those patterns as if they applied everywhere.

pseudo cradle
#

gang of four aside, because there's definitely valid criticisms against that book

spark magnet
#

ok, gang of four aside, tell me what a factory pattern is.

pseudo cradle
#

It's an interface for creating an instance of a class

narrow kettle
#
class FooFactory:
  def getFoo: return Foo1()

class Foo1:
  pass

class Foo2:
  pass
#

this concept works better with interfaces imo

#

good lord i think this might be an impossible task in python, static properties

pseudo cradle
#

Between this conversation here and the one in #ot1-perplexing-regexing I'm finding it hard to pull away and do work 😦

#

(One guy convinced Python sucks and is arguing with everyone about it)

narrow kettle
#

i think static properties are the first thing ive found that python cant do

#

thats impressive

flat gazelle
#

you can do them with metaclasses

#

!e

class U(type):
    @property
    def prop(self):
        return 7
class V(metaclass=U):
    pass
print(V.prop)
fallen slateBOT
#

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

7
narrow kettle
#

ahhhhhhhh that works

#

ty @flat gazelle i was playing with something like that but didnt get it quite right, ty

#

python once again proves its the most flexible lang out there

spark magnet
#

@pseudo cradle @narrow kettle in the FooFactory example: why is it a class? why not just a function?

narrow kettle
#

it could be just a function, i was jsut writing off the cuff, im used to c# which would oc need a class

spark magnet
#

I think functions that make objects are great. (it's what i was advocating for instead of lying constructors 🙂 )

pseudo cradle
#

Idk, I'm all for an extra layer of fuckup protection

spark magnet
#

@pseudo cradle i just don't see how it prevents screwups to make things behave differently than they appear.

brave badger
#

Does pathlib.Path.__new__ fit the Factory pattern?

spark magnet
#

that's a constructor (of sorts)

peak spoke
#

PurePath and Path are factories for the OS dependent path classes

spark magnet
#

is add(1, 2) a factory for 3?

pseudo cradle
#

Are you against design patterns fundamentally?

peak spoke
#

no, because add is not a class which creates different class instances depending on some condition

narrow kettle
#

I don’t think that fits a factory

spark magnet
#

No. I'm against doing Java things in Python when we don't have to.

narrow kettle
#

Factory is essentially just a ctor abstraction

teal yacht
#

I think design patterns were created for very specific languages, and most of them do not fit most other languages

narrow kettle
#

Make of that what you will

teal yacht
#

What nedbat said basically

narrow kettle
#

Design pattern don’t fit but design principles do

#

Key difference

teal yacht
#

Yeah, and it's all about using the tools we have at hand given a tool

peak spoke
#

The two classes I mentioned in particular look like factories to me, and are referred to as such in the PEP that proposed their implementation

narrow kettle
#

Solid will never go out of style imo

boreal umbra
#

In my code I have a line that's just None because I needed a place to put a breakpoint

#

what does the interpreter do when there's a line that does nothing?

spark magnet
#

you can use the dis module to see

narrow kettle
#
Foo.bar = classmethod(lambda cls: "stubbed_name")
```is there a way to make this a coroutine
spark magnet
#

jay, it seems like you are working against the usual structure of classes

raven ridge
#

open is also a factory - it returns different types of objects depending on whether you want buffering, text mode or binary mode, and read or write.

The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper). When used to open a file in a binary mode with buffering, the returned class is a subclass of io.BufferedIOBase. The exact class varies: in read binary mode, it returns an io.BufferedReader; in write binary and append binary modes, it returns an io.BufferedWriter, and in read/write mode, it returns an io.BufferedRandom. When buffering is disabled, the raw stream, a subclass of io.RawIOBase, io.FileIO, is returned.

narrow kettle
#

jay, it seems like you are working against the usual structure of classes
probably, im trying to mock an async def on an instance method

#

stumbling around in the dark tbh

spark magnet
#

@raven ridge how is a factory different than a function that returns objects?

raven ridge
#

It's a function that can return objects of different types.

spark magnet
#

a lot of functions do that

raven ridge
#

a lot of functions are factories 😄

narrow kettle
#

i have two checks that i need my mock to pass py if inspect.ismethod(obj): and if not asyncio.iscoroutinefunction(callback):

#

and i can not for the life of me figure out how

raven ridge
#

if there's a function where a) the primary purpose is to create a new object, and b) the type of new object that it returns can vary, that's a factory. They're not that uncommon, pathlib.Path() and open() are both excellent examples.

#

open is a little more clear, since it doesn't masquerade as a constructor.

spark magnet
#

@raven ridge but int() isn't a factory? In Python 2, it could return two different types.

narrow kettle
#

i mean technically all classes are factories, as they are just generators for instances

raven ridge
#

No, I'd say that int is a factory, in Python 2. It meets that definition.

spark magnet
#

but not in python 3?

raven ridge
#

a factory is just an object creator that abstracts the user from the type of object they'll get. In Python 2, int did that.

#

in Python 3, it doesn't - it always returns an int.

#

the purpose of a factory is decoupling - you can assume that the objects returned to you implement some common interface (in Python, via duck typing, in Java, via an interface or base class), without knowing which specific type you'll get.

narrow kettle
#

in java if it returned an Integer and not integer it would also be a factory

spark magnet
#

Jay, so your definition is a little different

narrow kettle
#

as with all design pattern the concept itself is nebulous, but generally anything that returns an object would be considered a factory for that object in some way

raven ridge
#

that's not the normal definition of the factory pattern.

narrow kettle
#

if it returns an object in such a way that you dont have to think about what actual class is being returned

#

thats a factory

spark magnet
#

but every function in python returns an object

narrow kettle
#

which still works better with interfaces imo

raven ridge
#

Wikipedia goes with:

In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
It specifically needs to be for the specific purpose of creating a thing, and it specifically needs to be able to return different classes of objects.

#

@spark magnet have you seen the arguments that design patterns are indicative of design flaws in a language, common problems that are so common and with such non-obvious solutions that programmers are forced to memorize rote solutions for them?

gleaming rover
#

but every function in python returns an object
@spark magnet except functions that don't return at all

raven ridge
#

those return None, which is an object.

gleaming rover
#

no.

narrow kettle
#

thats also an object lol

gleaming rover
#

functions that don't return at all e.g. infinite loops

teal yacht
#

"hurrdurr but you can always have it throw"

gleaming rover
#

or that exit

teal yacht
#

get out with your non total functions

gleaming rover
#

which is why there is typing.NoReturn

narrow kettle
#

thhose arent relevant then as they never finish

gleaming rover
#

just for these cases

#

edge case but technically correct, which is the best kind of correct

raven ridge
#

sure. fine, fair enough. "The only thing a function can return is an object" is the more precise phrasing, I suppose.

gleaming rover
#

perfect example of Smith's Law

#

but every function in python returns an object
@spark magnet but anyway before I derailed this discussion...I think it's about variability of type?

#

honestly I never really got the factory pattern (it's one of the holes in my knowledge since I don't have a CS education) but this is my guess

spark magnet
#

i think the key idea is "abstract away the specifics of the type returned."

raven ridge
#

I think it's about variability of type?
that's correct. If its primary purpose is creating things but it always returns the same type of thing, that's more like the "named constructor idiom".

#

that's things like datetime.date.today(), for instance.

#

design patterns have a bad reputation because the one that most people find easiest to name is the Singleton pattern, which is crap. It's a pattern whose entire purpose is to allow you to create a global variable in a language whose data model doesn't want you to have global variables.

narrow kettle
#

i will say that often times factories are abused and they do always reuturn the same type -__-

#

my last job abused that

gleaming rover
#

honestly I was under the impression that a factory method was one that performed argument preprocessing/resource acquisition etc. before calling the constructor

#

and the constructor (well, initialiser, like __init__) should only set instance attributes

#

what do you call that then

raven ridge
#

I'd call that an alternative constructor, or a named constructor

#

or a constructor method

gleaming rover
#

and the constructor (well, initialiser, like __init__) should only set instance attributes
@gleaming rover isn't this a pattern

raven ridge
#

like datetime.date?

#

the real constructor only takes year/month/day and stores them, and there's a class method called today that acts as an alternative constructor that looks up today's year/month/day and passes those as arguments to the real constructor

#

I don't know that there's any particular name for that design, though it's somewhat common.

gleaming rover
#

something like that but a bit more involved, like:

class Storage:
    def __init__(self, connection):
        self._connection = connection

    @classmethod
    def create(cls, uri, username, password):
        ...create connection...
        return cls(connection)
#

like there would be no public constructor

#

in an equivalent language

raven ridge
#

hm. I'd consider that an anti-pattern - at least in Python, where it's not possible to not have a public constructor.

#

(Though you can do it in Cython!)

gleaming rover
#

in the general case

narrow kettle
#

ya idk if id want that in python, you cant enforce it

#

well you kinda can

gleaming rover
#

yeah, I mean in general

narrow kettle
#

but its not ideal

gleaming rover
#

with enough effort

raven ridge
#

in general, "named constructor" is what I'd call it.

narrow kettle
#

i will agree that its better to have connection code etc in a seperate mthod

gleaming rover
#

I don't think it's an antipattern though

narrow kettle
#

requiring like SomeApiClass().Connect() is better imo then just SomeApiClass() because then you put your connection logic in the ctor

gleaming rover
#

in line with "all consenting adults here"

#

this facilitates testing too

#

because then you can test the resource acquisition logic separately

narrow kettle
#

on the testing front does anyone know how to mock a method that will pass both these checks ```py
if inspect.ismethod(obj):
and
if asyncio.iscoroutinefunction(callback):

spark magnet
#

@narrow kettle maybe it would be easier to implement a fake than a mock?

raven ridge
narrow kettle
#

maybe it would be easier to implement a fake than a mock?
can i still assert that it was called with a fake?

#

or rather assert it was awaited

#

@raven ridge forgive me but i dont see how that helps me?

spark magnet
#

you can do whatever you want with a fake

#
class MyFake:
    def __init__(self):
        self.times_called = 0
    def method(self):
        self.times_called += 1
raven ridge
#
In [1]: import asyncio
   ...: class C:
   ...:     @asyncio.coroutine
   ...:     def func():
   ...:         yield from asyncio.sleep(1)
   ...: 

In [2]: import inspect

In [3]: f = C().func

In [4]: inspect.ismethod(f)
Out[4]: True

In [5]: asyncio.iscoroutinefunction(f)
Out[5]: True
narrow kettle
#

ahhok i see ned, and i can just assert the times called

raven ridge
#

yeah. Between what ned's saying and what I'm saying, you should have everything you need to make whatever assertions you want.

narrow kettle
#

ya i think i can make this work, let me go look

#

yep that did it, thx i was making that way more complex then it needed to be

#
    @pytest.mark.asyncio
    async def test_publish_event_invokes_listener(self):
        messenger = Messenger()

        class Foo:
            def __init__(self):
                self.called = 0

            async def async_mock(self):
                self.called += 1

        foo = Foo()
        messenger.subscribe('bar', foo.async_mock)
        await messenger.publish('bar')

        assert foo.called == 1
raven ridge
#

you can even assert what it's called with, if you want, by calling a mock 🙂

narrow kettle
#

ive been playing with mocks for the past 4 hrs lol

raven ridge
#
class Foo:
    def __init__(self):
        self.mock = unittest.mock.Mock()
    async def async_mock(self, *args, **kwargs):
        self.mock(*args, **kwargs)
foo = Foo()
messenger.subscribe('bar', foo.async_mock)
await messenger.publish('bar')
foo.mock.assert_called_once_with()
narrow kettle
#

ohhh the mock IN the fake class

#

gotcha

#

that makes sense

spark magnet
#

mmmm, green....

narrow kettle
#

i want to add coverage too, but uhh, i dont think a coverage of like 10% will impress anyone 🤣

spark magnet
#

i bet you have more like 35%

narrow kettle
#

hopefully once i get finished writing all these lol

pseudo cradle
#

When you don't pass your tests, create new ones 😄

unkempt rock
#

Or the opposite, if you finally solve a bug that wasn't caught by your tests, add regression tests to make sure it doesn't pop up again. Writing tests is real programming.

paper echo
lusty sorrel
#

@narrow kettle if you want a test suite out of hell I invite you to look at PyInstaller

#

It's a pain maintaining it

#

A test fails every few days on a dependency upgrade

#

The whole suite needs rewriting

narrow kettle
#

i mean ya id imagine, tons of dependencies and platforms

tawny shoal
#

Is cx_Freeze any better in that regard?

rigid snow
#

Has anyone here used 'ring central' to send text messages?

spark parcel
#

That is better suited for an off-topic channel

vague dirge
#

Hi, anyone can help me with autorun raspi?

fallen slateBOT
#
**PEP 468 - Preserving the order of \*\*kwargs in a function.**
Status

Final

Python-Version

3.6

Created

5-Apr-2014

Type

Standards Track

boreal umbra
#

sorry wrong one

#

!pep 463

fallen slateBOT
#
**PEP 463 - Exception-catching expressions**
Status

Rejected

Python-Version

3.5

Created

15-Feb-2014

Type

Standards Track

boreal umbra
#

why wasn't this accepted?

#

I feel like this would be good:

#
var = my_list[8] except KeyError with None
daring siren
#

I think I agree with Guido on this one

full jay
#

That.... yeah I really don't like that

boreal umbra
#

what do you hate most about it?

full jay
#

I feel like try except stuff should be very obvious and structured

#

Having it nestled in-line just feels... dirty, I guess

boreal umbra
#

I mean it would have limited use but so does inline if else.

full jay
#

Sure but if/else don't typically handle things that would prevent the whole program from crashing.

#

It's already easy enough to accidently silence errors by having an empty exception. I can't imagine it would be very fun to have to hunt through everything to find one that's in-lined

#

I might just be weird about it, though

boreal umbra
#

I'm not sure I understand how inline would make it harder to debug

feral cedar
#

I'm sure if it was a thing we'd get used to it, and like steler said it's probably not going to be used that often

boreal umbra
#

broad exceptions that handle errors you didn't know you could get is problematic but I'm not sure that this would encourage people to do that.

paper echo
#

i dont hate it

#

because you still can only use expressions in the with

#

can't use raise from et al

#

i suppose most use cases for it are already covered by getattr and .get

paper echo
#

however you know what i really really want?

#

a type annotation stating what exceptions a function can raise

peak spoke
#

I'd probably prefer that in the docstrings, you can mostly control what types you return but (unexpected) exceptions can be introduced with changes to the code, some can be trigerred on any line etc.

boreal umbra
#

@paper echo I've been thinking about that kind of thing. do you have a syntax for that in mind?

paper echo
#

nope, no idea

grave jolt
#
def my_fun(x: int) -> float raises KeyError:
    ...
#

ehhhhhhhh

#

😎

def my_fun(x: int) -> Either[KeyError, float]:
    ...
#

if you're a type freak like myself

boreal umbra
#

I feel like the implication in the first example is that the float somehow raises a key error

#

it could be

grave jolt
#
@raises(KeyError)
def my_fun(x: int) -> float:
    ...
paper echo
#

im good with @raises

boreal umbra
#
def my_func(x: int) -> float, t.Raises[KeyError, IndexError]:
    ...
paper echo
#

the question is: what happens if a function called by my_fun raises the error?

#

it should probbaly not be recursive, right?

flat gazelle
#

It absolutely should

boreal umbra
#

I can't think of a reason to make it a decorator

#

decorators do stuff and type annotations don't

grave jolt
#

@final is a decorator 🤔

paper echo
#

@flat gazelle but then aren't you basically looking at @raises(TypeError) on a lot of things that use built in functions?

#

and @typing.overload

flat gazelle
#

I would like Raises[float, [TypeError]]

#

But it is useless otherwise

#

If it only tells me some exceptions

paper echo
#

true

grave jolt
#

we should create a version of python that has no exceptions 🙂

flat gazelle
#

Obviously you do not include exceptions that would happen if you break the type hint

paper echo
#

the Go discord is that way 👉

brazen jacinth
#

i don't find it that ugly i guees

var = Model.objects.get(*args, **kwargs) except Model.NotFoundError with Model.objects.create(*args, **kwargs)
try:
  var = Model.objects.get(*args, **kwargs)
except Model.NotFoundError:
  var = Model.objects.create(*args, **kwargs)
boreal umbra
#

Cython--

brazen jacinth
#

except maybe that with doesn't feel right

boreal umbra
#

it's like C++ but Python and has less than Cython

flat gazelle
#

No exceptions are problematic. There is quite a bit of erroring state in a real language

grave jolt
#

we should create a version of python that has no exceptions
an error just turns into a SIGSEGV

flat gazelle
#

Do you call MemoryError an exception

boreal umbra
#

except maybe that with doesn't feel right
@brazen jacinth as would give the false impression that it's the same as except x as e

flat gazelle
#

Go and Rust just abort, but I do not consider that a great solution to memory errors

grave jolt
#

I meant that a language could be restructured so that only "critical" stuff raises some kind of error

#

but that probably doesn't play well with dynamic typing

flat gazelle
#

Haskell does that somewhat, but Haskell errors are objectively terrible.

grave jolt
#

I haven't interacted with the IOErrors in haskell, but I've seen that it's not the most pleasant thing

#

I guess it's trying to tell people that it's kind of a last resort

brazen jacinth
#

does an exception itself being raised cause any significant overhead?

#

Stack trace gets handled by something lower level i imagine, but how big is this cost

#
if a[0]:
  val = func(a[0])
else:
  pass 

try:
  val = func(a[0])
except Exception:
  pass
#

hypothetical situation

grave jolt
#

I guess the approach depends on how likely it is that an error occurs

peak spoke
#

Handling is somewhat expensive when exceptions occur, but takes almost no time when it doesn't

brazen jacinth
#

What even happens, you do something unexpected -> in some way it raises an exception -> the interpreter keeps track where it happened and bubbles up the exception to where it is caught, along with it stack trace info (or if uncaught - some low level signal handles the unhandled exception cleans up and exits) and then handles the control back to the program?

#

or is there something more that happens underneath when an exception occurs?

full jay
#

That's pretty much the gist of it.

modern frigate
#

Does python handle the memory, or does C do that

#

ik that memory location is decided at runtime, but im not sure if the python devs had to develop their own way of interacting with memory or if c handles all that

tropic fulcrum
#

Which Python implementation are you using? CPython? PyPy? Jython? IronPython?

unkempt rock
#

That site is so good. I can't read enough of their articles.

modern frigate
#

Thanks!

#

That site is so good. I can't read enough of their articles.
@unkempt rock Its free articles are pretty good, but it quickly becomes money hungry

unkempt rock
#

I didn't even know they had pay articles. I know that they have some sketchy webdev techniques, like demanding your email address before providing you with the link to their GitHub for resources used in in guides. Things like that irritate me about them.

#

But they write good articles.

modern frigate
#

I emailed dan bader, who made the site to ask a simple question about the topic. His reponse was pretty rude:

Hey, JetDeveloping.

The article doesn't cover this question.
#

But they write good articles
Yeah

#

thanks for the article btw 😄

tropic fulcrum
#

@modern frigate Out of curiosity, why do you ask about memory management? You can write Python for years without having to worry about it. You may just be getting ahead of yourself.

peak spoke
modern frigate
#

@modern frigate Out of curiosity, why do you ask about memory management? You can write Python for years without having to worry about it. You may just be getting ahead of yourself.
@tropic fulcrum just curious.

unkempt rock
#

is codeacademy good for learning phyton?

modern frigate
#

Yeah, it seems pretty legit

grave jolt
#

ik that memory location is decided at runtime, but im not sure if the python devs had to develop their own way of interacting with memory or if c handles all that
Well, the OS handles that in the end :)

paper echo
#

I think they're asking if the cpython devs use their own memory allocator

prime estuary
#

CPython does have its own memory allocator, to more efficently use the blocks of memory given to it by the OS.

#

It's got lots of tricks as well - for instance a certain number of tuples are kept around when destroyed, so they can be reused when another is required of the same size.

raven ridge
#

+= on a str also cheats and modifies it in place if there's only one reference.

#

(on the topic of the interpreter mutating immutable objects, though not directly related to memory management)

unkempt rock
#

I think it was you that I've seen mention it here before as well, but that's obviously because there's a difference between being described as immutable on the level of Python and on the level of the underlying interpreter/C.

grave jolt
#

Well, it's the same as (a, b) = (b + a, a) not actually creating a tuple, I think

spark magnet
#

it's a different kind of optimization

magic python
#

is it safe to depend on the ordering of dicts now 🤔

#

I mean - i get it's there - but is it here to stay

#

maybe that's a "how long is a piece of string" question, I was unsure whether people usually took this as a side effect or as something which was a fixed part of the language now

brave badger
#

Isn't it more of an implementation detail than an actual feature?

spark magnet
#

it's guaranteed semantics as of 3.7

raven ridge
#

@unkempt rock it's obvious that the interpreter can do it, it's an interesting optimization that it does.

#

it's guaranteed semantics as of 3.7
And it was made guaranteed semantics because it was assumed that people would begin to depend upon it either way, so it was better to guarantee it and commit to backwards compatibility on it.

paper echo
#

It's also just a nice feature

gleaming rover
#

it's nice, but from a conceptual point of view it's kinda meh

#

IMO

grand leaf
#

I have no idea what I'm doing wrong.
So in views.py (I'm using django), I have a function that uses subprocess to run a java file (that returns a string "Hello World from Java"). I'm using subprocess.check_output because it returns output as a byte string.

def executeJava():
    javaoutputstring = subprocess.check_output("javac HelloWorld.java;java HelloWorld", shell=True, cwd="../")
    print(javaoutputstring.decode("utf-8"))
    return javaoutputstring

So I have another function that executes executeJava() and is supposed to post some string statements onto an html page.

def form_submit(request)
    #this works because I see the output in terminal, but I want it on the webpage
    executeJava() 

    context = {
            'string' : "This is the context string passed from the view",
            #'string2' : javaoutputstring,
        }
        return render (request, 'templates/index.html', context)

How can I print javaoutputstring onto the html page? Putting {{string}} prints out the statement on the page just fine, but not for {{string2}}

#

oh wait, forgot to put into a help thread, I'll ask there

gleaming rover
#

wrong channel

#

but anyway

grand leaf
#

yea, realized it after I posted it, but I'm desperate for an answer

gleaming rover
#

not really an excuse, but anyway

#

you're printing the decoded string, but returning what I assume is the encoded bytes object

#

that looks like the problem

#

also you don't seem to be assigning the result of your function to a variable...?

#

and you have executejava and executeJava

#

honestly everything kind f looks like a mess.

grand leaf
#

so javaoutstring isn't technically a "string", its still in bytes format is what you're saying

gleaming rover
#

if you have further queries you should open a help channel

grand leaf
#

cool, I realized I put it in the wrong channel right after I posted it, but thx for the help anyways

boreal umbra
#

I don't really see how having dicts remember their insertion order is that useful but I guess I just haven't come across a case where it's useful

#

I think I've only sorted a list of the k-v pairs to print them and that's about it.

pseudo cradle
#

I guess it's good for... I don't know, people who expect dicts to behave like an array/list?

#

Also, why doesn't python like having variables start with a number?

teal yacht
#

ambiguities

boreal umbra
#

If you start a token with 0x it will be read as an integer in hex format

teal yacht
#

you could have 1 be a valid identifier, or 1e3, or 0x1

boreal umbra
#

Or if you do b instead of x it's binary

teal yacht
#

it's simpler to disallow them entirely than to account for all edge cases

boreal umbra
#

Lgneous is right. You can use e to make exponentials.

pseudo cradle
#

Okay, fair

#

I hadn't considered that

teal yacht
#

it's also a common convention, so it's not gonna catch people off guard

pseudo cradle
#

I didn't even know you couldn't start a variable with a number until I came across it in a help channel

#

sigh because I'm cruising help channels instead of working

boreal umbra
#

Well, it's not a variable at that point

#

It's an int or float literal

pseudo cradle
#

That makes sense

#

👍

charred barn
#

it's a lot easier when you're parsing the language if variables can't start with numbers

torpid narwhal
#

I forgot the use case, but remembering their order was extremely important. I was quite happy that whatever version of Python had dicts remember their insertion order.

feral cedar
#

like 3.5 or something

#

you can always use ordereddict

boreal umbra
#

At this point I think the only use for ordered dict is that the order affects equality comparison

#

At this point anyway

#

I thought it was 3.6 when it started

raven ridge
#

no, it's also optimized for different operations. OrderedDict has operations specifically to support reordering, which are more efficient than if you were to reorder things in a regular dict by removing an element and then re-adding it. This makes OrderedDict more efficient as an LRU cache implementation, for instance.

#

It also has extra methods specifically to support that use case - unlike dict, the popitem method of OrderedDict allows you to choose whether you want to pop the earliest or the latest item, and it has a move_to_end method specifically to support reordering.

torpid narwhal
#

I wonder how much of a benefit there is?

#

From the optimization side of things

raven ridge
#

I don't really see how having dicts remember their insertion order is that useful
@boreal umbra There are scenarios where people want an ordered mapping, and where it's useful to perform operations either based on the key or based on the order (and not always the same operations). An LRU cache is the most common example - you want to be able to look up cached values by key, but drop the least recently inserted items when you need to make room. Another might be representing the columns in a SQL result set or an Excel spreadsheet or something - after a select col1, col2 from table it might be reasonable to want to support accessing columns from the result set by either index or name. If you want to pass around the dict and access them by name, you can. If you want to unpack the columns immediately into their own variables, you can:

#

!e ```python
import sqlite3

def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d

conn = sqlite3.connect(":memory:")
conn.row_factory = dict_factory
for row in conn.cursor().execute("select 1 as 'A', 2 as 'B'"):
a, b = row.values()
print(f"row={row} a={a} b={b}")

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

row={'A': 1, 'B': 2} a=1 b=2
raven ridge
#

in older Python versions that unpacking wouldn't have been safe or sane, and now it is.

#

Basically...

I don't really see how having dicts remember their insertion order is that useful
It isn't if you were already going to be using a dict. It's useful in cases where previously you couldn't use a dict, because you needed an insertion order preserving data structure, and you wound up having to use something like collections.OrderedDict or roll your own like https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers or the like, and now, in some cases, you can avoid rolling your own because if you use dict just so it can give you the guarantee you need with much less work than writing some alternative class that wraps a dict and adds an ordering yourself.

unique heart
#

hey guys. I'm trying to fetch the github repo link for a python package. what website can I send a request to?

raven ridge
#

That's not to say that werkzeug.datastructures.Headers could be implemented as just a dict now - it still can't, because in addition to needing to preserve order, it needs another feature that dict doesn't provide - allowing multiple values for the same key (because HTTP headers are weird). But it's still a good example of a real-life scenario where an order-preserving mapping is needed.

brazen jacinth
#

different structures with different properties are for different tasks, if preserved order is built-in at no extra cost, all i see is a plus

#

Java offers HashMap vs TreeMap vs LinkedHashMap for example - merely structures with different properties, some offer ordering, some allow null values, some offer sync support for multiple threads etc

oblique wyvern
#

Hi All,

I have an assignment and I am stuck

#

Could u guys help me out

fallen slateBOT
#

Hey @oblique wyvern!

It looks like you tried to attach file type(s) that we do not allow (.xlsx). We currently allow the following file types: .3gp, .3g2, .avi, .bmp, .gif, .h264, .jpg, .jpeg, .m4v, .mkv, .mov, .mp4, .mpeg, .mpg, .png, .tiff, .wmv, .svg, .psd, .ai, .aep, .xcf, .mp3, .wav, .ogg, .webm, .webp.

Feel free to ask in #community-meta if you think this is a mistake.

radiant fulcrum
#

@oblique wyvern Not the right channel, check the channel topic 🙂 also see #❓|how-to-get-help if you need help, however we cant help you with graded work as part of rule 5

oblique wyvern
#

@oblique wyvern Not the right channel, check the channel topic 🙂 also see #❓|how-to-get-help if you need help, however we cant help you with graded work as part of rule 5
@radiant fulcrum Sure

tawdry gulch
#

Does python do runtime optimizations for list slicing in for loops?
example:

for x in arr[1:]:
  print(x)

Would this be optimized, or would a new list be copied and gc'd right after the loop?
If so, what happens when this is a thing:

i = 1
for x in arr[1:]:
  print(x)
  arr[len(arr)-i] = "foo" 
  i += 1
#

I would assume that there is no optimization, but I can't know for sure

flat gazelle
#

There is absolutely no optimalization in the case of a name, as there is no guarantee it is a list

fallen slateBOT
#

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

dire forum
#

I'm trying to find the source code for os.symlink in order to understand what is going on under the hood, specifically on the Windows platform. I quickly went into this file: https://github.com/python/cpython/blob/master/Lib/os.py ... but this does not define a symlink function/method, which leads me to believe the definition is in some c extension or similar. Can anyone explain to me how to navigate the code base?

brazen jacinth
#

As it is platform specific code, it definitely has to in some way interact with the os on a low level, on linux for example very likely to directly interact with low level system calls like symlink, so i definitely imagine it's written in C

peak spoke
spark parcel
#

@peak spoke Maybe this is a better channel for discussing the import stuff

#

It seemed like you meant that the path maybe wasn't defined there. However, if we consider that we do something like this:

import os
print(os.path)

# The main part of the program goes here.

import sys
#

In this scenario, python will execute the entire program without knowing the path

#

If, on top of that, we put an import for something that requires the path in between, we're out of luck

#

Something like this:

import os
print(os.path)

import something_in_the_same_dir

import sys
peak spoke
#

What do you mean it doesn't know the path? sys.path is initialized internally before your script can take control

spark parcel
#

@peak spoke I thought you said that the path was initialized after stdlib imports and that fact meant that it imported time instead of the local time?

peak spoke
#

Did some testing locally and when ran directly time was not in sys.modules, to me it looks like it may be a side effect of how C modules that don't share the exact name are exposed to the interpreter (timemodule.c in this case) but I don't know enough about the internals to be sure there.

But anything that is used by the interpreter on initialzation (sys, marshal, some os specific stuff, importlib, anything from site in most cases etc.) won't ever be executed by you on imports because it'll be cached in sys.modules.
sys.path is populated with some base things as a part of the initialization process when the interpreter is executed before much else happens and then if it's run with site that does other things; this all happens before python gets to actually executing your script and its imports. Then those imports first look into sys.modules and use the module there, for the aforementioned packages they'll always be there in a normal environment so the actual import machinery doesn't execute. Then if I deducted correctly it may look into some of the renamed C modules like time, but didn't investigate much there, and if that neither of those find the module (and maybe something else) it goes through your sys.path to find the module with the name you imported which usually contains the directory of the file itself

dire forum
thick topaz
peak spoke
#

@teal yacht This pep and its discussion may interest you, it'll remove some unecessary modules that are no longer useful. In its current form, wave will remain (if the pep goes through) for the reason they gave in it

#

!pep 594

fallen slateBOT
#
**PEP 594 - Removing dead batteries from the standard library**
Status

Draft

Created

20-May-2019

Type

Standards Track

teal yacht
#

👍

#

and yeah i wasn't necessarily talking about wav, that's just the first i remembered from that section, i was more thinking about the sun au format or like colorsys

peak spoke
#

In the end those modules don't affect the user in almost any way beyond the stdlib list being a bit messy

paper echo
#

and add maintenance burden to the python core devs

peak spoke
#

Haven't looked at other modules, but the last commit to wave specifically was a typo fix more than half a year ago, so not a huge burden there

paper echo
#

plus some of them are outright redundant or obsolete or both

#

wave isn't on the removal list

peak spoke
#

(The first message was as a response in #python-discussion for why wave (and others) is in the stdlib so looked at that)

#

Some of those definitely are redundant at this point, but there was quite a bit of discussion in the mailing list for keeping some of the modules that are currently proposed to be removed in the PEP

paper echo
#

ah, yeah

teal yacht
#

(here's the image I posted, wav is highlighted because I used control-f, I was referring to the entire section, not wav specifically, and in fact most of these modules are proposed to be removed in that exact pep)

#

all except wav and colorsys are in the pep

torpid narwhal
#

It makes sense.

subtle whale
#

Hello. I wanted some help understanding cython. I want to make my code run faster and cython is the recommended way to go. However, I can't seem to find any suitable tutorials for it. And I don't see any tutorials that show how we can deal with dictionaries, lists, tuples and numpy in cython

teal yacht
pearl river
grave jolt
#

What pros and cons do ORMs have? I have never tried using them, and the idea of it seems a bit weird architecturally to me.

paper echo
#

it allows you to abstract over rows in your database by referring to entities/objects instead of doing database queries everywhere

#

really full-featured ORMs like django actually set up and manage database tables for you

#

sqlalchemy is a little more flexible, it can do things like generate classes based on an existing database

#

it can also abstract over specific quirks in your chosen rdbms and avoid writing raw sql, but that's arguably a downside and not a benefit depending on your attitude and needs

magic python
#

i've managed to avoid sql for so long and now i'm scared to try, ignorance is bliss, maybe

paper echo
#

its a big topic but its not that bad

#

the hardest part is learning about the different kinds of joins, and muddling through some of the terminology

somber halo
#

it's one of those must have skills for almost any kind of technical role

paper echo
#

that too

#

especially since you're a data guy @magic python

#

i use sqlite for ad-hoc data stuff all the time

#

and ive used postgres for some pretty big data storage/processing

somber halo
#

Postgres is ❤️

magic python
#

@paper echo yea, it's bad. All I ever need is select * from blah then I'm in pandas... Data isn't large (survey), but it's negligence not too have spent time with it.

paper echo
#

if you can do select and join you're not doing bad

peak spoke
#

I've been tracking some big parse trees from bs4 that weren't being collected by the gc (Looks like it's because of bs4's design if I didn't miss anything) and found out that a manual call to gc.collect removes them right away. How does gc itself work with the automatic collections? Thought that things like that would be caught by it

spark magnet
#

@peak spoke gc is for collecting cyclic structures (A refers to B, which refers to A, but nothing else refers to either of them)

peak spoke
#

Yep, but as I understood it it runs automatically in the background, why is a manual call to collect necessary?

spark magnet
#

it runs periodically

peak spoke
#

In that case, is collect more thorough than the periodic checks?

spark magnet
#

it's not more thorough, but it's happening sooner.

peak spoke
#

I let the app sit for a few minutes, with nothing happening; then the manual call immediately cleared it up

spark magnet
#

it's not time-based, it's based on how many allocations and deallocations have happened.

peak spoke
#

It's an async app so it is doing some things in the background during that time, if I don't figure out how to prevent the reference cycles (they're inherent to the lib for example) would I just be stuck with calling it manually or is there a better alternative

spark magnet
#

@peak spoke first, do you have to do anything?

peak spoke
#

Yes, it's leaving up to 50 MB uncollected for each object

spark magnet
#

but what is the actual problem? What bad thing happens?

peak spoke
#

Well, it can lead to running out of memory if left alone

spark magnet
#

but the gc should kick in if left alone.

peak spoke
#

Doesn't seem to want to do that

#

Well, I'll see how it goes; the project is local so I'll be able to deal with it manually when it starts becoming an issue

#

Is there some kind of document I could read into for how gc works internally or would the source code be the best place for that?

pseudo cradle
#

Context? Which gc are we talking about? Pythons?

teal yacht
#

yes

#

and its module gc

spark magnet
#

@peak spoke the gc page in the docs has some details.

rugged trellis
#

whats better to start coding? powershell or python?

torpid narwhal
#

Depends on the task.

solar delta
#

python for sure

torpid narwhal
#

But, Python has a much larger reach.

solar delta
#

powershell will be too much investment for the stuff you will learn

#

i mean.. you would never architect object oriented stuff in powershel

teal yacht
#

You actually would

#

powershell was designed to be an OOP alternative to other shells

#

It's just a shell script language, so you would typically not write as big programs as you would in python or some other general purpose PL

narrow kettle
#

so you would typically not write as big programs
corporations: "LALALLALALAL i cant hear you -_-"

split chasm
#

large begrudgingly open source projects as well, I've seen some doozies

tardy geode
#

What are the hardest python lines of code you can think of?

cloud crypt
#

@tardy geode what do you mean?

tardy geode
#

I mean code is code, some is simple and some is hard.. so what's the hardest code block you can think of right now?

grave jolt
radiant fulcrum
#
Results, Rounds: 1000
json        |  DUMPS: 0.0042ms, LOADS: 0.0038ms
ujson       |  DUMPS: 0.0014ms, LOADS: 0.0012ms
orjson      |  DUMPS: 0.0009ms, LOADS: 0.0012ms
hyperjson   |  DUMPS: 0.0022ms, LOADS: 0.0029ms```
brazen jacinth
#

hard to... read-write, understand..?

radiant fulcrum
#

Interesting to see ujson's serialization is quicker than its deserialization while all the others are the other way round

grave jolt
#

What about BSON?

pseudo cradle
#

What's that? Binary json?

grave jolt
#

kind of

#

format that mongodb uses

#

but it's not really json

radiant fulcrum
#

Binary Json pretty much

#

BSON is quite awkward for anything other than Mongo tho

pseudo cradle
#

Sounds like it

#

There's nothing more obnoxious than dealing with a binary file you don't have a parser for

#

(I'm not saying it's the case here, I just meant in general)

paper echo
#

msgpack 🙂

pseudo cradle
#

It's so stupid, it's taking weeks of everyone's time at work to parse this stupid 12 year old binary file

#

Maybe not weeks, but honestly it might take a full week for the stupid thing and it's such a small part of the overall project

#

But I'm getting offtopic