#internals-and-peps

1 messages · Page 42 of 1

rich wharf
#
if (match: re.Match := EXPR):
  ...
unkempt rock
#

That makes so much more sense

flat gazelle
#

The type of the loop variable is known from the type of Iterable

rich wharf
#

true

flat gazelle
#

For assignment expressions, it does kind of make sense though

rich wharf
#

yeah.

#

also I will always suggest better lambdas

#
x = (y, z) => y + z
f = (a, b, c) => (
  if a or b:
    print(c)
)```
#

even though they're unlikely

slim island
#

The only argument I see against them is that there's nowhere where they're necessary - but if normal lambdas exist, we may as well get not-shit ones

rich wharf
#

There are a few use cases, although very uncommon

#

One use case is as an alternative to decorators when you need multiple functions

#

A lot of times you'll need to make a common class or use multiple decorators just to listen to events, but these lambdas can make that easier.

#

Also for one of my use cases, when it's not convenient to make a single function to call another function with (for me, I have lots of these integrated functions where if I used actual functions it would be hundreds of blocks away), these lambdas would make my code easier to read

#

Right now I'm using a simple module I made called lambdatools to help make these lambdas somewhat more readable, but this syntax would help me personally a lot

#

Also I think my proposed syntax still keeps the "essence" of Python, it still feels mostly clean and good code.

deft pagoda
#

i like the generator syntax for lambdas

#
f = (x + y for x, y)

or maybe with from

f = (x + y from x, y)
rich wharf
#

@deft pagoda why not just use x + y

#

why do you need the for and from?

deft pagoda
#

because it would be a function

#

f(x, y)

rich wharf
#

oh

#

why isn't lambda x, y: x + y good for you

#

or my syntax, (x, y) => x + y

deft pagoda
#

it's fine for me, i just like the generator syntax

rich wharf
#

alright

#

so would f be a generator?

deft pagoda
#

no it would be a function

#

it would use the syntax that generators use, but to define a lambda instead

rich wharf
#

I don't really like the syntax since it doesn't really "indicate" it would be a function

deft pagoda
#

it indicates it fine --- (do something with variables --- from --- these variables)

rich wharf
#

yeah but it's reverse the order of normal python functions

deft pagoda
#

similar to how generator expressions have the do something at the front of the expression

rich wharf
#

it's normally args -> body not body -> args

deft pagoda
#

think generator expressions here

rich wharf
#

I don't really like the syntax, it just comes across as odd to me

deft pagoda
#

(x + y for x, y in zip(xs, ys))

rich wharf
#

The function takes in the arguments and outputs the result, not the other way around

#

Also that syntax is very close to generators, so it might confuse python users who are new

deft pagoda
#

it's supposed to be close to generators

#

that's the entire point

rich wharf
#

and that could be a problem

deft pagoda
#

i mean anything could be a problem

rich wharf
#

because it could confuse people that it's a generator expression

#

and it's also different from function order

#

so I see your point, I'm just saying why I wouldn't like it

deft pagoda
#

i don't know what that means -- different from function order

rich wharf
#

instead of the args first, it's the return value first

#

which is different from def

#

def name(... args ...): body

#

body for ... args ...

deft pagoda
#

it's suppose to be different than def

rich wharf
#

and that's why I don't like it

deft pagoda
#

ok

rich wharf
#

you're supposed to make the two concepts seem related and connected, not separate

#

maybe this is just my opinion, but those are my thoughts on it

deft pagoda
#

you hate list comprehension because the append is in the front and not at the end?

rich wharf
#

no?

deft pagoda
#

but you hate the syntax for functions when the function def is in the front and not at the end?

rich wharf
#

list comprehension requires it being at the front so that the end can have the if extension

#

and that separates the body from the iterable and condition quite nicely

deft pagoda
#

[for x, y in iterable x + y if x] could've worked

#

it's uglier, but it's not impossible to parse

rich wharf
#

and i prefer [x + y for x, y in iterable if x]

#

it separates the main return from the conditions and iterations

deft pagoda
#

(x + y for x, y) is just a continuation of that grammar

rich wharf
#

true, I just don't like it

#

it doesn't feel like a function, it resembles more of a generator or list comprehension

#

i'd probably constantly mistaken it for a generator

deft pagoda
#

to each their own

rich wharf
#

it's essentially an incomplete generator clause

#

and for is the keyword used for iteration, not for functional programming

#

so generally it would have a lot of confusion

deft pagoda
#

you could use from instead

rich wharf
#

and to me, I just personally don't like the syntax

#

from indicates a generator, not a function

deft pagoda
#

(x + y from x, y)

#

it indicates whatever you specify it to indicate

#

in the grammar

rich wharf
#

well in current python, from is used for generators

inland acorn
#

maybe (x, y to x + y), just putting out ideas xD

rich wharf
#

and using it for functions too would seem confusing

deft pagoda
#

also for imports

#

are imports generators

rich wharf
#

well I guess to me, it's just a general dislike of the syntax

#

it doesn't feel like a function

inland acorn
#

I could say the same about lambdas xD

rich wharf
#

it doesn't seem like nice syntax to me

#

I don't like regular lambda syntax either

deft pagoda
#

lambda syntax is awful

rich wharf
#

but lambdas use the same order as def

#

this is my lambda syntax idea

x = (y, z) => y + z
f = (a, b, c) => (
  if a or b:
    print(c)
)```
#

it's clean, also similar to other languages, and it clearly indicates a function

#

the arguments first, just like what you call with, and the body next

deft pagoda
#

the order isn't that important really

rich wharf
#

it's a nice touch that I prefer

deft pagoda
#

i just don't know why you're assigning to a tuple and then doing something else

inland acorn
#

maybe even some fanzy strange stuff like <x + y> were it would detect that x and y are the paramaters, but I think I would hate that xD

rich wharf
#

that isn't a tuple, that's an argument pair

#

and it would be ambiguous grammar otherwise

deft pagoda
#

you could do something like that, and detect all missing names as variables --- but error messages would not be easy to write

rich wharf
#

yeah, <x + y> would not be my preference

deft pagoda
#

i don't like the arrows

#

looks like rust

rich wharf
#

that's preference, but I think they're fine, and we could use -> too

inland acorn
#

I am just thowing out my ideas, they are rearly good xD

deft pagoda
#

i've done that name detection stuff in meta classes

rich wharf
#

=> is used in JS, -> is used in Java, so it would help people in those languages get a quicker switch to Python, and also it indicates what you're trying to do well

deft pagoda
#

python shouldn't look like js or java

rich wharf
#

it takes in the arguments, then it goes to the body, where the -> is pointing, and evaluates and returns it

#

x = 5 i mean this is valid javascript too

gray mirage
#

Python doesn't really have anything that looks like that, it'd be super out of place

rich wharf
#

we do have x := 5

gray mirage
#

And I say that as a big fan of Kotlin, which uses it in a bunch of places

rich wharf
#

(x) -> 5 isn't too different

#

I don't think it's too out of python

#

and whether -> or =>, I prefer it over the current lambda syntax

gray mirage
#

The issue is that all of python's recent operators, aside from @, are easy to understand because they're based on other operators

inland acorn
#

why dont we just remove lambdas all together and use functions like functools.partial and stuff from operator

gray mirage
#

:= is an assignment still

#

But - and > or = and >, well, those are all mathematical operators

deft pagoda
#

if they made partial a builtin

rich wharf
#

i think we could use => then

gray mirage
#

You could argue that a lambda is a mathematical construct, but python isn't lisp

rich wharf
#

= is assignment, and => takes those variables which it assigns from the parameters, and evaluates the body that > points to

deft pagoda
#

-> should be saved for implication

gray mirage
#

I expect most beginners are just going to think it's an alternative >=

deft pagoda
#

you know, x or not y == x -> y

rich wharf
#

I don't think it will be treated as such

#

@deft pagoda I don't like that syntax at all

#

x or not y is just fine

deft pagoda
#

that's normal syntax of logic

#

it already exists

rich wharf
#

in Python?

deft pagoda
#

in reality

rich wharf
#

reality isn't syntax

gray mirage
#

Where does this whole thing stem from?

#

We do already have lambdas after all

rich wharf
#

my proposal for lambdas

