#internals-and-peps

1 messages ยท Page 37 of 1

deft pagoda
#

it's pretty hacky

oblique crystal
#

Oh interesting. I need to save it somewhere for future ref

wide shuttle
#

I haven't read the online preview of the next edition of Fluent Python yet, but I'm sure it's in there as well

#

The first edition spend quite some time talking about how to solve that issue using metaclasses and decorators

oblique crystal
#

Huh. But it's not free book right

fossil pumice
#

oh wow, that's funky

#

__set_name__, I mean

#

thanks for explaining it

deft pagoda
#

there's a good beazley talk that covers them too

wide shuttle
#

oh cool, I haven't seen that one yet

deft pagoda
#

it's why i've been experimenting with all these meta hacks recently

wide shuttle
#

it feeds right into my python talks addiction

deft pagoda
#

i've done some god awful stuff, but it feels like magic sometimes

wide shuttle
#

I think that these tools are very powerful when used in the right places, but you shouldn't overuse them

#

If you're building a larger application that's more akin your company's framework, sure

#

or a personal project for the cool

#

or a framework for others to use

deft pagoda
#

i just like to see what's possible

wide shuttle
#

yes

deft pagoda
#

extremely fascinated by the enum example, which i added kwargs to

#

!e

from itertools import count

class IncrDict(dict):
    def __init__(self, start=0, step=1):
        self.counter = count(start, step)

    def __missing__(self, key):
        if key.startswith('__'):
            raise KeyError(key)

        self[key] = next(self.counter)
        return self[key]

class EnumMetaclass(type):
    def __prepare__(*args, **kwargs):
        start = kwargs.get('start', 0)
        step = kwargs.get('step', 1)
        return IncrDict(start, step)

class Enum(metaclass=EnumMetaclass):
    def __init_subclass__(cls, **kwargs):
        """Pull kwargs from class def"""

class Fruit(Enum, start=10, step=15):
    APPLE
    BANANA

print(Fruit.APPLE, Fruit.BANANA)
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

10 25
deft pagoda
#

it just seems like magic that python lets you do this

wide shuttle
#

Thanks

#

He has an older talk about metaprogramming, but it predates all this

#

probably why this is called the fun of reinventing

gray mirage
#

If __set_name__ could see the type hint as well you could use it for delegation

#

That would be wild

wide shuttle
#

it should be able to access it using the owner and the name

gray mirage
#

Oh, true, yeah

deft pagoda
#

yeah, you can get all that

cloud crypt
#

oh hey, this channel sounds fun :p

#

TIL __missing__ exists, haha

wide shuttle
#

Yeah __missing__ is quite useful

undone hare
#

I wonder if annotations overloading will ever be added to cpython

#

It would be super nice to have

wide shuttle
#

I wonder if annotations overloading will ever be added to cpython
@undone hare

Can you describe what you mean by annotations overloading?

undone hare
#

Well, we can't really have operator overlapping, so annotations overloading haha

wide shuttle
#

You mean multiple dispatch based on annotations?

#

That's what gdude was hinting at

undone hare
#

For instance, you could have the function spam dined twice, once with spam(bacon: int) and with spam(eggs: str), and if you call spam(42) for instance, the first one will be called

#

Ah yes

wide shuttle
#

strictly speaking, you could already do something like this, but it's not built-in

#

you can define multiple functions and a function that acts as the dispatcher/wrapper that inspects signatures and compares it with annotations

#

The Beazley talk linked above by salt-die shows a few handy tools you could use for that

undone hare
#

Hmm, you could even do that with a decorator

#

It sounds like a fun thing to do

wide shuttle
#

That's more or less the same

#

The decorator acts as a wrapper/dispatcher for the functions you passed to it

#

You just use the decorator-syntax to pass the functions to the dispatcher

undone hare
#

My main concern will be that one definition will shadow the previous one, and I'm pretty sure the first one is gone, so you'd have to call something in the middle, a decorator seems the smartest

wide shuttle
#

the functions objects don't shadow each other, only the names will be shadowed

undone hare
#

It could work the same way d.py creates commands, you actually return an object instead of a function

wide shuttle
#

but that's what you eventually want with a single dispatch: you have a single name that you call

undone hare
#

Well, that's the same idea, they will be garbage collected

wide shuttle
#

No, the dispatcher will hold a reference

#

Otherwise it wouldn't be able to dispatch

undone hare
#

I mean, if you do a plain

def spam(bacon: int):
   ...
def spam(eggs: str):
   ...
# Create handler here
```You won't be able to access the first definition of `spam()`
wide shuttle
#

Obviously not, no

#

but, the name of the function does not matter at all

#

it's just the dispatcher that needs a reference to the function object

#

Hey @hollow jolt, please keep it in English

hollow jolt
#

Ok ๐Ÿ‘Œ

undone hare
#

I think it should still have the same name

#

Or that's not a proper operator overloading

wide shuttle
#

It doesn't really matter ยฏ_(ใƒ„)_/ยฏ

#

I care about the function objects and the dispatching

#

I mean, I'm not saying a decorator isn't handy

#

It could be used to automatically group function objects based on the name you give them

#

But decorators are just callables you call with the decorated callable as an argument

undone hare
#

I'm thinking about a syntax like that

@overloaded
def spam(bacon: int):
   ...

@overloaded
def spam(eggs: str):
   ...
```and you can call `spam() ` as you'd normally do
wide shuttle
#

yeah

#

but

#
def one(bacon: int):
   ...

overloaded(one)

def two(eggs: str):
   ...

spam = overloaded(two)
#

would work just as well

#

You'd be able to call spam and depending on the argument you pass, it calls either one or two

#

I was just saying that you don't need to use decorators, but it's nice syntactic sugar

#

With classes and dispatching methods, you could use a descriptor

#

It depends on what you're doing, I guess

#

The magic is not in that you're using a decorator, but the callable that is the decorator

wide shuttle
#

As very quick example that does not really inspect the annotations all that closely (but it's just an illustration):

#

!e

from collections import defaultdict
from functools import partial
from inspect import signature


class Gather:
    def __init__(self):
        self._functions = defaultdict(list)

    def __call__(self, func):
        self._functions[func.__name__].append(func)
        return partial(self.dispatch, func.__name__)

    def dispatch(self, function_name, *args, **kwargs):
        for func in self._functions[function_name]:

            sig = signature(func)
            ann = func.__annotations__

            try:
                bound_arguments = sig.bind(*args, **kwargs).arguments
            except TypeError:
                continue

            if all(isinstance(value, ann[name]) for name, value in bound_arguments.items()):
                return func(*args, **kwargs)

        raise ValueError("No registered function matches the annotation types")




gatherer = Gather()


@gatherer
def foo(a: str):
    print(f"{a} is a str!")

@gatherer
def foo(a: int):
    print(f"{a} is an int!")

foo(10)

@gatherer
def bar(a: str, b: str):
    print(f"{a} and {b} are str!")

@gatherer
def bar(a: int, b: int):
    print(f"{a} and {b} are int!")

bar("10", "10")
fallen slateBOT
#

@wide shuttle :white_check_mark: Your eval job has completed with return code 0.

001 | 10 is an int!
002 | 10 and 10 are str!
languid dagger
#

Is that a custom single dispatch?

wide shuttle
#

yeah, a very naive one

#

It expects types as annotations and relies on not having the __future__ import

languid dagger
#

I thought functools.singledispatch also checked type hints

true ridge
#

@languid dagger yep, starting from 3.7

wide shuttle
#

I think functools.singledispatch only inspects the first parameter

#

And does not take the others into account

steep harness
#

hey is there every week a python challenge

wide shuttle
#

Hey @steep harness, I'm not sure what you're asking. Our community does not have a weekly challanges channel, although it is a plan we have for the future. Like everything, it has to be implemented and maintained, though. If you want to ask questions about the community, #community-meta is probably a better channel to do that. If you want to discuss Python in general, try #python-discussion. This channel is having conversations about Python itself, the language.

steep harness
#

nice but i thing i could be fun wift Weekly challenges

deft pagoda
#

you avoid the instantiation with a meta

#
from itertools import chain

class dynamicdict(dict):
    def __init__(self, default_factory, **kwargs):
        super().__init__(**kwargs)
        self._default_factory = default_factory

    def __missing__(self, key):
        self[key] = self._default_factory(key)
        return self[key]

class FuncStorage:
    def __init__(self, name):
        self.name = name
        self.func_dict = {}

    def __call__(self, *args, **kwargs):
        annotations = tuple(map(type, chain(args, kwargs.values())))
        return self.func_dict[annotations](*args, **kwargs)

    def __repr__(self):
        return f'overloaded function {self.name}'


def there_can_be_only_one(cls):
    return cls()

@there_can_be_only_one
class overloaded:
    func_storage_by_name = dynamicdict(FuncStorage)

    def __call__(self, func):
        ann = tuple(func.__annotations__.values())

        func_storage = self.func_storage_by_name[func.__name__]
        func_storage.func_dict[ann] = func
        return func_storage

@overloaded
def add(x: int, y: int):
    return x + y

@overloaded
def add(x: str, y: str):
    return x + y + '!'
oblique crystal
#

so id will add differently depending on the type?

deft pagoda
#

this is naive, since it doesn't check for more complex types like Any or Unions or whatever

#

yep

oblique crystal
#

so many cool stuff there. I wonder though if I ever get to use any ๐Ÿ™‚

whole glacier
#

This is actually pretty cool, I used to do this a lot in C# because they support same function with different arguments, so you can call one function but depending on the arguments it will behave differently

#

Method / function overloading

wide shuttle
#

You could slap a class decorator on that class instead of a metaclass

deft pagoda
#

oh, just return the instantiated version?

#

that works

wide shuttle
#

yeah or just divert the call to another another attribute to bypass object creation entirely

deft pagoda
#

how about that

oblique crystal
#

Method / function overloading
@whole glacier yeah I know about method and operator overload from C++/C#

#

but in python I never saw it, and personaly I used only things like itemgeeter

#

override is when you inherit and change method no?

flat gazelle
#

ye, I misread

oblique crystal
#

oh ok

#

I was just unsure cause in python I did not go much into those

deft pagoda
#

might also want to overload based on variable names

flat gazelle
#

in python you have to implement it yourself for methods. But for operators it does exist

deft pagoda
#

i think walking over the bound arguments probably better than a annotation dict

oblique crystal
#

might also want to overload based on variable names
hm?

fossil pumice
#

I like this new channel.

oblique crystal
#

is there any book or articles on this things? It seems like I am missing a lot of stuff. Even if I never use it, that's some cool shit you can do

#

so knowing it and having a reference won't hurt

wide shuttle
#

Do you mean on the Python data model?

#

Fluent Python is the best introduction to these kind of things I can think of

#

The new edition is being released soon

#

For the rest, I watch a lot of talks and read the docs

oblique crystal
#

so it covers differnet things salt was posting above? cool maybe I gotta grab it

wide shuttle
#

The things Salt posted above use the data model, yeah

#

A metaclass, some special methods/dunders

#

He also linked a Beazley talk a few hours ago that I'd recommend now that I've seen it

peak spoke
#

the reference in the python docs also has a lot of cool stuff, I often end up looking at the lexical analysis or the datamodel page; although things like metaclasses aren't explained in depth there

deft pagoda
#

i've been binging a lot of beazley

#

even going back to his talks in the 90s

oblique crystal
#

salt are you know/do this things just as side fun stuff or you use it on daily job?

#

I don't remeber if you ever mentioned what is your daily job so ๐Ÿคทโ€โ™‚๏ธ I only rmember you have some math background

deft pagoda
#

you could do this if you only need the instance:

overloaded = type('', (), {'func_storage_by_name': dynamicdict(FuncStorage), '__call__': __call__})()
oblique crystal
#

ugh, FLuent python s 26 Eur for kindle and almost 60 for paper back ๐Ÿ˜‘ probably need to wait for some disounts or bundles ๐Ÿ™‚

deft pagoda
#

this is just a hobby mostly

fossil pumice
#

fluent python is worth it

#

great book

oblique crystal
#

good to know. But if I'll buy it is probably worth to wait for new edition?

#

hehe I am not used to buying books yet ๐Ÿ˜‚ Now though I should be able to

wide shuttle
#

If you don't mind waiting, the new edition is coming out soon. it's already available in preview online.

#

The old version is still worth every cent as well

#

It's just that it was released just as 3.5 was being released, meaning that it only mentions things like await/async def and it does not have f-strings yet

#

nor some of the more recent goodies, like __init_subclass__ and __set_name__

deft pagoda
#

__init_subclass__ has been real fun to abuse

wide shuttle
#

The 2nd edition is almost here, though

sturdy timber
#

I'm hoping the new one wont be much more expensive than the old one, I'm really looking forward to getting it though

sacred tinsel
#

I'm tempted to get it in paperback once it comes out

#

but I already have the old one

deft pagoda
#

you think

isinstance(value, ann.get(name, type(value)))

for un-annotated args

#

is that right?

oblique crystal
#

If you don't mind waiting, the new edition is coming out soon. it's already available in preview online.
no problems for me to wait yeah. Not like I need it

willow shore
#

hey I saw someone import a base class and in order to make sure it had the function he needed he added an assert for the base class below the imports before his own child class implementation

#

is this something people actually do?

true ridge
#

In general, abstract classes are more useful

#

rather then simple asserts about a method's existence

eternal sigil
#

It's trying to implement java thing IIRC - forcing an interface. You can do the same in python with abstract base classes

wide shuttle
#

I think the assert here was placed above the child class, so it asserted that the base class had a method in the first place

#

If I read the question correctly

#

The abstract base class would force the child to implement it (or force it to be abstract as well)

eternal sigil
#

Oh, nice catch- I missed that. I guess it would work if you're worried that the base class isn't closed to modification?

wide shuttle
#

You could implement an abstract base class that specifies the protocol and use a __subclass_hook__ so you're able to use issubclass to check if a class implements the protocol, but I've never seen the pattern described above myself.

#

Not that I've been in the position to observe it a lot

willow shore
#

yeah I figured he was trying to emulate interfaces

#

I'll look into all of this thanks

boreal umbra
#

Do you think abstract classes are just another way that a language specification can show distrust towards its users?

full jay
#

I think you're going to have to elaborate on that

wide shuttle
#

I think they're coming from the position of Python having the philosophy of consenting adults

#

And having abstractmethods are a way to force an implementation

full jay
#

They're also a way to simplify the process

#

I think it's more an ease of use thing than a helicopter parent thing

undone hare
#

Well, abstract classes are important to provide some sort of safety in your code at some point

boreal umbra
#

"We can't trust our users to make classes correctly unless we give them templates, and we can't trust them not to try to instantiate the template itself."

deft pagoda
#

is it trust or just debugging your future self

oblique crystal
#

python is still much more liberal there compared to C family for exapmple, no?

slim island
#

It's not about trust - its just easier if users can't make that mistake if they don't want to be able to make that mistake

oblique crystal
#

in those regards

undone hare
#

Human errors are a thing, and it is important to prevent them

flat gazelle
#

Humans are bad at not ever making mistakes, computers are pretty good at that though

full jay
#

Until you pour soda on them

slim island
#

And thats why my programming language will only allow robots to write it

deft pagoda
#

i think if you're in a position to prevent awful things from happening, then you should do it

full jay
#

I really don't think it ties the user's hands that much either

eternal sigil
#

show distrust towards its users is a pretty aggressive framing. I trust my users to copy and paste the code into a separate class if they really want it.

Also, a lot of this is context sensitive. If I'm using a factory pattern, I'm expecting all concrete implementations to match a certain interface. If you don't implement it, you break my code

full jay
#

That second point is the main argument to make I think

#

It's less about trust and more about making sure stuff just works

flat gazelle
#

there is some merit to a language letting you do <the dumb thing> over a worse solution without <the dumb thing>, but I prefer a language that does not let me do <the dumb thing>, and instead provides a smarter solution.

#

and there often is a smarter solution

#

reflection is an example of something where a smarter solution is pretty hard to find

slim island
#

front facing cameras are better than normal reflections. You have more freedom to move them about

full jay
#

Until the power goes out

eternal sigil
#

Also, while this may not apply 100% across the board, if you're inheriting from my class, and its use of abstract methods is making it impossible for you to use it, you're probably inheriting from the wrong class and introducing new problems anyway.

full jay
#

Fair point

deft pagoda
#

i edited the widget metaclass from widget.py in kivy to this:

class WidgetMetaclass(type):
    '''Metaclass to automatically register new widgets for the
    :class:`~kivy.factory.Factory`.
    .. warning::
        This metaclass is used by the Widget. Do not use it directly!
    '''
    def __prepare__(*args):
        return ChainMap({}, PROPS)

    def __new__(metas, name, bases, methods):
        methods = methods.maps[0]
        return super(WidgetMetaclass, metas).__new__(metas, name, bases, methods)

    def __init__(cls, name, bases, attrs):
        super(WidgetMetaclass, cls).__init__(name, bases, attrs)
        Factory.register(name, cls=cls)
        if attr := getattr(cls, '__KV__', None):
            Builder.load_string(dedent(attr))


class WidgetBase(EventDispatcher, metaclass=WidgetMetaclass):
    pass

so i get the Properties for free and it will automatically load my kv string

#

thanks beazley

wide shuttle
#

Slightly related to protocols, abstract baseclasses and structural substyping/static ducktyping: pep 544 is an interesting read

#

!pep 544

fallen slateBOT
#
**PEP 544 - Protocols: Structural subtyping (static duck typing)**
Status

Accepted

Python-Version

3.8

Created

05-Mar-2017

Type

Standards Track

flat gazelle
#

structural typing is really nice

full jay
#

"Static Duck Typing". That's a phrase I never thought I'd hear

#

Makes sense, though. Those two aren't mutually exclusive

gloomy rain
#

Is that like type inference?

flat gazelle
#

structural typing is when you describe a type not as Sequence, but rather as has {length: int, get: int -> el_type}, so even things that are not explicitly inheriting from Sequence but have those methods are of that type. Python already has it to an extent afaik.

gloomy rain
#

Well, Python doesn't really need it, as it doesn't keep track of types, I guess?

#

If you execute code like some_obj.foo(), Python only cares if the object has the method, not which type it actually is.

#

You could implement the checks manually.

flat gazelle
#

yes

gloomy rain
#

But so this is like syntactic sugar for validating that an object has certain attributes?

flat gazelle
#

it is I think about adding capabilities to typing to describe structural types

wide shuttle
#

It depends a bit on what you're doing. This fits in the movement to add support for static type checkers by duck typing things like protocols instead of explictly registring that a class implements a protocol

#

The example given in the PEP is of a Bucket class which is Iterable[int] and Sized

#

Instead of explicitly having to register it as Sized and Iterable[int], you could infer that from the annotated __iter__ and __len__ methods

gloomy rain
#

That's cool.

wide shuttle
#

So instead of

from typing import Sized, Iterable, Iterator

class Bucket(Sized, Iterable[int]):
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

you can do this:

from typing import Iterator, Iterable

class Bucket:
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...
#

Notice the lack of explicit subclassing

deft pagoda
#

is -> only allowed after function types

boreal umbra
#

I realize this is actually a question for esoteric python

#

but I need to know how to make 12 == 15 True.

peak spoke
#

couple ways, but why not ask in esoteric python?

zenith topaz
#

Change the references with c_types.

peak spoke
#

since you create new ints you can change its eq for example

zenith topaz
#

I've seen juan do it several times.

undone hare
#

It would totally break test suites

#

After the first fail, all the others will fail

grave jolt
#

@flat gazelle

there is some merit to a language letting you do <the dumb thing> over a worse solution without <the dumb thing>, but I prefer a language that does not let me do <the dumb thing>, and instead provides a smarter solution.
But sometimes the language designer think that X is a dumb (or easily abusable) thing and just don't put it in a language.

#

Like Java not having operator overloading.

#

And a few breaking changes in Elm, specifically 1) disallowing tuples to be longer than 3 elements; 2) disallowing creating your own infix operators (like in Haskell).