deft pagoda
#
In [82]: %tt p -> q, p or q                                                                                                         
┌───┬───┬────────┬─────────┐
│ p │ q │ p -> q │  p or q │
├───┼───┼────────┼─────────┤
│ F │ F │   T    │    F    │
│ F │ T │   T    │    T    │
│ T │ F │   F    │    T    │
│ T │ T │   T    │    T    │
└───┴───┴────────┴─────────┘
rich wharf
#
x = (y, z) => y + z
f = (a, b, c) => (
  if a or b:
    print(c)
)```
gray mirage
#

But then what do you do with the lambda keyword?

#

You can't remove it

#

And there shouldn't be two ways to do the same thing

inland acorn
#

I dont like the lambda syntax, but I cant think of any other syntax I might like either ¯_(ツ)_/¯

rich wharf
#

Why can't we remove it in a future major python release?

deft pagoda
#

that's the worst koan of the zen to be fair

gray mirage
#

I don't think it's a bad statement

deft pagoda
#

there's multiple ways to do nearly everything

rich wharf
#

We can always remove lambda in a future major release and add ->

gray mirage
#

Also, the breaking changes in 3.x were never that drastic

inland acorn
#

I kinda like my idea of <x + y> but there would need to be well defined rules for it

deft pagoda
#

i don't like angle brackets much

gray mirage
#

I think a lot of this comes down to the fact that a lot of people abuse lambdas in the first place

inland acorn
#

like the arguments are the the undefined names from left to right

gray mirage
#

Lambdas are supposed to be single statement functions defined inline and never directly stored to a variable

#

If you follow that guideline then they're actually kind of not very useful

inland acorn
#

or maybe even something like this? <$0 + $1>

rich wharf
#

My syntax can help with this

deft pagoda
#

they're useful for all sorts of callbacks

gray mirage
#

So I don't really see why there's much point in expending a huge amount of effort on an alternative syntax

rich wharf
#

It gives lambdas as much power as regular functions without ruining readability

deft pagoda
#

though you could argue that the callback pattern should die

rich wharf
#

gdude, because I think it would lead to less lambda abuse

#

Lambdas would be easy to convert with this syntax

gray mirage
#

It probably should to be fair, yelling

rich wharf
#

lambda ARGS: EXPR can be converted to ARGS => EXPR

#

and it also allows people to use more powerful lambdas when needed

#

which I use all over one of my scripts

inland acorn
#

I am still sticking with my <x + y>

rich wharf
#

<x + y> makes a large amount of assumptions

deft pagoda
#

i think we should each get our own syntax

inland acorn
#

no

rich wharf
#

You'd have to check just for new variables

inland acorn
#

I think it is fine!

rich wharf
#

And that could lead to massive confusion and slow down your code

peak spoke
#

Can't get rid of callbacks with python wrappers like pyside2 that don't have many python alternatives and arguably all are worse for the job qt does

gray mirage
#

Lambdas are something that are useful in a very specific set of circumstances, and I think it would be better to discourage their use otherwise

rich wharf
#

I don't, because <x + y> means you have to check if x and y don't exist

#

It's different depending on where you place it in the code, and it has to check for variables in scope

gray mirage
#

Also using angle brackets like that just looks like a typedef in static langs

rich wharf
#

And I disagree, gdude. Lambdas have other uses that should be encouraged in Python and a readable way to use lambdas will reduce abuse.

deft pagoda
#

i remember something guido wrote about angle brackets being difficult to parse with the old parser

gray mirage
#

I agree that arrows would be the least disruptive and best looking change

#

But I don't think we need that change

rich wharf
#

I think it would be a useful change

gray mirage
#

And I don't see how making lambdas more attractive means they'll be abused less

#

If anything, they'll be abused more

deft pagoda
#

i think everything should be made into generator syntax so that it's human readable

rich wharf
#

gdude, at least we'll have more readable lambdas

inland acorn
#

like we could have: py sorted(some_list, key=<item.upper()>)actually, scrap that. here you should just do: py sorted(some_list, key=str.upper)

rich wharf
#

a lot of people use lambdas in clever ways for custom code

gray mirage
#

Lambdas are already readable

rich wharf
#

not when people use them for statements

#

people do clever ways that are not very readable for statements

#

and by this way, maybe it will not reduce abuse, but it'll make lambdas, and code readable

deft pagoda
#

you can always not use a lambda, so it's not that big a deal

gray mirage
#

Then maybe they shouldn't be using a lambds?

rich wharf
#

besides, in my case, it would actually make my code MORE readable

#

because I actually require lambdas with statements in one of my pieces of code

gray mirage
#

So this is just about your specific application?

rich wharf
#

It's also about general convenience

#

And it's a easy switch for converters

#

It's also helpful in the case of multiple event handlers

#

Decorators can only register one event handler, but this could register multiple possibly

gray mirage
#

Lambdas arguably aren't broken in this way, and I feel like you're abusing them if this is causing problems for you

rich wharf
#

I am abusing them since there's no other way to easily do what I want

#

If I separated all of my callbacks into separate defs, I'd have to scroll up hundreds of lines to edit the functions

#

And it would be very difficult to manage my code in this way

gray mirage
#

Well you can ctrl-click but that's besides the point

#

Without too much information available, it sounds like what you want is probably macros

rich wharf
#

All I want is a way to execute statements in lambdas

slim island
#

IMO lambdas for callbacks are perfectly readable - and moreso in some cases than a full function, you can be sure that any given lambda is used in only one place

rich wharf
#

So, this is my syntax

x = (y, z) => y + z
f = (a, b, c) => (
  if a or b:
    print(c)
)```
gray mirage
#

I don't think there's a usability case here

rich wharf
#

I doubt it will ever be added

#

But I think it would be a major improvement to Python

#

And maybe, but I personally would really like the addition of these lambdas

gray mirage
#

Again, this really seems like it'd be better suited to something like a macro system

slim island
#

I think it would be a minor improvement, but one that I'd personally like

gray mirage
#

And I have good news - a macro system exists

inland acorn
#

@rich wharf if you really want it, go write a pep for it 😄

rich wharf
#

regular users can write PEPs?

gray mirage
#

Well bring it up on the mailing list first

#

Yeah it's just a pull request

rich wharf
#

Probably not until some sort of python 4 is in the works

slim island
#

I imagine this is something that has come up before and been no'd

rich wharf
#

yeah, but I think my syntax is very readable

slim island
#

it's the same syntax as JS, not really your syntax

rich wharf
#

that's besides the point

#

the syntax is very readable

#

and is easy to switch from regular lambdas

#

converters could easily change lambda x, y: ... to (x, y) -> ...

deft pagoda
#

erase the parens and it would look better

gray mirage
#

That'd be quite hard to parse

rich wharf
#

it's easier this

deft pagoda
#

we got PEG now

rich wharf
#

(x, y) -> ...

#

or this

#

(x, y -> ...)

slim island
#

that second one is terrible

gray mirage
#

I wonder how far you could abuse tuples with like the matmul operator

rich wharf
#

agreed charlie

gray mirage
#

Also, why this instead of (x, y): ...

#

That'd be more like actual python

rich wharf
#

that might be fine for regular expressions but it would be word for

#
(x, y): (
  ...
)
#

I think => is just nicer

#

and it's also closer to what java and javascript users already use, so switching is a bit easier

gray mirage
#

I mean you're also basically introducing braces here

#

Which is a big no

#

You're just using parens instead

true ridge
#

are we discussing adding extended lambdas, again?

gray mirage
#

Hahaha

rich wharf
#

yes

deft pagoda
#

(callback(dt) from dt)

gray mirage
#

Yes, for the 29484936293764th time

rich wharf
#

and even then, it doesn't add new syntax and it still seems good

#

( ... ) uses parentheses, which already exist, and inside of them you can still use colons

gray mirage
#

We never use parens for statements though

deft pagoda
#

i don't care about extended lambdas, i just like the gen syntax for them - but i'm also not invested

swift imp
#

what is => used for?

gray mirage
#

It's not

swift imp
#

Oh

rich wharf
#

=> isn't in actual python

#

it's a concept for better lambdas

swift imp
#

Thats what I thought

rich wharf
#

and (x, y) => x + y is a lambda

#

or an idea for it

swift imp
#

I like lambda keyword

inland acorn
#

I still think my teribble idea is best

rich wharf
#

I don't

#

You can't do statements in it without plenty of magic

deft pagoda
#

i like magic

rich wharf
#
(x, y) => (
  if x:
    print(y)
)
#

This seems nice to me

inland acorn
#

well if you needs statements, then maybe you dont want a lambda?

rich wharf
#

not always

gray mirage
#

You can't make a multiline lambda right now, and if your answer is braces (even in the form of parens) then you're gonna get nowhere

slim island
#

The brackets there are pointless

swift imp
#

Yeah, if you need that much that make a real function.

rich wharf
#

actually not always

#

if I did that, my functions would be 300 lines away from their single usage

deft pagoda
#

boo to statements in lambdas

void sonnet
#

nested functions exist...

gray mirage
#

This just isn't that useful