flat gazelle
#

a worse solution without <the dumb thing>
those are what I meant with that.

#

though the elm infix operators are not too bad, as you can get similar behaviour with |> fun

#

still, would be nicer to have it

#

or any other way to call things infix

#

kotlins infix fun, scalas, kotlin, C#,... extension functions, haskell `fun`, rakus infix:<fun>, clojure arrow macros, ...

#

any of that would be pretty nice

crystal pebble
#

What is |> here? The same as in F#?

flat gazelle
#

ye

grave jolt
#

Yes, it's a pipe.

full jay
#

Remind me what that does?

flat gazelle
#

a |> b = b a afaik

full jay
#

Ahhhh okay

grave jolt
#

a x |> b y |> c === c(b y (a x))

full jay
#

I feel like I've seen that so many times but it never clicked before

grave jolt
#

The worst part is that these changes broke compatability with existing libraries.

spiral willow
#

we have piping Pwsh, it's good/bad

#

you can get some WTF code

flat gazelle
#

you can get always get WTF code

#

bad code cannot be stopped with language constraints

full jay
#

What's the main benefit of piping?

flat gazelle
#

code reads from left to right

grave jolt
#

I think piping is useful in functional approaches, where composition is much more common.

full jay
#

So it's purely a style/aesthetics thing?

grave jolt
#

Well, you can easily change |> to >>=

glass robin
#

I've seen that used in Scala

flat gazelle
#

ye, personally I often find infix calling clearer than the prefix calling

grave jolt
#

Operator overloading can also be used to produce highly WTF code, but it's still used.
I think the most WTF-prone feature in all languages is being able to name things.

#

It brings the most confusion in comparison.

full jay
#

I kind of think this breaks consistency across code

#

Like I get the purpose but I don't know

flat gazelle
#

ye, having one and only one way to call a function has its merits

#

but even python does not have that

full jay
#

Fair

crystal pebble
#

You know, I'd be interested in a composition operator for Python (.)

flat gazelle
#

if anything, I would take the arrow ones

#

<<< and >>>

#

in haskell Control.Arrow

full jay
#

I don't think I've ever thought of it as from right to left, more from inside to out

flat gazelle
#

but I think $ and &(the lens one) make more sense

#

python doesnt really manipulate functions that much

full jay
#

I do like this stylistically for functional style stuff, but it just doesn't feel very... Python

#

And I know that sounds dumb and possibly snoody

#

But it just doesn't feel right from that context

flat gazelle
#

ye, probably would need some modification to fit into python

#

you cant just take the things as they are

full jay
#

Exactly

#

And I think it'd potentially end up a keyword which would kill it

#

Although with GvR out as BDFL, it's possible

#

I wouldn't have thought the Walrus would have gotten through previously

flat gazelle
#

and well, nothing stopping you from

pipe (2, 1 .__add__, 3 .__rpow__, 6 .__mul__, 3 .__truediv__)
full jay
#

Which objectively feels worse, at least to me, lak

flat gazelle
#

it is

wide shuttle
#

It's "easy" to implement something that behaves like it yourself (there are some packages for it already), but it's a non-standard solution

#

Which makes it unusual

flat gazelle
#

python help: occupied

grave jolt
#

!e

class Pipe: # Sorry, I'm breaking all possible guidelines for brevity
    def __init__(self, fn=lambda x: x): self.fn = fn
    def __call__(self, arg): return self.fn(arg)
    def __rshift__(self, f): return Pipe(lambda arg: f(self.fn(arg)))

pipe = Pipe() >> (lambda x: x*2) >> (lambda x: x+1)
print(pipe(4))
fallen slateBOT
#

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

9
full jay
#

I'm too slow today

#

Okay, I don't hate that, @grave jolt

spiral willow
#

that's rule 2 violation written all over it

full jay
#

But it still doesn't feel sincere

#

And by that I mean like... I don't know, just isn't very Pythonic. Which I know, it's a buzzword, but it's always had a very distinct style, and I feel like you start to lose that with piping

grave jolt
#

I agree.

#

I also hate functools.partial for some reason. Maybe because it's basically point-free style. I would rather use a lambda.

wide shuttle
#

I have the opposite

oblique crystal
#

Although with GvR out as BDFL
btw there are no one for CPython in BDFL now?

flat gazelle
#

well, the other option is with clojure style arrows

chain:
  5
  _ + 2
  _ * 3
  _ - 3
  print(_)
``` or sth
full jay
#

@oblique crystal I think the council makes the decisions as a whole now

oblique crystal
#

council?

full jay
#

I might be thinking of the wrong word..

wide shuttle
#

I dislike the overuse of lambda

slim island
#

I would absolutely love nicer lambdas in python

flat gazelle
#

it does look better in clj

(->
  5
  (+ 2)
  (* 3)
  (- 3)
  (System.out/println))
full jay
#

It shouldn't be removed, it serves a purpose

#

I just don't like bare values on their own line

#

That's always felt hinky to me

slim island
#

JS, Kotlin, and probably others do anonymous functions really well

#

and I feel like Python could

full jay
#

It's not really geared towards using those, though

grave jolt
#
-- Haskell
(+ 2) . (* 3) . (subtract 2) $ 5

Similar to closure

boreal umbra
#

what's wrong with lambdas, other than that they have to be one statement?

full jay
#

They're often used when they don't need to be

flat gazelle
#

wouldnt that do it in the opposite direction

slim island
#

I think it could be. Map in python is currently very ugly - map+lambda is very possibly more readable than list comps

#

and nicer to read than a more verbose for loop

full jay
#

What's the function I'm thinking of...

slim island
#

Right now it is

flat gazelle
#

I honestly cannot think of a language with less convenient lambdas than python

slim island
#

but it could server a purpose

flat gazelle
#

except like C

crystal pebble
#

C++

glass robin
#

reduce is also very seldom

crystal pebble
#

C++ lambdas are terrible

grave jolt
#

Well, C doesn't have lambdas unless you write some super-clever macro.

flat gazelle
#

reduce is actually pretty cool

slim island
#

map + multiline lambda would be nicer than a lot of potential list comps/gen exprs

boreal umbra
#

map(str, my_ints) is shorter than [str(i) for i in my_ints]

grave jolt
#

I wish there was a map or fmap method for lists that would return a list.

full jay
#

@slim island but at that point why wouldn't you just make a regular function

glass robin
#

^

crystal pebble
#

Stelercus: But wouldn't that just return a generator rather than a list?

flat gazelle
#

I have used reduce(lcm, (range(1, 21)) to solve one project euler question

full jay
#

reduce(), map(), and filter() all kind of get a bad rap

boreal umbra
#

@crystal pebble if you plan to use up the whole mapping within another expression, you don't necessarily need it to exist as a list

flat gazelle
#

also, arent C++ lamdas the same as java lambdas, just that you need to capture locals manually

full jay
#

They're not often used so people tend to think poorly of them, and when they are used they aren't typically used properly

slim island
#
map(iterable_thing, (it) -> {
    if it.isdigit():
        if int(it) > 10:
            'big'
    'not big'
})``` IMO that's nice than the equivalent list comp or normal function
full jay
#

But they do still serve purposes, and don't hurt anything by being in the language

boreal umbra
#

but I can't immediately think of a time when I'd use map outside of a larger statement.

full jay
#

@slim island I disagree, that feels much messier to me

flat gazelle
#

yes, but map is pretty nice for some things

sum(map(operator.mul, vec_a, vec_b))
slim island
#

why?

#

oh - I missed an else

peak spoke
#

the comprehensions/gen exps are more readable in 90% of the cases and that's all what python is about

slim island
#

it was there in my brain

#

something like that

peak spoke
#

you get to the lambda/functional territory which is not really python's way

flat gazelle
#

ye, python just does not do FP

#

which is a shame imo, FP is a very nice paradigm

slim island
#

the comprehensions/gen exps are more readable in 90% of the cases and that's all what python is about
If map is there, its going to be used. Using it is much nicer with decent lambdas than without

flat gazelle
#

ye, comps are better than map in pretty much all cases

slim island
#

currently - people fairly often abuse list comps and lambdas - that abuse could be turned into a reasonable use

full jay
#

I don't think moving it towards maps and longer lambdas is a more reasonable use, though

peak spoke
#

they are definitely overused at a loss of readability but the functional alternatives aren't better

oblique crystal
#

I think the main case when I use lambdas is for a key in sortin list of tuples for example

slim island
#

I think maps+lambdas are very readable though

oblique crystal
#

if I want to sort it with second element

gloomy locust
#

Hello everyone

full jay
#

Yo

undone hare
#

I think maps+lambdas are very readable though
It doesn't feel very pythonic though IMO

full jay
#

The most common usage (improper usage I mean) of lambda is for keys in sorting

#

There are much stronger tools already in the Python library that address that

peak spoke
#

well guido wanted them gone completely from python

slim island
#

It's not currently idiomatic. But I think it could be implemented in a way that is idiomatic

full jay
#

Sure but it feels like we're forcing it to be that

peak spoke
#

the lambdas are limited as a design choice

full jay
#

Instead of using the tools already at hand that serve those purposes

slim island
#

well guido wanted them gone completely from python
IMO completely ditching them, or "fixing" lambdas would be much better than just leaving them as this thing thats there and should never be used

#

Instead of using the tools already at hand that serve those purposes
Map is a tool that already exists - this is just adding utility to that tool.

full jay
#

But there is already utility built into the standard lib without having to expand what is supposed to be a basic tool

slim island
#

You can't remove lambdas entirely. They have too much random utility in things like sorting

full jay
#

I'm not in favor of taping a hammer to a screw driver just so it can "do more"

slim island
#

sorting and button clicks and the like

#

Changing all of those to not inline functions would be terrible

flat gazelle
#

ye, lambda is still useful for callbacks

full jay
#

And map is still useful for some efficiency cases

slim island
#

And map is still useful for some efficiency cases
where?

flat gazelle
#

in some cases

slim island
#

Where is map better than gen expr?

boreal umbra
#

I would oppose expanding lambdas if it caused curly braces to have another function.

slim island
#

@boreal umbra Could just use normal braces

#

or go for something super spicy and <>

full jay
#

Do I have to do the import braces thing?

#

Because they've already established that's not happening

flat gazelle
#

or do it the raku way