inland acorn
#
lambda x, y: print(y) if x else None```
deft pagoda
#

i've done things like that before

rich wharf
#

the example I sent was a simplified example

true ridge
#
(x, y) => (
  if x:
    print(y)
)

@rich wharf this would be an ambiguous grammar for LL(1) parsers

inland acorn
#

give something more complex, I will make it a normall lambda xD

rich wharf
#

a lot of times I'm using while loops or 2/3 indents at most

deft pagoda
#

pff, LL(1) is so last year

inland acorn
#

you can do while loops in lambdas (you should not, but you can)

rich wharf
#

not in a convenient way

gray mirage
#

Cpython is not the only parser for python to be fair

rich wharf
#

and not in a very readable way

inland acorn
#

True

#

but if you need a while loop, then you dont need a lambda, you need a normal function

swift imp
#

I wish python would implement a type checking system that utilizes annotations, something that is completely optional

inland acorn
#

mypy?

gray mirage
#

It's called MyPy

swift imp
#

No not a static checker

rich wharf
#

one that adds ones?

gray mirage
#

I'm not sure what you mean then

rich wharf
#
lt.function('frame, exprs', lambda v: (
    v.set(seq = range(v.exprs[1])) if isinstance(v.exprs[1], int) else v.set(seq = v.exprs[1]),
    (yield from lt.foreach('i', v.seq, lambda v: (
        v.frame.set(v.exprs[0].value, v.i),
        (yield from v.frame.execute(v.exprs[2]))
    )))
))

@inland acorn

gray mirage
#

MyPy does runtime checking doesn't it?

rich wharf
#

no, it does it statically I think

gray mirage
#

I'm pretty sure it can do it at runtime too

#

I know running an app with it is considerably slower

swift imp
#

its static

true ridge
rich wharf
#

or in my syntax

(frame, exprs) => (
  if isinstance(exprs[1], int):
    seq = range(v.exprs[1])
  else:
    seq = v.exprs[1]
  for i in seq:
    frame.set(exprs[0].value, i)
    yield from frame.execute(exprs[2])
)
#

there, vivax, you can make that into a lambda if you want

deft pagoda
#

i don't really like typing --- but it would be great if cython could just use type hints though

gray mirage
#

That should be a function

true ridge
#

cython can use type hints

gray mirage
#

No bones about it

rich wharf
#

this as a function? hmm let me check

deft pagoda
#

it can?

rich wharf
#

that's over 200 lines away from the list

deft pagoda
#

can i use type hints instead of cdefs

rich wharf
#

where it's stored

gray mirage
#

Ctrl+click

#

Use your editor's features

#

That's why they're there

rich wharf
#

I personally like it all in one space over putting it in a function

#

instead of having to switch to two spots

gray mirage
#

Why do you insist on writing smelly code

rich wharf
#

because it's all in one place and easy to edit

void sonnet
#

is that the only place it is called?

rich wharf
#

yep

#

the only place it's needed to be called in that file

gray mirage
#

That doesn't mean you can't extract it to a function, even in another file

rich wharf
#

extracting it to a function still makes it 200 lines apart

#

and then I'd have to switch files just to edit it

gray mirage
#

Are you editing in notepad?

rich wharf
#

nope

peak spoke
#

how often do you change them all?

rich wharf
#

using sublime text

#

and a few times

gray mirage
#

Surely sublime can jump to definition or give you a quick symbol search

rich wharf
#

probably, but I prefer it all in one place where I can edit it

void sonnet
#

i mean, if it doesn't ever get called elsewhere, nest the function right above where you use it. problem? not no more...

rich wharf
#

I use it in a gigantic indented list

#

well not a list but an object

deft pagoda
#

wtf

true ridge
#

just use a single file

rich wharf
#

I already am

true ridge
#

what's the problem than?

rich wharf
#

there isn't a problem, I'm just proposing better lambda syntax for me

#

that would make some of the code where I can't use functions in this way without having to scroll up less convenient

#

having the lambdas all in one place like this is more convenient

#

and this conversation is going away from my suggestion to "my code is bad" which I've had this discussion before

#

and I don't need to go over all of the context for this, so I'll just say my case is niche where I sort of need to use lambdas for this otherwise very inconvenient

deft pagoda
#

i was happy to just imply it without saying it

void sonnet
#

wasn't my intent, personally. just trying to offer a possible solution. do you... 😄

rich wharf
#

it's not necessarily in a function

gray mirage
#

I mean, I don't think the answer to your problem is "invent a new syntax"

rich wharf
#

so I'm not sure how I'd nest it above where I use it

#

my problem is already solved, I'm just giving an idea for how I'd make it look better

gray mirage
#

The answer is more likely to be "use the established solutions"

rich wharf
#

the two options are use cleaner defs that are hundreds of lines away and not integrated with my code

#

which is the "established solution" that I'm not fine with

gray mirage
#

Or nest it just above

rich wharf
#

or to just use a lambda and abuse it

#

how would I nest it above

gray mirage
#

You know you can define a function inside another function right?

rich wharf
#

this variable is top-level

gray mirage
#

Then define it on the line before?

rich wharf
#

that's about 200 lines above actually

#

because it's a long variable definition

gray mirage
#

Are you trying to tell me what you have here is a single list that is 200 lines long?

true ridge
#

nice

rich wharf
#

it's not a list, it's a categorized object

inland acorn
#

@rich wharf if I am not wrong, here is your lambda: py lambda frame, exprs: (yield from ( frame.set(exprs[0].value, i), frame.execute(exprs[2]) )[1] for i in (range(v.exprs[1]) if isinstance(exprs[1], int) else v.exprs[1]))

rich wharf
#

you're wrong, you're only yielding from one part of it

#

you only yield from frame.execute

#

@gray mirage so you're close, but yes it is quite long

inland acorn
#

you only yield form there as well?

gray mirage
#

I fail to see what the difference is here

true ridge
#

frame, exprs = get_frame_and_exprs()

#

is this what you need

#

just define a single use function to get all

rich wharf
#

it's basically a long JSON object

#

except it has function callbacks

gray mirage
#

And you decided to define it all in a single statement instead of constructing it in parts?

rich wharf
#

but explaining the context would take a while

#

it's a bit more complicated so I don't think I can simplify it down enough for the convo

inland acorn
#

I am pretty sure what I have is corret, but I cant be sure xD ¯_(ツ)_/¯

rich wharf
#

it's more like

#
lambda frame, exprs: (
  seq := range(exprs[1]) if isinstance(exprs[1], int) else range(exprs[1]),
  (
    frame.set(exprs[0].value, i),
    ( yield from frame.execute(exprs[2]) )
  ) for i in v.seq
)
inland acorn
#

that is not valid syntax just looked werid at fist glance, what I gave is correct for what you gave me I am pretty sure.

rich wharf
#

yes it is

unkempt rock
#

does all the ifs have to be in the same scope as the other ifs?

rich wharf
#

anyways I'm done here, see you

inland acorn
#

okay, what you have is wrong anway since you are setting seq in the loop, and your yield would not work from there ¯_(ツ)_/¯

rich wharf
#

alright

#

well I have to go now, see you!

inland acorn
#

see you 😄

#

actually, yield is not valid in generator expressions, idk were I got that from :/

#

well anyway I need to go now

chilly radish
#

can somebody tell me if you can use ternary with yield. something like this py yield(k) if y else yield(k,v)

oblique crystal
#

Why not
yield k if y else k, v
?

#

Also I think it's better for help channels no?

swift imp
#

Why would you ever want to write a multiline lambda like that?

#

Like what benefit is that over a regular function?

gray mirage
#

I can't think of a good reason that isn't "I don't want to redesign my codebase"

#

Which is a valid reason if you don't have time to do that

#

But then you arguably don't have weeks to spend trying to convince a channel that your new lambda syntax is useful either haha

tawdry gulch
#

I mean it’s pretty trivial to convert lambda to proper function

#

And like, they have the same functionality

#

If you need it anony just define something at module level scope and use it from there

ivory pike
#

I am trying to use multiple files to make my script more modular but I am running into an issue. I do import middle_room at the start of my script and then call a function from that file later on. However, when I call it, I get the error that the function isn't defined. Middle_room is in the same location as my main python script.

#

Do I have to do the "from file import a b c d e" aspect if I want to import every function in the script?

digital briar
#

Are you calling it like this?

import middle_room
middle_room.close_door()
ivory pike
#

No, I was just doing close_door()

#

let me try that.

#

That fixed it. Thank you!

north root
#

hey there, just to let you know for next time, this channel is for discussion about python itself, not for help. if you need help, you can claim a help channel. see #❓|how-to-get-help

ivory pike
#

Roger, thank you. Will do next time

north root
#

thanks lemon_pleased

cinder basin
#

pls beg

#

i se

twin jacinth
#

i know basics of python

#

what should i learn next may I Ask

#

pls tag!

ivory pike
#

@twin jacinth What I do is find something I want done in a game I am playing. For instance, I made a program that took inputs from the user to determine what the best bang for you buck was on a selection of item upgrades in a game I play. Now I am making a MUD

twin jacinth
#

what is python best used for

#

like

#

when people get jobs

#

n stuff

#

what they build with python

ivory pike
#

Oh, I can't help you with that

twin jacinth
#

oof

#

theres a lot

#

it scares me to get started 😦

willow shore
#

CRUD, ETL.. REST

desert rock
#

@ivory pike Ooh, I love MUDs a ton, was addicted playing them when I was younger. Do you have a blog or something I can follow?

#

Sorry just realized I got a bit off topic here lol

willow shore
#

Heh I made a similar thing earlier that took a list of items from user and calculated value per weight, per stack, and the coefficient between those two xD

ivory pike
#

@desert rock nope, lol. I just do it own thing. It's not going to be very good, I have 9 rooms planned so far. Sorry :(

willow shore
#

first game I wrote was a text game about hacking, kinda like uplink but text ^^

desert rock
#

Lol whether its good or not doesn't matter, what matters is just getting it done lol
Either way that's a pretty cool project you're working on, def would love to try out the finished project

ivory pike
#

I'm space-chickun on github. I'll post it there when I'm done

#

Thanks for the encouragement!

desert rock
#

Followed!

hearty trench
#

"SQLite DateTime type only accepts Python datetime and date objects as input."

#

someone know how i can put datetime.now in my sqlite database

#

i did this

covert rain
#

x ** 2 is something you use in listcomps, not lambdas

unkempt rock
#

i mean i've used it many times in lambdas

covert rain
#

in your example-only code?

#

or real code

unkempt rock
#

no for eg: pyqt connections using lambdas

#

real code

covert rain
#

you use lambda x: x**2 in a pyqt connection?

#

😮

unkempt rock
#

it's not practical to do that for generated connections

covert rain
#

yeah, in this case you have to use lambdas to be readable. But as a shortcoming of pyqt itself

unkempt rock
#

so sometimes lambdas are needed

covert rain
#

pyqt's api is not pythonic at all - it is a thin wrapper around the C++ of QT and that shows

#

it shouldn't be an example of what we should do to be readable

unkempt rock
#

well that's true, but when presented with option like that it's better to use lambdas instead of hunting for a builtin

#

if one finds a builtin then that's great, most often there is none

loud igloo
#

don't confuse stdlib with builtin

covert rain
#

maybe I'd hide it in a utility def function:

def connector(func, *args, **kwds):
    @functools.wraps(func)
    def _call(state):
        return func(*args, **kwds)
    return _call
button.clicked.connect(connector(self.button_pushed, idx))
unkempt rock
#

okay

peak spoke
#

might as well use a partial

covert rain
#

not if you don't want to pass state

unkempt rock
#

@covert rain that's how it used to be, but it was actually deemed less pythonic than more

#

there was a connect() function like that

peak spoke
#

but the lambdas are more consise while remaining readable for callbacks

unkempt rock
#

yes callbacks are also a wonderful example

covert rain
#

I agree - the shortcoming of pyqt's ugly api can be slightly reduced by using lambdas

#

pyqt should allow you to pass a parameter to the callback like everybody expects

unkempt rock
#

well it's unlikely lambdas will go away and nor should it, they serve the purpose of being throaways like _

covert rain
#

well, I'm also against using _ as a throwaway, but that's a separate discussion

unkempt rock
#

huh? why not...?

covert rain
#

_ is for gettext internationalization

#

when you add internationalization to the code, all uses of _ as throwaway become errors

deft pagoda
#

yeah, that's more an argument for internationalization to use a different function name

unkempt rock
#

i think you can change it though

covert rain
#

most utility scripts to extract the text from the code use _ as the trigger

forest bluff
#

Hello I have a quick regex question.

deft pagoda
#

this isn't the place for regex questions

covert rain
forest bluff
#

Ok

#

Sorry

deft pagoda
#

though i've used both versions of _ in my code before

#

as all the throwaways were local

covert rain
#

I use _ign

#

as a short for "ignore"

deft pagoda
#

i would not have known unless you said so

unkempt rock
#

well sure, mostly i'd say _ is known more as throwaway than as for gettext...atleast that's what i think

covert rain
#

yeah most scripts are single language so that doesn't become a problem until later

deft pagoda
#

sly parser has a @_ decorator

covert rain
#

and you can probably use a IDE refactor tool to change each affected scope when adding the internationalization to the code

#

but it is a bit boring

#

if you had to do it for a codebase (like I did) you would be more concerned when you use _ 😄

somber halo
#

I'm yet to use it directly in a day job but I can imagine quite a few instances where I could have used Cython in the past (notwithstanding some possible issues that might have arisen wrt deployment)

rigid hazel
#

im new to python, is it good if i start with using VS code or use python software straight away?

wide shuttle
#

That sounds like a question for #python-discussion, @rigid hazel. This channel is specifically meant to discuss Python the language itself, from a more abstract perspective. (A lot of people use VSCode for their Python programming.)

rigid hazel
#

ohh alright sorry,thx tho

unkempt rock
#

I want to point out developers who learn python as their first language generally do better at interviews unless they specifically ask for another language which you should consider beforehand

#

python is faster, the guy interviewing you thinks you're really smart or something when you're doing stuff very fast

mellow widget
#

^ what?

#

can you not make up things that beginners may take as fact please

somber halo
#

I've also found the comment a bit weird...

flat gazelle
#

ye, for most interview questions you just write a procedural algorithm to solve. Pretty much any language with lists can use the same code

raven ridge
#

There's some truth to it. Python usually takes less code to write the same algorithm than most other languages, so you can write it faster on a whiteboard.

flat gazelle
#

it is incredibly minor for example implementations of algos. And if you writing on a whiteboard, why not use pseudocode. Does not get any terser than pseudocode

slim island
#

hm - I think it makes some amount of sense, but it might just be that I'm more familiar with Python - stuff like list comps are what I naturally think of when solving simpler problems, and writing that code in another language does take a little bit longer

flat gazelle
#

ye, if you are familiar with a language more than another, you should use when possible. That is much more important than what language you choose. And almost no language will be better than another in every case for tersely describing algos.

willow shore
#

you'd be hard to find a language that doesn't have a library to support or emulate any* kind of data structure

#

but that's for algos and data structure, if it's about architecture or something higher level... psudocode is just a yet higher level representation 😛

#

like if I'm gonna show an algo involving 4x4 matrixes I'm not going to like build a python mat4 lib on a whiteboard just because you're not familiar with it as a built in type I'm going to just express a 4x4 matrix

mellow widget
#

isnt being asked about a matrix completely only relevant to specific fields? if im interviewing for a company asking for python backend developers for their web app then that question is completely irrelevant

#

would be good to know what questions are actually asked in interviews for companies that arent FAANG and companies outside of california lol

willow shore
#

sure, it's just an argument against conforming to python std for solving theoretical problems

mellow widget
#

i dont disagreeing with anyone here at all, i think its a good discussion

willow shore
#

honestly what I've had to do the most is to write code to send in or do live coding with screen share

#

and usually what I've been tasked to do is something along the lines of a user-story

mellow widget
#

yep, mine were mainly python knowledge, soft skills, system design etc

willow shore
#

it can be a bit annoying sometimes because there's a million ways to do it and you have no idea what to focus on and what they really value

#

normally getting that info is very difficult for some reason

slim island
#

Most big companies do something at least similar to those FAANG dsalg questions. Skyscanner for example, but I do think its mostly US corps leading the way with it

willow shore
#

guess it kinda depends on the sector, I try to work in entertainment or apps not so much like fintech

mellow widget
#

hmm, feel like theres no where near enough data and research on this for people to make an informed decision on what to be prepared for

somber halo
mellow widget
#

best thing to do? ask the company what the test entails

willow shore
#

it's very individual, you can tell a lot by the listing itself

dusky cairn
#

Should I use camel case for python variables? PyCharm keeps telling me to use _ instead. I, particularly, don't like underline.

worldly venture
#

@dusky cairn yeah, you should be using underscores

#

you don't have to

echo plume
worldly venture
#

but PEP8, the style guide for Python, says so

dusky cairn
#

Thanks.

#

I was "camel casing" everything.

#

ehheheh

echo plume
#

I was going to reference it instead 😅

boreal umbra
#

I find snake casing easier to read, but I might be biased.

#

Camel casing looks more like traditional code, I guess.

spice pecan
#

While I do prefer snake_case, I think PascalCase is fairly visually appealing, like they do in C#. camelCase, on the other hand... not a big fan, it feels out of place to me

grave jolt
#

There are also some options which aren't supported by mainstream languages.

#

Like 'spaces between words' or kebab-case

maiden cypress
#

Hi, does anyone have any experience using python arcade?
I am trying to make a pong game using python arcade and was troubled because first, I have no idea how to make the opponent move on its own, Second, my pong game(Without the opponent moving) doesn't work yet.
I would greatly appreciate it if someone could assist me

boreal umbra
#

@maiden cypress you can check out #❓|how-to-get-help if you have a specific question, or #game-development for more general questions. However specific questions are more likely to get answered.

maiden cypress
#

Thank you, I will make sure to check those channels.

boreal umbra
#

I don't know anything about game development, but I hope you can get it working 👍

maiden cypress
#

Thanks!

boreal umbra
#

Anyway, the impression I'm getting is that Python invented contect management. But is it actually a thing in other languages?

maiden cypress
#

honestly, idk. I'm pretty new to python

boreal umbra
#

Ah, that was a general question for this channel.

maiden cypress
#

oh, I see

rain timber
#

!e

import random


bird_ask = ["Bird: Pretty bird!", "\n\nBird: SCREAM!!!\n"]
response_human = ["\nHuman: What do you say?", "\nHuman: Nobody said that!\n"]
response_bird = ["\nBird: Hello!\n", "\nBird: SCREAM!!!\n"]
if random.choice(bird_ask) == bird_ask[0]:
    print("\n\n" + bird_ask[0])
    if random.choice(response_human) == response_human[0]:
        print(response_human[0])
        print(random.choice(response_bird))
    else:
        print(response_human[1])
else:
    print(bird_ask[1])
fallen slateBOT
#

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

rain timber
#

pfft

vale breach
#

where should I go after completing a basic python course ?

#

Should I jump into a project or look to learn something specific in python like data science?

gentle lodge
#

Olive Garden to celebrate

vale breach
#

haha

gentle lodge
#

honestly I don't know; it's all about what you enjoy and are good at

vale breach
#

should I just explore different areas of python

#

I guess trying projects would be the cheapest way to see what I really enjoy

#

Data and ML have always interested me but I’m a far ways away from that

gentle lodge
#

I'd go with what you're interested in, even if it's intimidating

#

there are surely courses in those things

vale breach
#

Yeah

#

I just want to make use of my time since I’m at home so much and this has been something I’ve wanted to do

#

Thanks for the advice

meager meadow
#
quoteNumFileLoc = (p / 'quoteNumFile.txt')
quoteNumFile = open(p / quoteNumFileLoc, 'w+')
quoteNumFileTxt = quoteNumFile.read()
quoteNumFileTxt = int(quoteNumFileTxt) + 1
quoteNumFileLoc.write_text(str(quoteNumFileTxt))
newQuoteNum = quoteNumFile.read()
quoteNum = newQuoteNum
quoteNumFile.close()``` can someone help me why this gives me an error
#