map (* + 5),(1,2,3,8)
``` /s
slim island
#

Nice lambdas work in almost every other language - I just don't see why they wouldn't in Python

full jay
#

@boreal umbra For some reason I was expecting something from "The Happening"

boreal umbra
#

I've never seen that

#

sounds like a horror film?

slim island
#

I don't buy into the Python exceptionalism argument

glass robin
#

there was a fancy package named after Guido who overwrite <>, isn't it?

oblique crystal
#

The most common usage (improper usage I mean) of lambda is for keys in sorting
There are much stronger tools already in the Python library that address that
tools like?.. @full jay

flat gazelle
#

the operator module

full jay
#

Hold on, gotta find it again...

#

That

#

That one

#

Thank you lak, that was going to take me a while

slim island
#

Operator isn't necessarily better than lambdas

#

lambdas are more intuitive

#

to non python people

full jay
#

You hit the nail on the head there, Charlie

boreal umbra
#

But we hate those people

undone hare
full jay
#

You're trying to bring in sensibilities from other languages to Python

slim island
#

@full jay There's no reason why Python should do it differently though

full jay
#

That's the issue

slim island
#

lambdas for itemgetters are perfectly readable

#

and more editable

full jay
#

But not faster

#

And not Pythonic in the greater scheme of things

undone hare
#

Lambdas are faster than itemgetter for sure

slim island
#

what about them is not idiomatic?

full jay
#

lambdas end up being out of place in the broader code base

#

@undone hare Other way around

undone hare
#

? nope

full jay
#

Yep

slim island
#

You can always test it

full jay
#

itemgetter is optimized for the task

flat gazelle
#

TL:DR python is bad at functional programming and it is not really a problem

slim island
#

and I'd be curious to see

grave jolt
#

!e

from __future__ import braces

print(*map(
  lambda x: {
      y = x * 2
      return y + 1
  },
  [1, 2, 3, 4, 5, 6, 7, 8]
))
fallen slateBOT
#

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

3 5 7 9 11 13 15 17
full jay
#

Wait what?

flat gazelle
#

nice

full jay
#

I thought braces threw a joke error

undone hare
#

Itemgetter is a function call that creates a new function inside another namespace that needs to be keep, and returns that function, as a lambda is just a plain function

slim island
#

Just because its bad now - doesn't mean it couldn't be OK. Lambdas exist, they could be nice, and they could also become idiomatic

north root
#

what

undone hare
#

Man..

flat gazelle
#

was nekits thing added to that bot

peak spoke
#

an itemgetter is also more powerful than a lambda

slim island
#

how so?

full jay
#

But you're forcing a fundamental change in how the language is meant to be used

undone hare
#

Nekit made braces in python yep

full jay
#

Ah, knew it

peak spoke
#

in simple cases you really don't care about the speed differences that would create

undone hare
#

But @grave jolt just edited their code haha

flat gazelle
#

ah, makes sense

grave jolt
#

!e

# also a classic one
Truะต = False
print(Truะต)
fallen slateBOT
#

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

False
flat gazelle
#

a language cannot just change its paradigms

slim island
#

I think Python people have a tendency to get hyperfocused on doing things the python way. Something like Lambdas are a general concept that works well everywhere else - so why not in Python? The only argument I see is that they're "unpythonic" which just seems like a truism, but I don't see why they couldn't become pythonic if they were made nice

glass robin
#

python4 hehe

#

becoming a FL

undone hare
#

Unicode support haha

grave jolt
#

Fython

full jay
#

I have yet to see an example of it being nicer or cleaned up, though

flat gazelle
#

like dogelang but worse

oblique crystal
#

ok so it's itemgetter that we use instead of lambdas for key sorting?

full jay
#

Also I don't particularly see an issue with a language focusing on a specific paradigm

#

Yep, Loss

undone hare
#

There are 421 lambdas in the cpython source code, can we all say that they have fair use cases?

slim island
#

JS shows that major changes to a language can work and can be an improvement. Python is obviously not in the shitty place that JS was - but that doesn't mean Python couldn't improve

oblique crystal
#

cool need not to forget it

full jay
#

And again, I don't see how throwing extra lambda stuff into the mix makes it an improvement

#

The only argument you've given to it is that other languages do it

slim island
#

I have yet to see an example of it being nicer or cleaned up, though
IMO thats because you're too focused on what is currently good python. What is currently good python could be broadened out to be more inline with good programming in general.

flat gazelle
#

I would say the improvement should not be introducing FP, but rather some some sort of switch/given/when expression, more powerful unpacking and such

slim island
#

And again, I don't see how throwing extra lambda stuff into the mix makes it an improvement
More tools to write clean code. Maps in every other language are nice - I don't see why they couldn't be in Python

fresh warren
#

Is there a way to mimic this wrapper function structure without using the @function notation on the function to be wrapped

def wrapper(f1):
def g():
print('before f')
f();
print('after f')
return g

@wrapper
def my_func():
print('running func')

def main():
my_func();

if 'name' = 'main':main()

peak spoke
#

there are uses for lambdas for keys etc. and operator does maybe offers a bit too much wrapping around basic code but I still think it's more readable than the same lambda

glass robin
#

inline programming is in its essence unpythonic IMO, list comprehension excluded

molten onyx
#

Python is very very likely getting a match statement because of the introduction of their new parser

full jay
#

That I'm okay with

slim island
#

It doesn't replace it in the case of even 3 line functions @unkempt rock

glass robin
#

matching is powerful

full jay
#

Just make a damn function then!

#

Seriously, why does it have to be a lambda?

flat gazelle
#

wait, python is likely getting pattern matching?

molten onyx
#

a language cannot just change its paradigms
Python doesn't really have a "paradigm"

full jay
#

There's literally no reason it needs to be one if it's like that

undone hare
#

That would take some memory for nothing :>

flat gazelle
#

yes it does, it does imperative, procedural and OOP well

slim island
#

There's no need to make it a full function. A 3 line anonymous function is perfectly readable

#

I don't see why its so scary

undone hare
#

It can support paradigms, but not be a paradigm

boreal umbra
#

@flat gazelle I don't think python is as married to a particular paradigm as, say, Java is to OOP.

molten onyx
#

it also does functional, declarative and structured programming

full jay
#

It's not a matter of scary, it just goes against existing code bases and would hurt over all readability. You've mentioned that it could be made to integrate well but have not given anything that could act as such

molten onyx
#

Python is not tied to any paradigm

glass robin
#

pattern matching would need custom types

flat gazelle
#

python intentionally makes it hard to make complex expressions

slim island
#

@unkempt rock an example of what?

boreal umbra
#

I think Python makes it easy to make expressions that could look at lot more complicated

full jay
#

How a lambda could be just as readable (if not more so) than just making a 3 line function

boreal umbra
#

but I don't know that it makes it hard to make unreadable code.

slim island
#

where map is not replacable by comprehension
In some circumstances, its only replacable by defining a function

#

where an anonymous function would be fine

full jay
#

Fine based on the standards of other languages

peak spoke
#

I'd rather have a function for something big rather than separating out the lambda in the call

full jay
#

Rather than the ones that this particular language tends to go by

#

I don't think it's unfair to try and keep that style as is

slim island
#

why is python different? every language strives to be maintainable

#

Explicit > implicit

molten onyx
#

except perl

full jay
#

It IS maintainable! How is adding longer lambdas going to make it more maintainable?

#

You're making 0 sense on that front

slim island
#

Yes - my point is why is python different?

undone hare
#

Everything in the place it is used

slim island
#

JS/Kotlin/More have nice lambdas. They're all readable

full jay
#

Good for them

#

Like I don't get your point that Python should because others do

slim island
#

So why would lambdas in python be unreadable?

full jay
#

It doesn't need them

undone hare
#

Kotlin's lambdas are lemon_pika

slim island
#

ofc it doesn't need them

#

they would just be nice

#

as another tool

#

to define cleaner code

full jay
#

It doesn't make cleaner code

slim island
#

its easier to parse an inline function if its being used in one place as a map

#

than having to look at two separate places

full jay
#

I'm getting a migraine from this

#

Legitimately

gloomy rain
#

@full jay Maybe take a break.

peak spoke
#

going from your example above

map(iterable_thing, (it) -> {
    if it.isdigit():
        if int(it) > 10:
            'big'
    'not big'
})

I don't see this as very readable

slim island
#

A map or a list comp

peak spoke
#

you separate it whole anyway, so why not a function?

molten onyx
#

Multiline lambdas would be nice as cramming things into one expression makes certain logic extremely difficult.

gloomy rain
#

Language design isn't really a big deal.

glass robin
#

The only lambdas I use in TS could be regular function as well

molten onyx
#

...that is what a lambda is?

flat gazelle
#

it is not as simple as "make a nice lambda syntax" to improve the language

gloomy rain
#

There are certainly a lot of other Python language constructs, such as comprehensions, which reduce the necessity for anonymous functions.

flat gazelle
#

it is not a small change for very little gain unless you give other tools along with it

unkempt rock
#

hello

gloomy rain
#

Not saying that they can't still be useful, but there are way fewer use cases for them.

molten onyx
#

You can argue this same point for :=, which is now seemingly permanently in the language

slim island
#

@gloomy rain But there are also constructs that could benefit from them. There are cases where a map+anony function would be more readable than list comps. Map exists, people are going to use it, they should be able to use it nicely

glass robin
#
/*No point of making a lambda here, but it's how it's used in TS */
my_lambda => (c: string) {
    if c == "Foo": "bar"
}
unkempt rock
#

tรผrk varmฤฑ tรผrk

gloomy rain
#

@slim island It's just going to be less of a priority for language designers if there are other nice solutions to the same problems.

slim island
#

Yeah sure - I'm not even necessarily saying this is something that 100% needs to be done, there are very probably higher priority things. I'm just saying I think this is a feature that would improve the language if it existed. It wouldn't magically make python unpythonic

unkempt rock
#

hey @rotund mural

#

burdayฤฑz reis

molten onyx
#

It's not

flat gazelle
#

honestly, the only thing I use map for is instead of (fun(*a) for a in zip(u, v, w, x))

gloomy rain
#

@slim island You could also argue that given that there is one nice way to solve a certain problem, there is value in discouraging people from solving the same problem in 5 other ways. It's easier to learn one way rather than five, and codebases will become more regular, structured and predictable.

whole glacier
#

map is great lol

full jay
#

That's part of the Zen of Python

molten onyx
#

You cannot pass comprehensions around in the same fashion you can map

full jay
#

The whole "There should be ideally only one solution" or something like that

glass robin
#

I don't feel it's really python philosophy @gloomy rain

flat gazelle
#

!zen one

fallen slateBOT
#
The Zen of Python (line 12):

There should be one-- and preferably only one --obvious way to do it.

full jay
#

That

molten onyx
#

In addition, you will need to use generator comprehensions for the lazy evaluation

slim island
#
def func_for_list_comp(thing):
    # a line
    # another line
    # a third line with a return
[func_for_list_comp(it) for it in iterable]

map(iterable, (it) -> {
    # a line
    # another line
    # a third line with a return
}
flat gazelle
#

it kind of fails in a lot of cases

slim island
#

IMO the second is nicer to read

#

Its a common construct in a lot of other languages

full jay
#

@flat gazelle The command you mean?

slim island
#

and its good to be generally idiomatic with other languages

flat gazelle
#

no, that line of the zen

full jay
#

Ah right

slim island
#

@unkempt rock the third alternative is a normal for loop and apending to a list, or a function that yields or something

flat gazelle
#

ye, why not just use generators there?

gloomy rain
#

I kinda prefer the first one, personally. It encourages the use of abstractions.

glass robin
#

it kind of fails in a lot of cases

I agree. I didn't remember this line, but reading various python code it doesn't feel this way

gloomy rain
#

Otherwise you have the implementation of the thing you are doing to the list right in the middle of the call.

#

If you give it a descriptive name, it's more readable.

#

And easier to swap out, too.

slim island
#

sure - replace the [] with () - and the code is practically the same. I think some functions are so inherently tied to the thing they're iterating over, that naming it is less readable

#

Some functions are never going to be reusable or don't even want to try to be reusable

flat gazelle
#

thing is, kotlin/java can do it well because it calls it infix like

someList.map { a -> a + 2}
gloomy rain
#

Comprehensions cover a large part of the use cases of functional calls like map and filter, etc.

#

And they are pretty intuitive.

flat gazelle
#

so it can be long, because there is no additional information after it, at most another step in the chain

slim island
#

Using anonymous functions over named functions means you can know that you can edit it as it isn't being used anywhere else

flat gazelle
#

when you have the other way around, it gets harder to parse out what is going on

gloomy rain
#

Well, worst case, you could do a nested function.

flat gazelle
#

haskell actually has the same problem, which is why you see <$> over map and fmap

slim island
#

Yea, I agree having map be a function rather than a method is much less readable

wintry cave
#

do imported functions act as classes, so that if you imported foo, which had a variable bar, you'd be able to call foo.bar?

boreal umbra
#

@wintry cave you can't access objects defined inside of a function with the dot operator, no.

#

in order for that behavior to be supported, the function would have to know how to expose which objects aren't dependent on the parameters that get passed to it, I would think.

#

But you can get similar behavior by creating a class that implements __call__

#

@gusty solar this isn't a help channel, but the split method for strings will split each string into a list of strings based on whitespace

#

or you can specify a delimiter. .split(", ")

flat gazelle
#

your best bet it probably a generator

gusty solar
#

okay thx, lemme switch ti correct channel

deft pagoda
#

you can use peekable from more_itertools to make a clean generator

boreal umbra
#

when is someone going to make all_the_itertools?

#

I want an iterator that only goes back and forth between the first two items, no matter how many possible items there are.

flat gazelle
#

you can do that by doing islice and cycle

boreal umbra
#

yeah but

wide shuttle
#

There's always even_more_itertools

willow shore
#

hmm... so now that I have my classes inherit from an abstract class to kinda mimic interfaces, should I then assert that these child classes I'm importing are actually inheriting from the correct abstract class?

#

would that be something people do or is that taking it too far

oblique crystal
#

There's always even_more_itertools
@wide shuttle you're kidding right? I know of more_itertools but never ever saw/heard/found on google even_more

primal magnet
#

lol I've yet to explore the base, itertools

boreal umbra
#

@whole obsidian You can't use this server as a platform for paid services, and I see you're charging a subscription fee.

whole obsidian
#

i'm not

#

i'm asking what people think to the features on my project

#

it's not even released yet @boreal umbra

spiral willow
#

that I'm not paying for them

boreal umbra
#

This looks like a list of relatively unrelated tools

rugged crypt
#

@whole obsidian hi, why is it supports windows 8 above not windows 7?

whole obsidian
#

but not necessarily useless

#

and they're categorised

boreal umbra
#

making them is probably worthwhile just to learn what goes into it.

whole obsidian
#

@rugged crypt because i've not tested it for windows 7

boreal umbra
#

but there are probably robust open-source solutions for all the things this does

whole obsidian
#

yeah, individual solutions

#

not an all in one

full jay
#

I removed the link. As Stelercus said, we'll happily link projects that are open-source, but not paid ones. Or if they are paid, we've tested them ourselves and find them worth suggesting to our users

spiral willow
#

I got CSV to JSON conversion right here: powershell Get-Content .\File.txt | ConvertFrom-CSV | ConvertTo-JSON | Out-File .\file.json

whole obsidian
#

would you want to test it @full jay ?

rugged crypt
#

@whole obsidian they are many people using Windows 7 that's why I asked!

spiral willow
#

Windows 7 is EOL unless you paid for support

whole obsidian
#

well they shouldn't because it's unsupported

full jay
#

At the moment, not in particular. I've got a massive project to tackle here at work. But these aren't the kind of things we would link to.

worldly venture
#

@whole obsidian they are separate tools for a reason though

whole obsidian
#

why not? what sort of things would you link to?

full jay
#

The only paid services we would consider linking to or suggesting are learning materials, not various tools

whole obsidian
#

oh

#

learning tools xd

#

jk

worldly venture
#

say I'm writing some stuff for a microservice which handles image uploads, why would I want audio, password, hashing, text, math tools

full jay
#

We're an education server first and foremost, not an ad page

whole obsidian
#

but they make learning easier... faster

worldly venture
#

putting things together is more scope bloat

spiral willow
#

and most of those "tools" are couple of lines of python

worldly venture
#

Simple is better than complex.

whole obsidian
#

it's simple to navigate :D

full jay
#

If these were open-source projects and you had the code shown for them and what have (and it got put in the right channel) then I wouldn't care

#

Buuuuuuut

whole obsidian
#

i am happy to make it free--- paid was just an idea

deft pagoda
#

More complex is more than complex.

boreal umbra
#

I hope this hasn't discouraged you from learning more about programming and trying to make a living doing it.

full jay
#

In that case you are free to check out the channel description for #303934982764625920 and post your project there so long as it follows those requirements

whole obsidian
#

this is a big rip

spiral willow
#

If you want to make swiss army knife python library, that's fine

boreal umbra
#

Though most of the functionality you're offering are already built into the language.

whole obsidian
#

i didn't make it for my own benefit

#

i made it for others

full jay
#

And there's plenty of places where you can offer that kind of thing

#

But if it's here, we just have rules about it

unkempt rock
#

witch python software do u guys use?

#

i use pycharm

whole obsidian
#

ok

boreal umbra
#

@unkempt rock PyCharm is an IDE. It's the one that I use most of the time

true ridge
boreal umbra
#

but that isn't what "python software" is per se.

unkempt rock
#

ik thats wut i mean @boreal umbra

spiral willow
#

Pycharm/VS Code are two most popular editors/IDE in most Surveys

unkempt rock
#

im working on a choose your own adventure game

whole obsidian
#

It would be better if you said

#

IDE/editors

boreal umbra
#

PyCharm is the only IDE I've used extensively, but it helps me a lot with debugging and connecting to the remote machines where most of my code gets executed.

#

it might be that VSC can do those two things just as well

unkempt rock
#

i agree

#

im still learning the language though

deft pagoda
#

depressingly ot

boreal umbra
#

depressingly ot?

whole obsidian
#

what do u guys make that's useful

boreal umbra
#

who said any of us made useful stuff?

true ridge
#

This isn't the right channel to dicuss it @whole obsidian

whole obsidian
#

so you make useless stuff?

deft pagoda
whole obsidian
#

your github profile layout is strange

#

also what does it do

deft pagoda
#
In [202]: past("""
     ...: for i in range(5):
     ...:     print(i)
     ...: """)
For
โ”œโ”€โ”€Name
โ”‚  โ”œโ”€โ”€i
โ”‚  โ•ฐโ”€โ”€Store
โ”œโ”€โ”€Call
โ”‚  โ”œโ”€โ”€Name
โ”‚  โ”‚  โ”œโ”€โ”€range
โ”‚  โ”‚  โ•ฐโ”€โ”€Load
โ”‚  โ•ฐโ”€โ”€Constant
โ”‚     โ•ฐโ”€โ”€5
โ•ฐโ”€โ”€Expr
   โ•ฐโ”€โ”€Call
      โ”œโ”€โ”€Name
      โ”‚  โ”œโ”€โ”€print
      โ”‚  โ•ฐโ”€โ”€Load
      โ•ฐโ”€โ”€Name
         โ”œโ”€โ”€i
         โ•ฐโ”€โ”€Load
whole obsidian
#

Oh

#

I see

flat gazelle
#

โ•ฐ there are some wack characters out there

#

do you have some website where these are listed? I generally just use -| and + corners, but these would look nicer

deft pagoda
#

i search for 'box drawing unicode'

flat gazelle
#

makes sense

oblique crystal
#

you also have some graphvis tool?

hasty thistle
#

the wikipedia article has some good box drawing chars

whole obsidian
#

Yeah, what is ยฆ

#

And ยฌ

lost nexus
#

what are some common usages of bitwise operators?

charred wagon
#

With enums

#

If you want to set multiple flags, you can OR them together

boreal umbra
#

Huh, I didn't know that's what re constants were doing

#

Also, the | and & operators are really useful for sets.

#

You can also make a class that makes << and >> do the same thing as C++-style string concatenation

peak spoke
#

sets have a lot of useful operators

boreal umbra
#

But don't do that

north root
#

bitwise operators are useful using numpy as well

deft pagoda
#

i've used << to add things to a queue

boreal umbra
#

oh that would be interesting

#

what if << could append to a list?

deft pagoda
#
myqueue << item
#

you could reverse it to pull from a queue

#

myqueue >> item

peak spoke
#

liked the |= operator when I needed it

boreal umbra
#

Speaking of operators in numpy, I don't think you can use | to concatenate matrices. I really want that.

#

At least I did want that when I was taking linear algebra. Which I will never have to do again.

restive wagon
#

hello hope you're doing ok , I just have a question which is : from where to start programming with python?
hope you answer my question

boreal umbra
#

print("Hello world!")

flat gazelle
#

!resources

fallen slateBOT
#
Resources

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

flat gazelle
#

see here B2W

restive wagon
#

thank you mate

boreal umbra
#

Though a potential problem with using my_list << some_thing to do append

#

it would be a mutation, and the convention is that infix operators should return a new thing

flat gazelle
#

my_list <<= some_thing

boreal umbra
#

oh nice

#

though new language users might not recognize that it's the same format as += and think it's a a weird arrow thing?

deft pagoda
#

queues are mutable, so doesn't really matter

boreal umbra
#

right, but generally speaking, aren't infix operators supposed to create a new object without messing with either operand?

lost nexus
#

You can also make a class that makes << and >> do the same thing as C++-style string concatenation
what like 'hello' << ' world'?

boreal umbra
#

something like that, yes

#

I saw someone make a class so that you could have print << 'hello' << ' world'

#

and the top comment was "Thanks, I hate it"

lost nexus
#

heh that's cool

#

my_list <<= some_thing
@flat gazelle in this case, what type would some_thing need to be?

boreal umbra
#

it could be anything

flat gazelle
#

you would have to override <<= on some class

lost nexus
#

I see

boreal umbra
#
class superlist(list):

    def __ilshift__(self, other):
        self.append(other)

lost nexus
#

this is cool. im definitely going to mess with this

boreal umbra
#

but if you wanted to be consistent

#
class superlist(list):

    def __ilshift__(self, other):
        self.append(other)

    def __lshift__(self, other):
        return self.copy().append(other)
#

not exactly ideal

deft pagoda
#
from collections import deque

class Deque(deque):
    def __rshift__(self, other):
        return other.appendleft(self.pop())

    def __lshift__(self, other):
        if isinstance(other, deque):
            return self.append(other.popleft())
        return self.append(other)

    def __rrshift__(self, other):
        if isinstance(other, deque):
            return self.appendleft(self.popleft())
        return self.appendleft(other)

    def __rlshift__(self, other):
        return other.append(self.popleft())
boreal umbra
#

lol __rlshift__ is a thing

deft pagoda
#
In [231]: a = Deque(); b = Deque()
     ...: a << 1
     ...: a << 2
     ...: a << 3
     ...: a
Out[231]: Deque([1, 2, 3])

In [232]: b << a; a >> b; print(a, b)
Deque([2]) Deque([3, 1])
boreal umbra
#

Speaking of which

#

does the stlib not have a queue data type with O(1) pop operations?

deft pagoda
#

thats above

boreal umbra
#

that's part of the stdlib?

deft pagoda
#

yes

boreal umbra
#

๐Ÿ˜ฎ

deft pagoda
#

collections is stdlib

#

you should memorize the whole of collections, it's all magic

boreal umbra
#

okay, I'll go get some blank flashcards.

peak spoke
#

and itertools

deft pagoda
#

itertools too, but i find collections more magical

#

everytime i import ChainMap

#

or defaultdict

#

also, collections.abc is real dope

peak spoke
#

also good to skim the abcs to know what's what in python

deft pagoda
#

tbf, the UserList, etc stuff is basically deprecated -- also, OrderedDict

#

and typing NamedTuple and dataclasses maybe supplant collections namedtuple

peak spoke
#

I use it in one of my projects

boreal umbra
#

I see, deque does everything a queue or a stack would do.

deft pagoda
#

double-ended queue is what it stands for

north root
#

double ended que-

#

yep

boreal umbra
#

lol

#

I suppose the idea is that __getitem__ is usually O(1) for list, but O(n) for pop(0)?

deft pagoda
#

yeah, popleft is O(1) on a deque

boreal umbra
#

so it must be a linked list internally

deft pagoda
#

it's, i think it's more sophisticated

#

i can't remember details about it

boreal umbra
#

doubly-linked list?

#

maybe it could even dynamically create references to other nodes in the middle as it grows and shrinks, and then keep track of what their indices are as the list changes.

#

then you have O(n) lookups, with some divisor.

deft pagoda
#

yeah, doubly-linked something something

#

slow lookups in the middle

#

comes with a rotate though

#

i gave a demo with my kivy console

oblique crystal
#

defaultdic is my fav

deft pagoda
boreal umbra
#

nice lol

deft pagoda
#

i think i use defaultdict the most

boreal umbra
#

there doesn't appear to be a more_collections module on pypi

#

oh there is

deft pagoda
#

i have a couple of classes that might qualify

#

cyclic tuples and set with choice

oblique crystal
#

I used in past ordereddict

#

but now it is pointless

deft pagoda
#

yeah, its mostly deprecated

oblique crystal
#

unless needs backward compatibility

boreal umbra
#

Is "remembering insert order" actually part of the specification of dict now?

oblique crystal
#

I wonder why it is defaultdict and not DefaultDict

#

like other collections elements

deft pagoda
#

historic reasons

oblique crystal
#

Is "remembering insert order" actually part of the specification of dict now?
yes

boreal umbra
#

I thought it was just a side effect of how they implemented it in cpython

#

and that it's not guaranteed in other implementations.

oblique crystal
#

it was as of 3.6-3.7 I think

deft pagoda
#

dicts ordered since 3.6

oblique crystal
#

or 3.5

boreal umbra
#

ah

oblique crystal
#

and since 3.7 it is assured

boreal umbra
#

cool

fresh warren
#

whats the best python ide for web dev

slim island
#

Pycharm probably

boreal umbra
#

PyCharm

deft pagoda
#

that's off-topic here

coral geyser
#

hi im new here

slim island
fresh warren
#

oh okay thanks

deft pagoda
boreal umbra
coral geyser
#

thanks

boreal umbra
#

unless you wanted to talk about language specifics, which you're more than welcome to.

slim island
#

Is there a reason ordered dict still exists beyond backwards compatibility? Or does it have some extra features?

oblique crystal
#

@boreal umbra they eve say this above one of collections

peak spoke
#

you get some more pos manipulation from it iirc

deft pagoda
#

yeah, there's some reason to use it, but i don't remember it

peak spoke
#

you can pop and move keys to either end

molten onyx
#

@slim island the == operator behaves differently as it does not disregard order

slim island
#

Ah - I guess thats a pretty big thing actually

molten onyx
#

which is why ordered dict is in use for e.g. Signature objects

#

yeah it is

deft pagoda
#

!e

from inspect import signature
from textwrap import dedent

def parse_signature(signature):
    return str(signature)[1:-1].split(', ', 1)[1]

class Person:
    def __init__(self, name): self.name = name

    def __init_subclass__(cls):
        def deco(func):
            child_args = parse_signature(signature(func))
            self_args = parse_signature(signature(cls.__base__.__init__))
            all_args = f'{self_args}, {child_args}'

            globals_ = {'func': func, 'cls':cls}
            locals_ = {}
            wrapper = f"""
            def wrapper(self, {all_args}):
                super(cls, self).__init__({self_args})
                return func(self, {child_args})"""
            exec(dedent(wrapper), globals_, locals_)

            return locals_['wrapper']

        cls.__init__ = deco(cls.__init__)

    def __repr__(self):
        args = parse_signature(signature(type(self).__init__)).split(', ')
        args = ', '.join(f'{arg}={repr(getattr(self, arg))}' for arg in args)
        return f'{type(self).__name__}({args})'

class Cyborg(Person):
    def __init__(self, version): self.version = version

class Android(Cyborg):
    def __init__(self, model): self.model = model

print(signature(Android))
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

(name, version, model)
deft pagoda
#

there we go

#

the inits are added together

#

and same with the signatures

oblique crystal
#

if there is one thing I don't like about this channel is that now I want to hang around it a lot lol

boreal umbra
#

yeah, I've been less productive

#

but I'm learning so much ๐Ÿ˜ฎ

oblique crystal
#

I think I made already 3 bm's with seasonalbot here

boreal umbra
#

bm's?

#

is that what I think it means?

deft pagoda
#

beast modes

oblique crystal
#

bookmarks

#

.bm

#

idk what you thought it means ๐Ÿ™‚

boreal umbra
#

good

echo blade
#

I really wanna work through Fluent Python, but I'm conflicted because the 2nd edition comes out in 6 months! I'd like to make the most use of my time, and I think that would be best spent getting up-to date information, though I know the first edition will still have so much to offer.

shy vine
#

It's not that dated

whole obsidian
#

what should i code - that's useful

boreal umbra
#

Savage

sturdy timber
boreal umbra
#

Oh, python news has a feed from the email forum?

sturdy timber
#

Yep, it's the first one in the channel

boreal umbra
#

Oh cool

peak spoke
#

oh just noticed pprint now allows disabling its dict sorting

trail swift
#
if asking_how_to_make_this_colored:
  print("Tell me how")
else:
  print("PLEASE")```