Traceback (most recent call last):
File "c:\users\brile\desktop\olddesktop\pythonstuff\projects\quotelibrary\quotelibrary.py", line 25, in <module>
quoteNumFileTxt = int(quoteNumFileTxt) + 1
ValueError: invalid literal for int() with base 10: ''

gritty skiff
#

the value stored in quoteNumFileTxt can't be cast to an integer

#

looks like it's an empty string

amber nexus
#

well 10x10 is 100

#

and not really the right channel for this

languid dagger
#

!warn @karmic grove Don't post random images

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied warning to @karmic grove.

potent heart
#

Hi team

#

Can you suggest the good sites for learning python on our own

#

I just wanna learn it.

#

Code academy is charging

deft pagoda
#

maybe ask in #python-discussion this channel is for specific discussion of the python language

potent heart
#

Sure, sir @deft pagoda

ruby spruce
#

I'd like to try contribute to Python, but I don't want to sign anything.

grizzled vigil
#

@ruby spruce Yeah, unfortunately the CLA is required for legal reasons. Without it, the PSF could easily get into lawsuits over the intellectual property of contributions.

ruby spruce
#

NodeJS have just that when you open PR, you automatically agree with terms.

viral flame
#

Hey .. can anyonee tell why python gobject (PyGObject) is used for ?