peak spoke
#

Not really suited to this channel but you can add py or python after the first 3 backticks

golden imp
#

is it possible to express using type hints that the return type is the same type as the argument?

flat gazelle
#

TypeVar is probably what you want

golden imp
#

ok, let me try that

flat gazelle
#
T = TypeVar('T')
def repeat(x: T, n: int) -> Sequence[T]:
    """Return a list containing n references to x."""
    return [x]*n
golden imp
#

bleh, apparently pycharm isn't smart enough to pick up on this

#

maybe mypy will

#

oh actually pycharm sort of can

unkempt rock
#

from pprint import pprint as pp is my goto dev line to put in every file and eventually remove.

peak spoke
#

I don't really use it that much in files as the things where I print usually end up in the repl when prototyping

flat gazelle
#

I generally just print things normally

unkempt rock
#

if I have dicts of any complexity i baiscally need it

#

or I wont see things as they are.

flat gazelle
#

ye, for that is would probably nice

wide shuttle
#

I'm slowly developing the habit to use logging, even for smaller projects, as I like the way you can configure the logging levels

unkempt rock
#

Its mainly a shell uisage thing

flat gazelle
#

I generally do not work with that

peak spoke
#

It's nice but also takes up a lot of space for longer lists/dicts

unkempt rock
#