gray mirage
#

That library is used for interfacing with GTK

wide shuttle
#

NodeJS have just that when you open PR, you automatically agree with terms.
@ruby spruce

It's not an easy thing and, honestly, when you come to a license agreement, having an explicit "signing" stage sounds like the better option to me. You are entering into an agreement over licensing; I don't see signing something odd in that process. The status of "implicit consent when you do something" has been heavily debated on all kinds of legal matters and since copyright issues would be a major issue for Python/the PSF, I don't mind them doing it in this way.

undone hare
#

The PSF agreement is really easy to sign now, everything is virtual

#

The only downside is that you need to wait a day before the bot notice that you signed it

ruby spruce
#

I don't want to sign it. I have to find some language that don't require it

undone hare
#

I mean..

#

you keep the intellectual rights on your code

nova tiger
#

what is the psf agreement, in a nutshell?

undone hare
#

You just certify that you wrote it under a certain license

gray mirage
#

CLAs need an explicit signature to be a legal document, pretty sure

#

There are some very easy ways to do that using github's tools though

undone hare
#

I mean, i signed it, you don’t need an actual signature 😄

gray mirage
#

I actually help run a project with a CLA, we have users "sign" it with their GitHub account

undone hare
#

It is using adobe sign thing

gray mirage
#

If they don't, the PR can't be merged since the check doesn't pass

#

It's a decent middle ground because it's easy enough that it doesn't discourage contributors

undone hare
#

what is the psf agreement, in a nutshell?
@nova tiger in a nutshell, you agree that every piece of code you contribute to the PSF projects is licensed under a specific OSI license

ruby spruce
#

why this legal stuff have to be so difficult currently...

gray mirage
#

It's not that hard

#

But a big org with important projects needs to cover their asses

undone hare
#

I mean, it is just 3 fields to fill

ruby spruce
#

But these fields ask private data. Why have to be unable to make anonymous contributions.

gray mirage
#

Well a certification is useless if it isn't tied to a real person

undone hare
#

I’m pretty sure they state that this will stay private informations

gray mirage
#

It's a legal document, you are providing an enforceable guarantee in the form of a contract

#

That could never work anonymously

#

But I'd be surprised if they make the details public

#

GDPR is a thing

undone hare
#

The only thing taht is public is if a certain github username have signed it

ashen lance
#

Hi
I have a collection of list but while converting each item to a set, I am only getting first item as the result
lst2 = [[1, 3, 2, 5, 7, 9, 4, 6, 8], [4, 9, 8, 2, 6, 1, 3, 7, 5], [7, 5, 6, 3, 8, 4, 2, 1, 9], [6, 4, 3, 1, 5, 8, 7, 9, 2], [5, 2, 1, 7, 9, 3, 8, 4, 6], [9, 8, 7, 4, 2, 6, 5, 3, 1], [2, 1, 4, 9, 3, 5, 6, 8, 7], [3, 6, 5, 8, 1, 7, 9, 2, 4], [8, 7, 9, 6, 4, 2, 1, 3, 5]] for m in lst2: print(m)

#

Output is always {1, 2, 3, 4, 5, 6, 7, 8, 9}

flat gazelle
#

a set is unordered

ashen lance
#

yes but it means if I provide [4, 9, 8, 2, 6, 1, 3, 7, 5] as input, output should be {4, 9, 8, 2, 6, 1, 3, 7, 5}

flat gazelle
#
In [6]: {4, 9, 8, 2, 6, 1, 3, 7, 5}
Out[6]: {1, 2, 3, 4, 5, 6, 7, 8, 9}
```a set by definition may order its elements in whatever order it decides
ashen lance
#

Oh
got it, thanks, and set doesn't allows repetition right?

flat gazelle
#

ye, unique elements only in an undefined order

dusky cairn
#

I call a function inside a function.

def funcB()
  if conditionmet:
    return

def funcA()
  something
  funcB()
  foo
  bar

If the condition is met on funcB() while called by funcA(), will it exit the funcA() as well, preventing it to run foo and bar?

flat gazelle
#

no. return only exits the current function.

dusky cairn
#

Is it possible to make it otherwise?

flat gazelle
#

you can kind of do it with exceptions, but it is better to encode it in the function result

dusky cairn
#

Would you mind giving me an example, please?

flat gazelle
#
def fun_b():
    return 1 == 1
def fun_a():
    ...
    if fun_b():
        return
    foo()
```is the nicest way
dusky cairn
#

Thanks!

wide shuttle
#

These conversations would have been better suited for a help channel. The topic of this channel is mainly to discuss Python itself, from a more abstract and higher level perspective. For more general conversation related to Python, there's #python-discussion, and for help questions, there are help channels available in the Python Help: Available category (see #❓|how-to-get-help).

dusk viper
#

Do you thinks python will be the most learn languages?

forest compass
#

I just cant decide guys... I need to learn Java for my University but I want to start directly with Python.. Do you think I should just start with Python instead of Java and make it later?

clear hornet
#

Learn what you need to succeed

#

plenty of time to learn other things later

#

you got a lifetime of learning ahead

forest compass
#

Thank you! Then I gotta with Java first and then Python 😄

#

Python will be like in 4. Semester

slim island
#

I just cant decide guys... I need to learn Java for my University but I want to start directly with Python.. Do you think I should just start with Python instead of Java and make it later?
This is not the right channel at all. But you can learn the two in tandem fairly easily - time spent with python won't be wasted with Java, and time spent with Java won't be wasted with Python - they share a lot of concepts, and seeing different ways of doing things will probably be good for your fundamental understanding

forest compass
#

Thank you and im sorry, I thought "Language" would do it more 😅

clear hornet
#

in the end it is about the work load. Set priorities, if you need Java now, learn it now, as you said. Py is going to be done later

#

if you can do both at the same time.. well be careful to not burn out

forest compass
#

Thank you Scorcher! I think I will just learn Java to the point until I can succeed in the University, when its done I will switch to Python, since I love Python much more

glad goblet
#

where can i learn more about oop
and class variables and instances and all those stuff

#

??

lost nexus
#

!resources @glad goblet

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.

glad goblet
#

very helpful .....

lunar trail
#

Corey Schafer has probably the best OOP tutorial series I've seen

glad goblet
#

i actually want to learn how to use class vars outside classes

#

ik him

#

will check it out thnx

lunar trail
#

The videos explain how to do that :~)

mellow widget
#

class variables? Do you mean class attributes or instance attributes?

#

Yeah defo watch the series first

unkempt rock
#

bro when would you ever use deques like it sounds really niche to simply just rotate a list from either ends

deft pagoda
#

any time you need a queue, i use them often

true ridge
#

bro when would you ever use deques like it sounds really niche to simply just rotate a list from either ends
@unkempt rock on certain operations, it is also faster

flat gazelle
#

queues are nice for some algorithms, such as BFS

#

also task queues

#

I am not aware of any usecase for a deque that would not be fulfilled with a queue/stack

deft pagoda
#

i made a dihedral group object using deque rotates

#
class Ngon(tuple):
    def __new__(cls, n):
        if isinstance(n, int):
            return super().__new__(cls, range(n))
        else:
            return super().__new__(cls, n)

    def __repr__(self):
        return f'<{super().__repr__()[1:-1]}>'

    def __mul__(self, other):
        new_vertices = deque(self)
        new_vertices.rotate(other)
        return type(self)(new_vertices)

    def __rmul__(self, other):
        return self.__mul__(other)

    def __invert__(self):
        new_vertices = deque(self)
        new_vertices.reverse()
        new_vertices.appendleft(new_vertices.pop())

        return type(self)(new_vertices)
unkempt rock
#

word i feel like a beginner reading that rn

deft pagoda
#

just models rotating and reflecting a ngon:

In [9]: pentagon = Ngon(5)                                                                                                          

In [10]: pentagon * 3                                                                                                               
Out[10]: <2, 3, 4, 0, 1>

In [11]: ~pentagon                                                                                                                  
Out[11]: <0, 4, 3, 2, 1>

In [12]: ~pentagon * 3                                                                                                              
Out[12]: <3, 2, 1, 0, 4>
true ridge
#

oh, the repr is quite nice

deft pagoda
#

i have a much more ridiculous version of the repr that draws an ngon with the vertices labeled

true ridge
#

hahaha, is it too esoteric for this channel?

deft pagoda
#

it's not esoteric, but it's just over-the-top

true ridge
#

would love to see it, if it is public

deft pagoda
#
In [13]: pentagon = NgonVis(5)                                                                                                      

In [14]: pentagon                                                                                                                   
Out[14]: 
                                                 
                                                 
                                                 
                          * * * *                
                    * * * *       *              
              * * * *             * *            
          * * *                     * *          
        *                 | _ |       *          
        *       _             |       * *        
        *       _ |                     * *      
        *       _ |                       * *    
        *                                   * *  
        *                           _         * *
        *                         |   |         *
        *                         | _ |     * *  
        *       _                         * *    
        *       _ |                     * *      
        *     | _                     * *        
                              |       *          
        * * *                 |     * *          
            * * * *               * *            
                  * * * * *     * *              
                          * * * *                
                                *                
                                   
#

it has a builtin raycaster

mellow widget
#

whats the benefit of using __new__ over __init__?

north root
#

__new__ is where the instance is actually created

flat gazelle
#

__new__ lets you return any object, whereas __init__ just gives you an object and you give it the fields

#

generally, you do not need __new__

north root
#

yeah, there are only specific use cases where it actually makes sense to use it

peak spoke
#

new is commonly used in factory classes or immutables

#

but neither of those is terribly common in itself

willow shore
#

for a factory I think I'd rather just make a normal method that returns an instance*

deft pagoda
#

well, ngons subclass tuple so a bit of necessity

willow shore
#

can I overwrite new and return None to make sure no one creates instances of a class you're not supposed to use in this way?

#

say it only has staticmethods

#

just used as a namespace

wide shuttle
#

You can return None but that would return None to the caller, which is probably unexpected behavior

willow shore
#

only if they'd try to do var = Class() right?

wide shuttle
#

Why not raise an exception if you want to communicate that it's not a normal operation?

willow shore
#

because you'd only find out at runtime then

#

hmm

wide shuttle
#

If you return None, they may only find out much later on in the process

willow shore
#

hmm

wide shuttle
#

Either they don't use the instance at all (which is when None) or they get something like NoneType has no attribute... later on, which may be very confusing as to what has actually happened

willow shore
#

mypy seems to understand -> None annotation when I inherit an overwritten new at least

#

actually nvm it doesn't

#

I would have to put it on every single implemented child class -_-

#

sad plugin

deft pagoda
#

you can make a metaclass and raise error on __call__

#

everyone always says to me: salt, metaclass solutions are best solutions

peak spoke
true ridge
peak spoke
#

Why would it overallocate so much and then fall down again?

somber halo
#

I'd say it's due to the garbage collector

peak spoke
#

For example at 100s it goes over twice the previous usage and then back to 12% increase from the previous step

somber halo
#

but yeah this trend in memory consumption is ... interesting

#

Wouldn't expect this trend to be so high

peak spoke
#

I'm not completely sure what the private bytes from the perfmon represent but the trend should remain if that's not the actual memory usage of the process

somber halo
#

the excerpt cited by @true ridge IMO explains this behaviour.

spiral willow
#

Private Bytes in Windows is memory asked for by application, doesn't mean memory contains any data

#

however, it's best determination of memory used by specific app as Working Set/Virtual Bytes can contained DLLs mapped to application but resident elsewhere

rich wharf
#

Python while comprehensions

#

x := x + 1 while True

#

EXPR while CONDITION and the EXPR is evaluated

flat gazelle
#

mixing state and comprehensions is not a great idea

rich wharf
#

alright

boreal umbra
#

Did anyone see the proposal to implement @ for functions? It would create a composite function.

#

But everyone would have to get on board with and memorize the execution for each function in the chain

gray mirage
#

and also that's a weird use for a matrix multiplication operator

#

although then again, pathlib uses /

boreal umbra
#

I never fully understood why matrix multiplication needed it's own operator, since the matrix classes can just type check the other argument.

deft pagoda
#

i think i have a function composition class somewhere

boreal umbra
#

So if you get 2 * my_mat, the __rmult__ method can handle that.

#

@deft pagoda do you just have a lot of classes that implement operators for builtins?

#

Because I really like that.

deft pagoda
#

because you can have element-wise multiplication for *

boreal umbra
#

Ah

flat gazelle
#

Currently, the way numpy works is a*b is element wise product, and a@b is matrix product

boreal umbra
#

I see. Thanks.

deft pagoda
#

yeah, i do have a lot of classes that implement dunders and nothing else a lot of the time

boreal umbra
#

😃

flat gazelle
#

Function composition would be nice, but with the current verbose partial application, it may be a bit unwieldy

boreal umbra
#

What do you mean?

flat gazelle
#

There is also the issue of composition of functions that take more than one argument.

boreal umbra
#

Yeah. It would only work if each function in the chain all magically returned the right tuples.

deft pagoda
#

it's easy to implement --- user error is always possible

flat gazelle
#

Well, for example

partial(map, int)@partial(filter, lambda x: x > 0)
``` Is not all that nice
boreal umbra
#

What does partial do?

spice pecan
#

creates a func with some arguments pre-supplied

flat gazelle
#

functools.partial in this case

boreal umbra
#

So it wraps around another function, supplying whichever arguments you choose for the inner function?

flat gazelle
#

Ye

boreal umbra
#

Nice

spice pecan
#

ye, exactly

#

just like bound methods automatically supply self

boreal umbra
#

Don't methods not necessarily "know" that they are methods?

#

Because you can create a function outside a class and then retroactively add it to a claas

flat gazelle
#

Pretty essential if you want function composition to be actually useful. I don't think python needs or can use functional programming concepts like this effectively

spice pecan
#

if you add it to the class object it will still supply self in instances

#

if you make it an instance attribute, however, it will just stay a regular function

boreal umbra
#

Right

#

I didn't think instances even looked in their own instance dict for callables.

spice pecan
#
>>> class Sample:
...     pass
...
>>> Sample.method = lambda self: print(self)
>>> a = Sample()
>>> a.method()
<__main__.Sample object at 0x0000020E8F040AF0>
>>> a.method = lambda self: print(self)
>>> a.method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'self'```
#

And I believe it doesn't matter if you create the instance before or after adding a method to the class

deft pagoda
#

i think this was close:

In [12]: class Function: 
    ...:     def __init__(self, *funcs): 
    ...:         self.funcs = funcs 
    ...:     def __mul__(self, other): 
    ...:         return Function(*self.funcs, *other.funcs) 
    ...:     def __call__(self, value): 
    ...:         for func in reversed(self.funcs): 
    ...:             value = func(value) 
    ...:         return value 
    ...:          
    ...:                                                                                                                            

In [13]: a = Function(lambda x: 2 + x); b = Function(lambda x: 2 * x)                                                               

In [14]: a(10)                                                                                                                      
Out[14]: 12

In [15]: (a * b)(10)                                                                                                                
Out[15]: 22
#

giving these things a useful repr would be a challenge

#

the upside is you can decorate with @Function

#

i guess use __name__ is the best bet:

In [33]: @Function 
    ...: def times2(x): 
    ...:     return 2 * x 
    ...: @Function 
    ...: def add2(x): 
    ...:     return 2 + x 
    ...:                                                                                                                            

In [34]: times2 * add2                                                                                                              
Out[34]: times2 ∘ add2

In [35]: (times2 * add2)(10)                                                                                                        
Out[35]: 24
rich wharf
#

We have assignment expressions now

#

Why not remove as from with