I really only ever use it to get a general idea of what im looking at if its not very human readable otherwise.

#

But that seems to be pretty often especially when I work with loaded in json that is nested deep a million miles

flat gazelle
#

ye, I just do not work with that kind of JSON. If I ever end up with lotta JSON, I will be sure to use pprint, that is a good idea

unkempt rock
#

usually it happens when Im trying to access something and I get like, "Blah blah not subscriptable"

#

That tells me that there is soemthing about the data structure that i cant see because its not printed in a nice way

#

pprint usualy just makes it immediately obvious

#

but yeah

oblique crystal
#

I'm slowly developing the habit to use logging, even for smaller projects, as I like the way you can configure the logging levels
@wide shuttle do you just format and create it by hand writing things to file and foramting as you please? Or you use some tool/lib?

wide shuttle
#

I'm mainly using the built-in logging module. It does everything I need.

#

For our community projects, we use Sentry integration for errors and the like

#

Which is amazing

oblique crystal
#

cool. I should take a look at those

fossil pumice
#

Sentry is ๐Ÿ‘Œ

gray mirage
#

I use Sentry as well and it's pretty baller

narrow kettle
#

what does it offer over default logging

oblique crystal
#

but it's not free it seems? unless you do it alone for yourself?

novel nacelle
#

ok hi

#

im new

#

uh

#

wait

#

is this the channel for learning the language

primal badge
#

idk

#

I am new as well

civic briar
#

Me too

limpid iron
#

#python-discussion or a Help channel. You should probably only answer if you know the answer, not continuously echo "Me too".

spare current
#

I am also new

true ridge
#

No, this is not

north root
#

welcome you four

#

we have lots of resources to learn from here

#

!resources

fallen slateBOT
#
Resources

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

north root
#

many recommend Automate the Boring Stuff from that list

remote matrix
#

ABS is great for getting syntax under you and understanding the basic structures of Python imo

#

you pretty much can't get through the book without memorizing syntax basically

narrow kettle
#

its what i recommend to coworkers on thebuisness side of things that arent looking to become devs but rather make parts of their day easier

remote matrix
#

yep, totally fair reason to use Python is just simply automating stuff around your pc

echo blade
#

I'd recommend Python Crash Course over Automate the Boring Stuff. Having done both cover-to-cover, automate takes a "just works" approach that doesn't put much concern on writing clean code. The first half of Python Crash Course + the 2nd half of Automate the Boring Stuff is a much nicer combo.

limpid iron
#

I don't think this channel is being used for it's intended purpose.

true ridge
#

Yes @limpid iron, unfortunately it is not :/

limpid iron
#

No... not at all.

oblique crystal
#

naah, for better part of the day this channel had good stuff

shy vine
#

It's a little silly to make sweeping pronouncements based on 20 minutes of conversation. No channel is ever going to be 100% on topic. If you feel it's getting out of hand that's why we have moderators.

unkempt rock
#

I'd recommend Python Crash Course over Automate the Boring Stuff. Having done both cover-to-cover, automate takes a "just works" approach that doesn't put much concern on writing clean code. The first half of Python Crash Course + the 2nd half of Automate the Boring Stuff is a much nicer combo.
@echo blade I have to agree about this. Automate is good for the person who really is picking this up while working at their unrelated to software job, for the purposes of quickly making productive enhancements with no emphasis on software engineering. I dont think there is anything wrong with that, but its best to know that.

#

I havent read PCC though

modern hound
#

Hey, I recently got started with Python, however I've been using a website to code. What do yall use to code python in?

remote matrix
#

Visual Studio Code is gonna be the most popular probably

#

it's free and easy to get started with

winter yarrow
#

I agree, VS Code is my suggestion. Pycharm is also good.

wide magnet
#

you dont recommend sublime ?

#

Sorry for my english.

north root
#

this discussion should be in #tools-and-devops instead, but i use vs code and sublime text

cobalt egret
#

Hey everyone! Rolling off of @modern hound's question, I've also recently began learning a bit of python to expand my skill set, and was wondering what tools/websites you all have used that have been effective in practical learning?

north root
#

we also have the rest of our resources here

#

!resources

fallen slateBOT
#
Resources

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

north root
#

something important that not too many beginners know of is PEP8, the Python style guide. it describes and explains the conventions of Python code.

#

!pep 8

fallen slateBOT
#
**PEP 8 - Style Guide for Python Code**
Status

Active

Created

05-Jul-2001

Type

Process

boreal umbra
#

You know, I've pretty much completely forgotten that % can be used for string formatting.

north root
#

i'm reminded of it everytime i use C

boreal umbra
#

Why do you use C, unless you're building Python modules?

north root
#

i don't use C often. before i used C because i was taking a course that used it. now, i just mess around with C occasionally

boreal umbra
#

ah

#

I took a C class last semester

#

I have to make an operating system emulator during my last semester next year, and I might do that in C

#

I hope not

north root
#

ah systems programming is not so fun

boreal umbra
#

Linus Torvalds might beg to differ

#

But he's weird. Glad he does his stuff though.

north root
#

his quotes are great

boreal umbra
#

there are quite a few

#

he said that Microsoft writes crappy operating systems. Windows is certainly not great if you're a developer, but doesn't it achieve its own goals pretty well?

#

My personal computer (I have a separate work computer) is Windows, and I have to jump through lots of hoops to pretend it's linux.

north root
#

yeah windows is just fine for non-devs for the most part

#

i've realized we're not in an off-topic channel lol

boreal umbra
#

I mean... operating systems?

#

If someone wants to talk about the language we can move.

north root
#

fair enough

boreal umbra
#

I guess.

#

For a while I was into gaming. But I haven't really had time to for a while

#

And Windows is the place to be for that.

north root
#

yeah, i used to game quite a bit, so windows was great for that. i have less time for that nowadays though and i code a lot more, so linux is a much better experience for me. i still use windows for office, photoshop, video editing, etc. though

boreal umbra
#

oh cool

#

what videos do you make?

north root
#

lol i used to make frag movies for csgo, but now i just make videos for some school assignments

boreal umbra
#

I've thought about starting a youtube channel for algorithm ASMR

#

so I explain how different algorithms work, but it's mostly ASMR

#

I figure both genres have been done to death, so I'd have to offer an intersection if I wanted to corner the market.

unkempt rock
#

signals electrical shock collars pypeek

boreal umbra
#

why

north root
#

that's an interesting combination

cobalt egret
#

@north root Awesome! Thanks for the links!

north root
#

no problem!

deft pagoda
#

here's some more fun with the queue idea:

#

!e

from collections import deque

class Deque(deque):
    def __rshift__(self, other):
        other.appendleft(self.pop())
        return other

    def __lshift__(self, other):
        if isinstance(other, deque):
            self.append(other.popleft())
            return other
        self.append(other)
        return self

    def __rrshift__(self, other):
        if isinstance(other, deque):
            self.appendleft(self.popleft())
            return other
        self.appendleft(other)
        return self

    def __rlshift__(self, other):
        other.append(self.popleft())
        return other

a, b, c = (Deque() for _ in range(3))

a << 1 << 2 << 3
b << 4 << 5 << 6
c << 7 << 8 << 9

print(a, b, c)

a >> b >> c

print(a, b, c)

a >> b << c

print(a, b, c)
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

001 | Deque([1, 2, 3]) Deque([4, 5, 6]) Deque([7, 8, 9])
002 | Deque([1, 2]) Deque([3, 4, 5]) Deque([6, 7, 8, 9])
003 | Deque([1]) Deque([2, 3, 4, 5, 6]) Deque([7, 8, 9])
deft pagoda
#

where a >> b takes the rightmost item of a and places it on the left side of b

#

and vice-versa for <<

undone hare
#

I donโ€™t really see why would you jump objects around deques, but thatโ€™s pretty cool haha

deft pagoda
#

cause appending/popping on either side of a deque is O(1)

undone hare
#

I mean, you usually process items before putting them back on another deque

deft pagoda
#

i'm making conveyor belts

wide shuttle
#

You could add a check for if the other item is callabe; if so call it with the value

#

And then have another (or the same) deque take it in again

#

a >> function >> b

deft pagoda
#

oh that's fun

smoky shuttle
#

Interesting

unkempt rock
#

So this is weird, but might be helpful for someone:

import itertools
list(itertools.permutations('SOMEBODY'))

Think Scrabble.

undone hare
#

Just need a dictionary library now lemon_pika

unkempt rock
#

Scrabble bruteforcer when?

deft pagoda
#

you can get unique permutations with more_itertools

flat gazelle
#

anyone have an article on import hooks?

deft pagoda
#

right shift was easy but i did this hack for left shift:

    def __lshift__(self, other):
        if self and callable(self[-1]):
            f = self.pop()
        else:
            f = lambda x: x

        if callable(other):
            self.append(other)
            return self

        if isinstance(other, deque):
            self.append(f(other.popleft()))
            return other

        self.append(f(other))
        return self
#

where it temporarily adds the function to the deque

smoky shuttle
#

Are you creating your own deque

deft pagoda
#

it's just a deque with fun notation

smoky shuttle
#

Oh nice

#

What's the fastest sorting algo?

deft pagoda
#
In [21]: a, b
Out[21]: (Deque([1, 2, 3]), Deque([4, 5, 6]))

In [22]: f = ฮปx.2 * x

In [23]: a << f << b
Out[23]: Deque([5, 6])

In [24]: a, b
Out[24]: (Deque([1, 2, 3, 8]), Deque([5, 6]))
flat gazelle
#

@smoky shuttle radix sort or counting sort

deft pagoda
#

that's if the items are numeric

flat gazelle
#

you can sort strings with radix sort, as well as vectors and such

deft pagoda
#

timsort is fast in general

smoky shuttle
#

radix is only for fixed integer keys

true hollow
#

Aren't >> & << shift operators?

smoky shuttle
#

pretty sure is it's quicksort for real use cases

flat gazelle
#

depends on the case

smoky shuttle
#

yeah

flat gazelle
#

radix sort can do a lot more than you think. And quicksort is bad for small lists

#

there you want insertion sort

true hollow
#

Also fun fact
Python supports bitwise operations
& is and
| is or
^ is xor
~() is two's complement

flat gazelle
#

ye, you can use it to add 1 to a number without parentheses in mulitplication -~x*3 is the same as (x+1)*3

smoky shuttle
#

Yeah but is you start sorting large amounts of data it could use up a lot of memory

true hollow
#

!eval py print(bin(bin(1) ^ bin(1))

fallen slateBOT
#

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

true hollow
#

:^(

#

Sad

flat gazelle
#

essentially, sorting is hard

smoky shuttle
#

True

undone hare
#

Oh hey

#

Py3.8.3 is out

true hollow
#

waw

flat gazelle
#

there are some talks on this in the C++ community

#

and probably elsewhere too

deft pagoda
#

In [28]: a = {'a': 1, 'b': 2, 'c': 3}; b = {'b': 3, 'c': 4, 'd': 5}

In [29]: a.keys() & b.keys()
Out[29]: {'b', 'c'}

you can & dict views

smoky shuttle
#

Have you ever used a sorting algorithm other than for interviews and coding problems?

flat gazelle
#

no