#
with (f := open('file.txt')):
  ...

over

with open('file.txt') as f:
  ...
frigid jackal
#

I still prefer the first method imo

#

I mean second

#

It just makes more sense to a non-programmer

#

Because you're doing with open("this file") as variable_name, it's understandable to nearly anyone

#

But using the walrus operator just makes it look unusual imo

#

This isn't an argument

#

Just my thoughts 🙂

unkempt rock
#

it's also worth noting that they could carry different contextual meaning. as is the return value from __enter__ whereas the walrus is the return result of the expression

#
class Foo:
    def __enter__(self):
        return 42
    def __exit__(self, type, value, traceback):
        pass
    def __str__(self):
        return "random value"

with (a := Foo()) as blah:
    print(a, blah)
rich wharf
#

still, the walrus can be used the same way

#

with (a := Foo()) is equal to with a as Foo()

unkempt rock
#

except that's not guaranteed to be the case

deft pagoda
#

also, it breaks old code

rich wharf
#

@unkempt rock how is it not guranteed

unkempt rock
#

the snippet demonstrates why

rich wharf
#

wait

#

I see

#

you have me beat

calm pine
river needle
#

anyone know how to input units for answer to a python input

#

like the program asks for the user to input value then it plugs that into a function and the answer is just a number. i want add the units for it

boreal umbra
quaint fox
#

Is await still just syntax sugar for yield from? Or they already changed that? As far as I remember, you couldn't use yield from in a coroutine

rich wharf
#

@quaint fox nope, not anymore

#

you can actually use yields in coros

#

and then use an async for

#

but you can't yield from coros

#

you can't use yield from in a coroutine it looks like

#

but you can still use yield

#

so you can emulate yield from

#
RESULT = yield from EXPR
#

is equal to

#
_i = iter(EXPR)
try:
    _y = next(_i)
except StopIteration as _e:
    _r = _e.value
else:
    while 1:
        try:
            _s = yield _y
        except GeneratorExit as _e:
            try:
                _m = _i.close
            except AttributeError:
                pass
            else:
                _m()
            raise _e
        except BaseException as _e:
            _x = sys.exc_info()
            try:
                _m = _i.throw
            except AttributeError:
                raise _e
            else:
                try:
                    _y = _m(*_x)
                except StopIteration as _e:
                    _r = _e.value
                    break
        else:
            try:
                if _s is None:
                    _y = next(_i)
                else:
                    _y = _i.send(_s)
            except StopIteration as _e:
                _r = _e.value
                break
RESULT = _r
quaint fox
#

Oof

rich wharf
#

really though

#

it's basically for i in x: yield i

#

at the basics

quaint fox
#

So, yield from is basically impossible inside a coroutine because it's implemented as an synchronous for?

rich wharf
#

i'm not sure why it's disallowed in a coroutine

#

but it's behavior is possible to emulate

quaint fox
#

Oh well, that aside, yielding in a coroutine creates something like an asynchronous generator, does that means that stuff like __next__ return coroutines?

rich wharf
#

I don't think so

#

Maybe __anext__

#

but coroutines are generators are different

#
async def coro(x, y):
  for i in range(x):
    yield i
    await asyncio.sleep(y)

async for i in coro(3, 4):
  print(i)
quaint fox
#

Well, as far as I know, coroutines are just fancy generators, so having an asynchronous generator amuses me

#

But if they use different magic methods, I see that possible

rich wharf
#

yep

#

coro uses __aiter__ I'd think

quaint fox
#

Ok thank

#

You cleared my confusion

rich wharf
#

np

wide shuttle
#

It's because yield from is not just for i in iterable: yield i

rich wharf
#

yep

wide shuttle
#

The snippet you shared above, the huge one from the pep, should be the equivalent of what yield from does. Instead of just yielding from an iterable, it allows you to delegate things to subgenerators, allowing communication between the original caller and the innermost subgenerator. This opened up a lot of possibilities for the old style coroutines. Fluent Python describes it as opening up a tunnel from the innermost generator to the original caller.

rich wharf
#

Why isn't it allowed in async functions though?

wide shuttle
#

When you now use yield within a coroutine/async def, it becomes an async iterator and you can used it in async for item in gen(), where the __anext__ method of the async generator is awaited each time to produce the new item. And, as mentioned earlier, in this simple case, yield from iterable would be the functional equivalent of for item in iterable: yield item. This means that whenever you use yield from in a new-style coroutine, calling the async func should return an async generator. However, if you look at the "functional equivalent" above, there's nothing in the current implementation to support asynchronous iteration that uses await gen.__anext__(). That means the yield from implementation would have the change quite drastically in order for it to support that.

#

However, I've never taken a deep dive into the implementation and I'm not a coroutine expert. I'm sure aeros knows much more about the matter. I've seen the suggestion to implement support prop up a few times.

undone hare
#

I am wondering, did any of you wonderful people did some tests on namedtuple to see if they are worth using for performance reasons instead of classes?

molten onyx
#

IIRC namedtuples are just slotted classes

stable grail
#

yes, thats a fair comparison

wide shuttle
#

It builds a (slotted) tuple subclass with a custom __new__, I think

#

And it uses exec for that part, which some people don't like

#

Ah, yeah

boreal umbra
#
field_defaults = dict(reversed(list(zip(reversed(field_names),
                                                reversed(defaults)))))
#

This is in the source code for named tuple

#

I don't wanna use them anymore.

deft pagoda
#

i did something similar because i couldn't figure out a way to preserve a function signature when adding to the function from a metaclass

boreal umbra
#

oh you know what?

#

Maybe this would be a use case for composite functions 😮

deft pagoda
#

would a composite function keep the signature of the innermost function

#

that'd be sweet

grave jolt
#

Isn't that what functools.wraps does?

deft pagoda
#

close, but not the signature

hasty thistle
#

field_defaults = dict(reversed(list(zip(reversed(field_names), reversed(defaults)))))
doesn't that reverse everything twice, returning it to the original order? am I missing something? 🤔

deft pagoda
#

he also initializes field_defaults right above that

#

i don't know wtf is going on with this code

peak spoke
#

Does the blame show something?

deft pagoda
#

it's hettinger

wide shuttle
#

He initializes it because defaults are optional

#

So, in the case you don't have defaults, you get the empty dict

grave jolt
#

Maybe it's made to change the dict behavior from override to ignore? (doesn't make any sense to me)

wide shuttle
#

He uses this style a lot

#

This is the full snippet:

    field_defaults = {}
    if defaults is not None:
        defaults = tuple(defaults)
        if len(defaults) > len(field_names):
            raise TypeError('Got more default values than field names')
        field_defaults = dict(reversed(list(zip(reversed(field_names),
                                                reversed(defaults)))))
peak spoke
#

well would be nicer under an else imo

grave jolt
#

Beautiful, idiomatic Python (C)

peak spoke
#

but is there any purpose behind all the reversed instead of using the zip directly

grave jolt
#

Maybe it's to change the zip behavior

wide shuttle
#

zip stops as soon as the shortest iterator runs out

grave jolt
#

^

hasty thistle
#

oohhh

grave jolt
#

Why would anyone comment that, it only took us 5 minutes to figure out that line

wide shuttle
#

default values, in a signature, always come after fields with non-default values

#

So, you start from the back, until you run out of default values

#

and you're left with fields (potentially) that don't have default values

grave jolt
#

Maybe a defaultdict would be better?

visual maple
#

zip zap monkaS

hasty thistle
#

Maybe a defaultdict would be better?
that's... created in the same file...

wide shuttle
#

how would a default dict work?

#

You don't want to have any values attached to the fields with no defaults

grave jolt
#

oh

#

I thought it was the other way around

wide shuttle
#

This is just a dict that holds the parameters that do have default values

#

It's just to support this:

#
>>> from collections import namedtuple
>>> Point = namedtuple("Point", "x y", defaults=(10,))
>>> Point(1)
Point(x=1, y=10)
>>> Point(1, 2)
Point(x=1, y=2)
visual maple
#

use a dataclass

deft pagoda
#

is this more readable:

In [1]: fields = ['hi', 'there', 'bob', 'what']                                                                                     

In [2]: values = [4, 6]                                                                                                             

In [3]: f = iter(fields)                                                                                                            

In [4]: for _ in range(len(fields) - len(values)): 
   ...:     next(f) 
   ...:                                                                                                                             

In [5]: defaults = dict(zip(f, values))                                                                                             

In [6]: defaults                                                                                                                    
Out[6]: {'bob': 4, 'what': 6}
sacred tinsel
#

oh I didn't even realize you could do that

#

it's been a while that I used a non-typed namedtuple

#

I just can't get over how nice this is

>>> import typing as t
>>> 
>>> class Cat(t.NamedTuple):
...     name: str = "Ves"
grave jolt
#
defaults = {
    name: default_value for (name, default_value)
    in zip(fields[-len(values):], values)
}
#

This is still semantically one line, but IMO a more readable one

#

Or even:

fields_with_defaults = fields[-len(default_values):]
defaults = {
    name: default_value for (name, default_value)
    in zip(fields_with_defaults, default_values)
}
# or:
defaults = dict(zip(fields_with_defaults, default_values))
boreal umbra
#

It seems like the advantage you get with slotted classes is that if you define __slots__ within the class, then instances are stored as tuples rather than dictionaries, yes?

#

Which I assume means that attribute lookup takes slightly longer (still O(1)), but the instance uses less memory.

deft pagoda
#

i think attribute lookup is faster with slots

#
dict(zip(fields[-len(values):], values))

seems fine

undone hare
#

How would that even work if you use a tuple? You'd need to be able to map an attribute name to a variable

hasty thistle
#

Which I assume means that attribute lookup takes slightly longer (still O(1)), but the instance uses less memory.
using __slots__ as opposed to not using them seems to be faster
https://stackoverflow.com/a/28059785/11400238 (sidenote: most extensive answer I've ever seen on SO)

wide shuttle
#

I haven't looked into __slots__, but I assume that it creates only one look-up table for the entire class instead of a mutable per-object dict

#

And probably stores it in some smart way in C (struct)

boreal umbra
#

I didn't think you could create a C struct at runtime.

wide shuttle
#

Hmm, yeah

boreal umbra
#

Maybe the interpreter can predict what structs it will need at compile time?

#

This isn't something I know very much about.

grave jolt
#

Well, structs don't 'exist' at runtime, right?

#

And even if they would, all the fields would still be PyObject*s

boreal umbra
#

I don't really know how C works internally.

#

Magic, I guess.

grave jolt
#

From what I've seen, it uses some techniques that mimic OO features.

boreal umbra
#

Weren't objects a C++ invention designed to expand on structs?

unkempt rock
#

I don't really know how C works internally.
@boreal umbra

it varies from compiler

#

GCC and CLANG can treat it in different ways

#

( ps: I know that clang is just the front-end of the compiler )

boreal umbra
#

I don't know what CLANG is, so you don't have to worry about sounding uninformed with me 😄

unkempt rock
#

I don't know what CLANG is, so you don't have to worry about sounding uninformed with me 😄
@boreal umbra

It's a C compiler, like GCC 😛

boreal umbra
#

I inferred as much

grave jolt
#

In CPython, every 'python object' conforms to some "PyObject" interface. Something like:

TY_STRING = 1
TY_RATIONAL = 2
# py_object = [type, repr_function, number_of_attrs]

# imagine that these arrays are stores contiguously in memory:
my_string = [TY_STRING, lambda x: x[3].encode("utf-8"), 1, b'hello_world'] # "hello_world"
my_rational = [TY_RATIONAL, lambda x: str(x[3])+"/"+str(x[4]), 2, 22, 7] # 22/7

memory = {
  0x4200: TY_STRING, 0x4201: lambda x: x[3].encode("utf-8"), 0x4202: 1, 0x4203: b'hello_world',

  0xff00: TY_RATIONAL, 0xff01: lambda x: str(x[3])+"/"+str(x[4]), 0xff02: 2, 0xff03: 22, 0xff04: 7,
}

Then you can pass a pointer to the beginning of an object struct. Since all the objects 'start' the same, you can cast the pointer type to PyObject * and then just treat some memory location as if it was just a PyObject.

def PyRational_Check(PyObject_ptr memory_location):
    return memory[memory_location + 0] == TY_RATIONAL

def PyRational_Numerator(PyObject_ptr memory_location):
    return memory[memory_location + 3]

def PyRational_Denominator(PyObject_ptr memory_location):
    return memory[memory_location + 4]

# Then you can have polymorphic functions, kinda
def PyObject_ConvertToString(PyObject_ptr memory_location):
    return memory[memory_location + 1](memory_location)
assert PyRational_Check(0xff00)
assert not PyRational_Check(0x4200)
assert PyRational_Check(0) # Segmentation fault (core dumped)
#

But I'm not really a CPython developer, so please correct me if you are

boreal umbra
#

I do recall that everything is a PyObject* struct, and that that struct keeps track of the reference count for that object

grave jolt
#

yes, I oversimplified stuff

boreal umbra
#

except for when that object is immune from being deleted, ie those integers and class objects.

grave jolt
#

Are classes undeletable?

#

I don't think so

boreal umbra
#

I believe not.

grave jolt
#

I mean, uncollectable

#

Since you can create them at runtime.

boreal umbra
#

I thought that once a class is created, it stays in memory for the rest of the program

#

I'm not sure what it would take to ensure that a class doesn't get deallocated until the last instance is referenced.

grave jolt
#

I think classes are treated like other objects in that regard

#
def f():
  class A:
    ...
  # do something, and don't store A anywhere
  # A.refcount is 1 now
  return 256

# A.refcount is 0 now
boreal umbra
#

But what if f() returned an instance of A?

grave jolt
#

an instance of A always has a reference to A

boreal umbra
#

ah good point

#

but

#

hmm

#

I was going to say, what if you don't have any A instances left

#

but then you call f() again?

whole glacier
#

Do note that if you put a class in a func like that, that class will be created anew everytime you call f()

grave jolt
#

Yes

boreal umbra
#

oh cool

grave jolt
#

It's like

A = make_me_a_new_class(...)
boreal umbra
#

that makes sense

whole glacier
#

!e ```py
def f():
class A:
...
print(id(A))

f()
f()

fallen slateBOT
#

@whole glacier :white_check_mark: Your eval job has completed with return code 0.

001 | 94422229536880
002 | 94422229537824
grave jolt
#

The same way def creates a new function (or lambda)

whole glacier
#

classes are objects as well, so any inner objects within the function will be recreated

boreal umbra
#

It makes perfect sense. For some reason it didn't occur to me.

cloud crypt
#

happens to the best of us

#

though I have no idea why one would create a class inside of a function except for very rare cases

wide shuttle
#

Like namedtuple? We're going in circles!

#

(It does use type(...) not class ... written out, obviously)

undone hare
#

Well yeah, there are some cases where you could need a class factory

grave jolt
#

I made a module for sum types (aka algebraic data types/disjoint unions/Hello T|World-thing in functional languages) recently.

#

There, I created metaclasses and metametaclasses inside a function.

cloud crypt
#

namedtuple is well

#

I love attrs

#
from attr import dataclass

@dataclass
class Point:
    x: int
    y: int

a, b = Point(0, 0), Point(1, 1)
print(a, b, a < b)```
undone hare
#

attr? isn't dataclass in the dataclasses module?

#

I may have dreamed about that module though

deft pagoda
#

yeah, attrs is another one

cloud crypt
#

it is in attrs as well

#

imho attrs is nicer

deft pagoda
#

dataclass idea came from attrs i think

cloud crypt
#

yeah same

deft pagoda
#

i dunno if it's nicer, it looks basically the same

boreal umbra
#

though I have no idea why one would create a class inside of a function except for very rare cases
@cloud crypt I've done it one time, when I needed for there to be a way to create a class using a JSON.

#

So the function reads the JSON and returns a class for that specification.

grave jolt
#

Or do you have some other purpose?

cloud crypt
#

I wonder what PyPI does not have haha

grave jolt
#

I literally found it by searching for "json schema to class". It's like import antigravity

boreal umbra
#

I was working on an nlp package, and the different pipelines were each individual classes

#

and then there were a few usecase-specific options that you'd pass to the constructor for those pipelines

#

We wanted to make it so that you could customize the whole pipeline.

#

In a way that was compatible with the CLI for the package.

undone hare
#

Oh, attr isn't a stdlib module

cloud crypt
#

yep it is not

true ridge
#

dataclasses FTW

cloud crypt
#

Ah fun fact, latest 3.8.2 release has 2m lines in Lib

true ridge
#

wow, too much code

cloud crypt
#

ye haha

#

Guido has 1m additions in cpython repo lol

true ridge
#

on master, it looks like we have 800k (including tests etc.) under Lib/

cloud crypt
#

shrug

undone hare
#

Lib/ is only 37.33 MB of freakin' code haha

true ridge
#

if we exclude the tests, there are 315357 lines of code

#

find Lib -type f -name "*.py" -not -name "test_*.py" -not -path "*/test/*" -not -path "*/tests/*" -not -path "*/*_test/*" | xargs -e wc -l

#

something like this

cloud crypt
#

pythom

#

I have written 30k lines of python in my life hahaha

raven sphinx
#

v

undone hare
#

Nice try

fallen slateBOT
#

@raven sphinx Per Rule 6, your invite link has been removed. If you believe this was a mistake, please let staff know!

Our server rules can be found here: https://pythondiscord.com/pages/rules

gray mirage
#

blinks

#

oh well, mods will already be aware

undone hare
#

They left hahaha

gray mirage
#

yup, saw that

undone hare
#

God I love internet

grave jolt
#

Well, they can join again and post the link again.

undone hare
grave jolt
#

Does the bot maintain a list of pending punishments for users who left?

hoary marsh
#

Im not sure if he left or got kicked \ banned, but as long as we didn't get links here its fine for me

undone hare
#

Does the bot maintain a list of pending punishments for users who left?
@grave jolt Yup it does

grave jolt
#

Well, at least it's not segmentation fault

inland acorn
#

it got rate limited, so joe restarted it

grave jolt
#

oh