#internals-and-peps

1 messages Β· Page 145 of 1

red solar
#

if i don't care about the exception, but i need the whole of __exit__ to be run even if there was an excepetion

grave jolt
#

if you don't want to suppress it, just ignore those arguments

red solar
#

but __exit__ will still run properly?

grave jolt
#

yes

red solar
#

ok sick

#

imma go try this out πŸ™‚ (might ping you again in a while)

grave jolt
#

πŸ‘

unkempt rock
#

omg i know tkinter

grave jolt
#

contextmanager has to care about those arguments because it's a very generic library function

unkempt rock
#

omg same

#

no way

grave jolt
unkempt rock
#

tkinter is op

#

fr

#

better then django

red solar
#

i can't tell if this is a serious convo

unkempt rock
#

<@&831776746206265384>

#

tkinta epic

unkempt rock
#

its serious

undone hare
unkempt rock
#

is this u

astral gazelle
#

Yes he just posted a link with slurs and deleted it

undone hare
#

yes it is me

unkempt rock
#

tkinter is extremely sophisticated

red solar
#

my god...

unkempt rock
#

epic

red solar
#

it's like i stepped into a time machine and went back to like iOS 3

#

that blue rounded button...

unkempt rock
#

its hot

#

tkinta on top!

red solar
unkempt rock
#

u just mad

#

u no have good tkinta ui

astral gazelle
#

This isnt really appropriate for the channel

#

An interesting convo i was reading was interrupted for tkinter talk

unkempt rock
#

tkinta is important

astral gazelle
#

This is spam at this point

unkempt rock
#

no its not

red solar
#

@grave jolt if i do that ^^, how do i prevent someone from constructing an AtomicIntView on their own?

astral gazelle
unkempt rock
#

no

red solar
unkempt rock
#

this is advanced

red solar
#

yes, but not advanced python πŸ˜‚

unkempt rock
#

im sharing my upper intellect in python

astral gazelle
#

Share it elsewhere, this is offtopic for the channel

unkempt rock
#

omg its advanced

unkempt rock
#

@astral gazelle cant u take jokes

grave jolt
#

@unkempt rock @unkempt rock This channel is for discussions about the Python language. If you want to discuss how awesome tkinter is, we have #user-interfaces .

unkempt rock
#

tkinta is python

#

yes

red solar
#

Python language meaning the implementation (and ig language concepts, but libraries are not language concepts)

surreal sun
#

I know this was already brought up - but would you all say that iterators implement __next__ and are strongly recommended to implement __iter__ but don't have to?

flat gazelle
#

I would argue that an iterator should always have __iter__, in the same way a mapping should always have a .items()

grave jolt
#

if you want to enforce it, I'd return a separate object from __enter__ (as before)

flat gazelle
#

but well, a number of things in python will not require the full protocol of whatever they operate on.

#

!mute @unkempt rock 3d you were already told to keep this channel on topic.

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @unkempt rock until <t:1635963331:f> (2 days and 23 hours).

unkempt rock
#

is awesome

surreal sun
flat gazelle
#

there are things in the stdlib that operate on iterators that do require __iter__, such as most of itertools

#

so I would argue it's more a matter of python being duck typed, so a function doesn't every actually take an iterator, it takes some object that has some methods, and for a lot of the stdlib, the methods are just __next__, and not __iter__.

red solar
#

or is that too unpythonic?

grave jolt
#

I hate this word

red solar
#

unpythonic?

grave jolt
#

yeah

red solar
grave jolt
#

some people just come here to shitpost 🀷

red solar
#

well, idk i think it's something to live by, pythonic stuff is generally easier to understand too

pliant tusk
#
>>> class a:
...     def __init__(self):
...             a.__init__ = None
... 
>>> A = a()
>>> a
<class '__main__.a'>
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
>>> A.__init__
>>> A
<__main__.a object at 0x10520c7c0>
>>> 

you could do this

red solar
#

that prevents __init__ being called again

#

i want to prevent a user from constructing a in the first place

#

(but my function still constructs it)

#

but i think i may be going about this the wrong way again :/

#

ohhhhh

#

nvm i see what it does (but still don't think it's what i want)

pliant tusk
#

you can make __new__ return your single instance

red solar
#

hmm... can i steal __init__?

rotund atlas
#

I would like to save the data passed to a variable in a function to be used later by the same function in a different state. how I can achieve this without using global variables. I have pickle library in my mind.

flat gazelle
#

there is the slightly hacky option of

class A:
    def __init__(self):
        raise RuntimeError(f'cannot instantiate {type(self).__name__}')
    @classmethod
    def _create(cls, name):
        self = cls.__new__()
        self.name = name
spark magnet
#

@red solar why is important to prevent construction?

red solar
flat gazelle
#

@rotund atlasyou can assign attributes to the function itself, e.g.

def counter():
    counter.i = getattr(counter, 'i', 0) + 1
    return counter.i
red solar
#

lemme think about it more and come back

fallen slateBOT
#

src/atomics/_impl/atomic/base.py line 52

class AtomicViewBase(PropertiesMixin, SupportedMixin):```
spark magnet
#

@red solar why would someone try to make one of these instances? Just because they shouldn't, doesn't mean you have to try to stop them. Maybe they just won't.

verbal escarp
#

@red solar when i saw your code my first thought was to have a global datastructure and remove everything except maybe an ID from the classes to have pure @properties as API

red solar
red solar
red solar
spark magnet
red solar
#

hmm

#

i didn't think of that

grave jolt
red solar
#

yeah that too

verbal escarp
spark magnet
red solar
#

like hot potato

#

i don't own the buffer, i have no control over what the user does with the buffer they provide me

#

so i'm trying to contain it in a with statement

verbal escarp
#

🀷

spark magnet
#

@red solar using a with statement to manage object lifetime is good.

red solar
#

@grave jolt is it so bad for __enter__ to return self, and instead of type hinting telling the user they can't use an operation, it just raises an exception?

red solar
spark magnet
red solar
#

ig, and i have an exception if they do, but just the fact that it's available...

spark magnet
feral cedar
#

the end of the with block signals the "end" of the resource, if someone uses it afterwards it's really not your fault

spark magnet
#

give them a more convenient API that's the right way to do it.

red solar
flat gazelle
#

I think if you put it in a docstring, it's obvious enough

red solar
#

hmm... ok well i enjoy refactoring (no sarcasm), so i'll redo it with a manager, and then come back and you guys can tell me if it doesn't look obvious

spark magnet
red solar
#

AtomicInt(width: int) allocates its own buffer

#

AtomicIntView(buffer) gets passed one, but after construction has all the same operations

#

(the view is more for shared memory scenarios)

#

(I was advised to get rid of AtomicInt and just have AtomicIntView, but i don't wanna do that)

white nexus
#

Ohshit I'm glad that ned is here because if not I would've forgotten to try and reproduce that coverage bug πŸ’€

pallid moon
#

While I see the benefits of PEP 671, it's growing in me the sentiment that step by step we are introducing more and more syntax to the language

#

I wonder if there's a middleground between syntax (as in just "operators") and statements, something a little more expressive by its own

halcyon trail
#

honestly as annoying as it sounds the solution to this is just to make sure you get things right, and make sure your "base" syntax picks the best abstractions possible

#

in this case, 671 is literally just making up for a very weird wart in the language, so it's kind of a lose-lose situation

gleaming rover
gleaming rover
#

honestly I think Python did really well for its time

#

but 30 years down the road πŸ₯΄

halcyon trail
#

I actually agree

#

But yeah I'm usually thinking of Kotlin

feral cedar
#

!pep 671

fallen slateBOT
#
**PEP 671 - Syntax for late-bound function argument defaults**
Status

Draft

Python-Version

3.11

Created

24-Oct-2021

Type

Standards Track

feral cedar
#

yeah tbh, for being like 5 years older than java, it's doing pretty well

gleaming rover
halcyon trail
#

Rust does well for what it is but it's has a lot of different goals so I don't like to compare as directly

gleaming rover
#

also ugly af

gleaming rover
#

just that the semantics (of lifetimes) complicate things

halcyon trail
#

Yeah a lot of thought but a lot of language design real estate into things that only make sense if you care a lot about performance

verbal escarp
halcyon trail
#

When we talk about syntax,.what kinds of things deserve good first class syntax, etc

unkempt rock
#
import pkgutil
import importlib

modules_list = []

# Iterating through every module inside the classes package
for module in pkgutil.iter_modules(path=["./classes/"]):
    # returning the module information that has 3 differnt attributes, but we need the whole information for now.
    modules_list.append(module)

while True:
    # Displaying the module alternatives
    for count, e in enumerate(modules_list):
        # e.name will return the module name
        print(count, e.name.replace("_", " ").title())

    print("X. Type 'x' or 'exit' to close the program")
    usrInput = input("\nInput <<<: ")
    if usrInput.lower() == "x" or usrInput.lower() == "exit":
            exit()
    elif usrInput.isdigit():
        try:
            # Trying to import the module specified by the user
            module = importlib.import_module(f"classes.{modules_list[int(usrInput)].name}")
            # Iterating through the module and trying to find the class name
            for attr in dir(module):
                if attr.startswith("bpPr_"): # bpPr_ being the prefix for my class names
                    pClass = getattr(module, attr)

            # Calling the methods inside the class
            pClass(int(usrInput)).option_output()
            pClass.play()
        except Exception as e:
            print(f"Oobs... no such file...\n{e}")
    else:
        print("Oobs... must be a number!")

Is this well commented? Feedback? Any tips? Any "keywords" I should've used on a specific line when describing?

rich cradle
#

I don't think that's on topic for this channel, that's probably better for #python-discussion . But personally, I think that's over-commented. You should be writing comments to explain why a program does what it does, not just what it does. The code should be clear enough to tell the latter without too many comments.

gleaming rover
#

^

#

code should be self-documenting

#

comments should be reserved for exceptional cases IMO

#

I think I've written one comment in the last month

#

and it was to explain why an unchecked cast was safe

rich cradle
#

Same, I rarely ever write comments that aren't docstrings

solar haven
#

Hello! Is there a way to chain __init_subclaclass__ in multiple inheritance or is it only the first parent's __init_subclass__is run? Thanks!

solemn sonnet
#

Hello

flat gazelle
prime estuary
lusty scroll
exotic flume
#

hello

#

import socket
import ssl

hostname = 'www.python.org'
context = ssl.create_default_context()

with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())

#

context obj created. how context obj connected with wrap_socket ?

#

context.wrap_socket(sock, server_hostname=hostname) - pls tell me the working of this line

verbal escarp
surreal sun
#

I honestly can’t remember the last time I wrote a comment besides open source contributions, I usually just write docstrings since they’re explanatory once

lusty scroll
verbal escarp
surreal sun
#

Probably the 2nd or 3rd haha

#

I never even look at my old code sometimes

exotic flume
#

Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() of an SSLContext instance to wrap sockets as SSLSocket objects. The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching.

surreal sun
#

Or my code is just self explanatory

#

I’ll write docstrings for every function usually tho

lusty scroll
#

of course there's TODO / FIXME... and it never hurts to explain why you did something either, if it's not obvious, I think

surreal sun
#

Since I want to finish it in a future commit

lusty scroll
#

is it because flake8-todo is installed?

surreal sun
lusty scroll
#

there's also another plugin called flake8-todos, might be worth checking for that too

#

I was never big on "smart TODOs" showing up as problems in projects I've worked on. maybe it's helpful for some. but to me it's far from obvious the mere presence of a TODO indicates a bug

verbal escarp
#

flake8-todo? never heard of..

halcyon trail
#

But still not quite there

verbal escarp
#

while we're rethinking lambda syntax, we might also take into consideration more general ideas like callbacks/errbacks

#

async anonymous functions

brave badger
hoary drum
#

which is the best software to run python on

#

plz

verbal escarp
white nexus
white nexus
#

That's also why I switch from feature to feature, so I continually have to relearn the code πŸ™ƒ
Easy to question wtf I did and refactor when I come back to it and ends up being pretty damn good code if I do say so myself

verbal escarp
#

well, i tend to dig deep into a particular part of the code to really wrap my head around all details so it also takes me a while to forget about the details, maybe 2-3 months, but basically i'm doing the same as you - work on different features or projects and then come back later with fresh eyes

#

after a few rounds of coming back to the same code, you get an idea of what kind of code needs commenting

ornate lion
#

can i ask a question here for school work ?

verbal escarp
ornate lion
#

i mean i already asked in the general chat someone can toss me some tips on how to go about solving that question

verbal escarp
#

then go ahead

ornate lion
quick snow
verbal escarp
ornate lion
#

wont let me

verbal escarp
#

you posted them twice

undone hare
#

You should use an help channel if you feel the need to post an image

#

also hai amogor!

verbal escarp
halcyon trail
#

@wide shuttle @surreal sun @feral cedar btw, i got a response on that python iterator vs iterable, changing iter behavior thing:

Unfortunately that isn't backwards-compatible. Some people may explicitly want their iterators to not be iterables to guarantee that people who want an iterator get a fresh/new one instead of reusing a live iterator.

#

I suppose that I could comment that such people have the option to implement their __iter__ function as throwing, actually

#

well, okay, they have the option to do that but it's still not backwards compatible

#

oh well

#

I didn't even consider that, actually. We discussed people who would want an iter implementation other than return self, but we didn't really consider that people would actually want iterators that are not iterable πŸ€·β€β™‚οΈ

surreal sun
#

Hmm, so I guess inheriting from collections.abc.Iterator will do for now

halcyon trail
#

yeah pretty much

#

inheriting from the correct ABC is generally a good choice for all kinds of reasons in any case

rapid forum
#

can some1 help me in Help corn

unkempt rock
#

does anybody have a advanced tkinta user interface they can

#

share

#

tkinter proo

ornate lion
atomic egret
#

How should I type-hint a Union of the exact object of discord.embeds.Embed.Empty or a str. Embed.Empty is already initialized from discord.embeds._EmptyEmbed.

atomic egret
#

ooh, is that a new channel?

grave jolt
#

yes

atomic egret
#

cool!

white nexus
red solar
#

did i break PyCharm?

#
_init_AtomicIntView = AtomicIntView.__init__
AtomicIntView.__init__ = None
raven ridge
#

!e @static bluff re: "privacy" in Python, the closest thing you can get is using closures.

class Person:
    def __init__(self, name, age):
        my_name = name
        my_age = age

        def get_name():
            return my_name

        self.get_name = get_name

        def set_name(name):
            nonlocal my_name
            my_name = name

        self.set_name = set_name

        def get_age():
            return my_age

        self.get_age = get_age

        def set_age(age):
            nonlocal my_age
            my_age = age

        self.set_age = set_age

p = Person("John Doe", 42)
print(p.get_name())
print(p.get_age())
p.set_age(24)
p.set_name("Jane Doe")
print(p.get_name())
print(p.get_age())
print(dir(p))
fallen slateBOT
#

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

001 | John Doe
002 | 42
003 | Jane Doe
004 | 24
005 | ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_age', 'get_name', 'set_age', 'set_name']
raven ridge
#

Not that any of this is a good idea, mind you. But that's a way to hide state that makes it harder to introspect and modify - not impossible, mind you, but harder.

sour thistle
#

isn't that just descriptors (@ property) with extra (or, well, maybe fewer) steps?

raven ridge
#

no - with descriptors, you usually still have a "private" attribute like _name or _age that is used by the property methods, and that shows up in dir() and that could be modified directly, out of contract

#

with this approach, the private state is not an attribute of the object, and is harder (though not impossible) to access directly.

#

(you need to get to it through p.get_age.__closure__[0])

red solar
#

ah he also asked about this in #c-extensions , was about to recommend an extension lol

raven ridge
#

yeah - I was following it there, but since this solution is language hacks instead of C extension hacks, I pinged him with this idea here.

#

there's a few things in the standard library that use a trick like this. @functools.cache does.

static bluff
#

❀️

#

Thanks ghoul

fallen slateBOT
#

Lib/functools.py line 525

def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):```
ornate lion
#

I need help so my question is
I need to make a list of prime numbers up to 256 then from those prime numbers i need to sample of 3 values to XOR those numbers to get my hash value i have to
repeat this 16 times so far i got the code where it prints all the prime numbers up to 256

verbal escarp
ornate lion
#

i need help to start off with i have no clue about hashes and xor in python any example ?

verbal escarp
#

!e print(True^False)

fallen slateBOT
#

@verbal escarp :white_check_mark: Your eval job has completed with return code 0.

True
verbal escarp
#

A hash function is any function that can be used to map data of arbitrary size to fixed-size values. The values returned by a hash function are called hash values, hash codes, digests, or simply hashes. The values are usually used to index a fixed-size table called a hash table. Use of a hash function to index a hash table is called hashing or ...

surreal sun
#

XOR is exclusive or, it is basically:
when you have True XOR True it'll give back False
if you have True XOR False it'll act like OR and give back True
if you have False XOR True it'll also give back True
and if you have False XOR False it'll be False

surreal sun
#

yea

unkempt rock
#

What is a bitwise operation?

raven ridge
#

an operation that is defined based on the individual bits of an integer represented in binary.

surreal sun
#

!e
print(bin(~0b1100))

#

oh

raven ridge
#

!e ```py
a = 0b101
b = 0b011
print(bin(a | b), a | b)
print(bin(a & b), a & b)

fallen slateBOT
#

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

001 | 0b111 7
002 | 0b1 1
unkempt rock
#

i'll never understand, what is a bits of an integer?

#

i know binary, its 0 and 1

raven ridge
#

ok, so in decimal, the normal numbering system that you're used to, numbers have a ones column, and a tens column, and a hundreds column, and a thousands column, because it's base 10.

#

in binary, numbers have a ones column, and a twos column, and a fours column, and an eights column, because it's base 2

unkempt rock
#

I've never learned about bases?

raven ridge
#

so the number 1011 in binary is 1 * 8 + 0 * 4 + 1 * 2 + 1 * 1

#

which is 11 in decimal.

unkempt rock
#

alright ty for trying but I wont understand

#

why math

#

i hate it

raven ridge
#

it's not math, it's counting.

unkempt rock
#

1 * 8 + 0 * 4 + 1 * 2 + 1 * 1 gave me a brain freeze

raven ridge
#

in decimal, after 9 is 10, after 99 is 100, after 999 is 1000. In binary, after 1 is 10, after 11 is 100, after 111 is 1000

unkempt rock
#

so its like

#

1, 10

#

11 = 100

#

100 = 1111

#

1111 = 10000

raven ridge
#

counting from 0 to 10 in binary is:

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
#

in decimal, every time you try to go up from a 9 in a column, you carry a 1 to the left. In binary, every time you try to go up from a 1 in a column, you carry a 1 to the left.

#

that's because in decimal, 9 is the highest symbol, and in binary, 1 is the highest symbol.

#

and you know that 1010 in binary is 10 in decimal, because it's got a 1 in the eights column and a 1 in the twos column, and 8 + 2 is 10.

unkempt rock
#

Oh I see, but how come it's not this then:

0000
0001
0010
0011
0110 instead of 0100
0111
1110
etc..
raven ridge
#

because 1 + 1 is 0 carry the 1, and 1 + 1 is 0 carry the 1, and so you've carried a 1 twice and gotten two zeroes, for 100

#

and because 011 is 3 (zero fours and one two and one one), and because 100 is four (one fours and zero twos and zero ones)

unkempt rock
#

so what would 23 be in binary?

raven ridge
#

one sixteen plus one four plus one two plus one one

unkempt rock
#

wait

raven ridge
#

10111

unkempt rock
#

lemme try to type

#

ok nvm

raven ridge
#

last bit.

#

or, least significant bit.

unkempt rock
#

so the columns go like this:
1 2 4 8 16 32 64 128, etc...

raven ridge
#

from right to left, yes.

#

so it's actually:
128 64 32 16 8 4 2 1

unkempt rock
#

ok lemme try to get the number 54 in binary

bleak plank
#

Hello guys, am new here, and i want to learn pyhton

unkempt rock
#

!e 16+16

fallen slateBOT
#

@unkempt rock :warning: Your eval job has completed with return code 0.

[No output]
unkempt rock
#

!e print(16+16)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

32
digital hill
unkempt rock
#

!r print(16+16+8)

#

!e print(16+16+8)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

40
raven ridge
#

you can have at most one sixteen - you can't add 16 + 16

unkempt rock
#

oh?

raven ridge
bleak plank
#

sorry if my english so bad, but can you tell me if i want to learn pyhton what apk that i must have?

digital hill
bleak plank
#

okay then, where should i start??

glad raven
#

Hi, I want to catch exceptions raised in the child process in a multiprocessing concept
How can I do it??

nocturne hazel
#

anyone available to help? I'm having issues separating and formatting multiple outputs from a for loop question in #help-pear

small swallow
verbal escarp
#

wtf πŸ˜„

#

they use an exception to escape the stack and call the next function without recursion

#

i'm impressed and appalled at the same time

#

if that doesn't have a massive performance penalty..

wide shuttle
# raven ridge no - with descriptors, you usually still have a "private" attribute like `_name`...

The descriptor could probably hide the value in a similar obfuscated way to hiding it in a closure cell, if you'd take a different path from how you typically solve this issue. Another thing that would make it more difficult to access the value is to have a descriptor that has a __set__ method and "hides" the value in the instance dict under the same attribute name. It would still be available in the instance dict, but not on regular attribute access, as the descriptor overrides the access. In all cases, you'd have some searching to do, but you can still find a reference to the value somewhere. Closures is probably the easiest way to do this, although it's less reusable than a descriptor that hides the value somehow.

verbal escarp
#

gives

#
[400, 1800, 500.0, 538, 193.73000059699874]
[1800, 130100, 61750.0, 63640, 36691.75450267878]
#

upper is reference to an lru_cached naive factorial function, the lower is the tail-recursive one

#

in nanoseconds

raven ridge
verbal escarp
#

i'm not sure if sacrificing performance for infinite recursion is a good idea..

wide shuttle
#

It does make for an easy way to implement a cached property, were it not that we don't have to anymore

raven ridge
#

The docs call that a "data descriptor"

verbal escarp
#

okay, that performance test is BS, i normalized it with 10000 calls and a factorial of 200 which gives ```
[100, 352700, 200.0, 224.02, 3529.757351192264]
[244400, 5153700, 263900.0, 320027.07, 123130.9109539044]

wide shuttle
#

Or does it do so in the reference as well?

raven ridge
#

I'm looking at Hettinger's, but I believe the reference docs use the same term

wide shuttle
#

Ah, yes,

Note, adding __set__() or __delete__() changes the kind of descriptor to a β€œdata descriptor”. See Invoking Descriptors for more details.

raven ridge
#

But I'm with you now, I missed the significance of __set__ on first read. This is a clever approach.

#

More work as a one off, but reusable, so that's cool.

#

Could be wrapped up into an @private_property

unkempt rock
raven ridge
#

a thing that doesn't exist, but could be built using this idea.

#

actually - we don't even need a new decorator for it, really. We can just use @property as long as we always have a deleter, I think...

unkempt rock
#

I've seen people use @propert but what does it really do?

#

type hinting?

#

the function or what?

surreal sun
#

Example:

If you only want to have a way to get the value


class Test:
    @property
    def value(self) -> int:
        return 5

test = Test()
print(test.value)
>>> 5
test.value = 2
AttributeError: can’t set attribute value

If you want to be able to set it too, something like


class Test:
    def __init__(self):
        self._value = 5
    @property
    def value(self) -> int:
        return self._value
   
    @value.setter
    def value(self, value: int) -> None:
        self._value = value

test = Test()
print(test.value)
>>> 5
test.value = 2
print(test.value)
>>> 2

and if you wanna be able to delete it


class Test:
    def __init__(self):
        self._value = 5
    @property
    def value(self) -> int:
        return self._value
   
    @value.setter
    def value(self, value: int) -> None:
        self._value = value

   @value.deleter
   def value(self) -> None:
       print("value has been deleted!")
       del self._value

test = Test()
print(test.value)
>>> 5
test.value = 2
print(test.value)
>>> 2
del test.value
>>> "value has been deleted"
print(test.value)
>>> error about how it doesn’t exist (like AttributeError: "value" is not an attribute or something)
unkempt rock
#

How is this useful?

feral cedar
#

say you want to restrict the value of an attribute to specific values, you can do that with properties

surreal sun
#

Here’s an example:
datetime.datetime uses properties for their attributes, so the user can’t change it and make the program go haywire. They technically can change via a β€œprivate” attribute, but it’s not made known and most people will only interact with the β€œpublic” attributes

#

Because if the user edits it to an hour that doesn’t exist like 42, datetime.datetime would want to restrict that

unkempt rock
#

Ahh okay ty

surreal sun
manic sundial
#

I'd like to evict some keys from an in-memory cache container and I was thinking to do this from a "worker" task, as in:

class Cache:
    worker_interval: int = 86400 # 24 hours in seconds
    worker: Optional[Task] = None
    container: Optional[RedisDict] = None
  
    @classmethod
    async def run_worker() -> None:
        await asyncio.sleep(cls.worker_interval)
        await cls.evict_what_should_be_from_my_cache_container()
        cls.worker = asyncio.create_task(cls.run_worker())

    @classmethod
    async def evict_what_should_be_from_my_cache_container() -> None:
        """
        Replaces `container` with a deep copy that is just like the original minus the   
        keys that were too old to be worth keeping.
        """

Is there something fundamentally wrong with this design?

unkempt rock
manic sundial
unkempt rock
#

I don't think your task is correct

#

What you usually do is something along the line of

asyncio.create_task(main_task())
while True:
    await side_task()
    await asyncio.sleep(DELAY_BETWEEN)
manic sundial
unkempt rock
#

Because you start by sleeping, then you clear the cache once and start your main task and never sleep or clear again

#

Oh wait, it is a recursive call

manic sundial
#

yup

unkempt rock
#

Well, it doesn't work anyway as you don't run the worker at the same time

manic sundial
unkempt rock
#

Because if you really want to do this, you don't have to re-run run_worker in another task and you basically have the same code as me, but you fill up the stack overtime

manic sundial
unkempt rock
#

Yeah, each call is another stack frame

manic sundial
#

@unkempt rock Makes sense, thank you!

lusty scroll
#

1000 frames iirc

manic sundial
#

I was hoping I would be able to use tail-recursion optimizations, but I see Python does not out of the box do tail-recursion optimizations.

unkempt rock
#

!e

import sys
print(sys.getrecursionlimit())```
fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

1000
unkempt rock
#

I thought it was much more by default

#

I wonder if that'd get raised up by the one million PEP

manic sundial
#

:)

peak spoke
#

it can't go much higher before running out of space

unkempt rock
#

Do you know how large a call frame is, num?

manic sundial
#

No idea.

manic sundial
unkempt rock
#

It is an actually question, I don't know how large it is, heh

peak spoke
#

Not exactly, but they are fairly large iirc

elder blade
unkempt rock
#

We don't lower it in snekbox

elder blade
#

Ah

lusty scroll
#

a PyFrameObject is 48 bytes, InterpreterFrame is 80 bytes

unkempt rock
#

The interpreter is pretty much running normally, it is just the kernel applying some limit on it

manic sundial
#

While you folks are here, may I ask a last "my python is more rusty than I thought" question?
Consider:

MyClass1(Mixin1, Base):
    ...
MyClass2(Mixin2, Base):
    ...

where Base is a subclass of ABC. Question: can I do something so that MyClass1 and MyClass2 will appear to my IDE's static type checker as instances of a single type, i.e. a type defined as constituted of any combination of Base + something?

unkempt rock
#

They will both be a subclass of Base

#

You can't say anything else about them, there is no other common ancestor

manic sundial
#

Indeed but my static type checker does not see the attributes/methods inherited from their respective mixin.

unkempt rock
#

Otherwise you have a Union[MyClass1, MyClass2]

manic sundial
unkempt rock
#

But in either case, if you use an isinstance check it will work fine

manic sundial
#

Of course.

#

Thanksies!

lusty scroll
unkempt rock
#

Yep!

unkempt rock
#

I think i shouldn't be here

quick cedar
#

which operating system is best for python

unkempt rock
lusty scroll
#

and the shebang (#!/usr/bin/env python3) at the top of python sources should just work, mostly

halcyon trail
#

IME there are more minor bugs and caveats for the closer-to-OS stuff on windows, than linux

lusty scroll
#

personally I find it easier to build python itself and extension modules than on Windows, too

halcyon trail
#

maybe less than in the past

#

but I do remember qutie a few cases of going through a module like os, or subprocess, and there are things that seem more with linux in mind, and on windows theyd on't work, or don't work fully

lusty scroll
#

like signals

#

or even just Ctrl+C

#

or readline

static bluff
#

What's everyone's fave piece of Python's syntax?

#

I know we take it for granted, but mine is probably python's flexibility in terms of arguments

surreal sun
#

Hmm, I really love match/case, but I haven't gotten to use it all too much

static bluff
#

Second to that, iterable unpacking

surreal sun
#

ohh, you're asking that type

surreal sun
halcyon trail
#

i would agree with arguments as it's pretty unique to python as well

surreal sun
#

one of the features i like is
one, two, *three_and_above = *[1,2,3,4]

static bluff
#

Also

#

{**some_dict, 'something_new': 1234}

surreal sun
#

Ooh, i love that too

#

Unpacking in general is nice

static bluff
#

We're learning C++, and the entire notion of a dictionary literal goes way beyond what it can do

#

So even just that is a win

halcyon trail
#

that's not really true

#

C++ can do that stuff with libraries that use functions and lambdas, which is how most languages do it

#

it also has initializer lists built in

#
unordered_map x{{"hello", 5}, {"goodbye", 10}};

and so on

#

(sorry at first I was talking about comprehensions rather than literals)

verbal escarp
feral cedar
#

some other langs have them, but yeah they're great

verbal escarp
#

werent they invented in python?

feral cedar
#

they're reminiscent of set builder notation from math. no idea if they first showed up in python

flat gazelle
#

they are from math, and I think they were in some ML derivative first

verbal escarp
feral cedar
#

Boo

verbal escarp
#

1969 in SETL

#

never heard of that before

#

hmm.. i know it's double-edged, but i think the whole idea of protocols and mapping syntax to methods is pretty nice

#

i think that was one of the things that made me fall in love with python in the first place

#

how clean and simple everything looks, hiding away complexity

#

while you still can get into the details if you really want or need

#

oh, and for-loops are absolutely amazing

#

if you come from a language like java that is one of those "OMFG HOW IS THAT EVEN POSSIBLE AND WHY CANT ALL LANGUAGES HAVE THAT!?!" features

feral cedar
#

java has for each loops though

verbal escarp
#

i've ran from java a long time ago ^^

feral cedar
#

before java 5?

verbal escarp
#

apparently so

feral cedar
#

wild

#

anyway, nowadays it's much more common, swift, kotlin, rust, etc

verbal escarp
#

just looking at the syntax, it's not nearly as nice as python for-loops though

#
for (Iterator it = hs.iterator() ; it.hasNext() ; )
   System.out.println( it.next() );
feral cedar
#

that is not a foreach loop lol

flat gazelle
#

you can just

for(var a: hs) {}
verbal escarp
#

oh

#

ah

#

okay, whatever ^^

#

ever since i had to write uni exams in java by hand i hate it

feral cedar
#

yeah, i had hand-written java too. luckily my teacher let us abbreviate things (RightRectangularPrism 😩 )

surreal sun
#

in C, would for each loops be something like:

#include <stdio.h>
int main() {
  int arr[] = {1, 2, 3, 4, 5};
  for (int *pointer = arr; pointer < arr + (sizeof(arr) / 4); pointer++) {
    printf("Value: %d", *pointer);
  }
}
#

This sounds like a name that would be generated from a repl.it name generator

verbal escarp
#

should be a band name

surreal sun
#

ASLBFB

#

wait, what

feral cedar
#

IndentationError: mixed use of tabs and spaces

surreal sun
#

You have got to be kidding me lmao

flat gazelle
surreal sun
#

ah

#

Ohh I messed it up, I forgot the expression after the first ;

flat gazelle
#

but most C code over arrays will just use i as an index

#

just like bad python code

surreal sun
#

Hm, is there a style guide for C?

verbal escarp
flat gazelle
flat gazelle
verbal escarp
#

ohh

#

yeah, that looks like it's written by someone coming from one of those languages

#

not having embraced the beauty of python's for-loop yet

surreal sun
#

Honestly, I will always love

for idx, _ in enumerate(array):
  ...

over

for i in range(len(array)):
  ...

if you want to get the 'index' in an array only

#

enumerate looks a lot nicer in most cases if I'm being frank

verbal escarp
#

i'd prefer the second

#

at least it's clear what you're doing there

#

also.. why???

#

:p

surreal sun
#

hm, fair
but descriptive for loop variable names go a long way, so as long as you aren't doing something like

for a, b in enumerate(...)

or just overall random names, i wouldn't care too much

#

mostly a personal preference for enumerate

verbal escarp
#

when do you ever need the index but not an element while iterating over something?

surreal sun
#

I had a usecase for it a while back but I can't remember it

tiny aspen
#

don't know where to put this but does anyone know any open source python algorithms that make use of neural networks to identify common road items{road, traffic signs etc}

verbal escarp
flat gazelle
#

@verbal escarp when you are only writing to elements

#

Sth like double all elements of a list

verbal escarp
#

then i'd question whether a list is the best approach, numpy arrays would make this much nicer.. but okay, at least one use-case

raven ridge
#

!e @wide shuttle @static bluff Following up on Sebastiaan's idea from this morning, this does a decent job of hiding private state without being nearly as weird as the closure approach I proposed:

class Person:
    def __init__(self, name, age):
        self.__dict__["name"] = name
        self.__dict__["age"] = age

    @property
    def name(self):
        return self.__dict__["name"]

    @name.setter
    def name(self, name):
        if not name:
            raise ValueError("Name must not be empty")
        self.__dict__["name"] = name

    @property
    def age(self):
        return self.__dict__["age"]

    @age.setter
    def age(self, age):
        if age < 0:
            raise ValueError("Age must not be negative")
        self.__dict__["age"] = age

p = Person("John Doe", 42)
print(p.name)
print(p.age)
p.age = 24
p.name = "Jane Doe"
print(p.name)
print(p.age)
print(dir(p))
fallen slateBOT
#

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

001 | John Doe
002 | 42
003 | Jane Doe
004 | 24
005 | ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
raven ridge
#

It's not quite as hidden as the closure approach - instead of poking around in .__closure__ the user has to go poking around in .__dict__, which is a bit easier. But hopefully it's reasonably obvious that .__dict__ is private and shouldn't be messed with. If you're super paranoid, you could go with .__dict__["don't"]["touch"]["this"]["age"] πŸ˜„

elder blade
#

How does Python access the property?

raven ridge
elder blade
#

Ah

raven ridge
#

which lets us use the same name in the instance dictionary for the "private" state.

surreal sun
raven ridge
#

no, I mean that getattr(obj, name) checks for type(obj).__dict__[name] and if it's found and is a descriptor with __set__ or __delete__, it is used instead of obj.__dict__[name]

surreal sun
#

ohhh

unkempt rock
#

today I've seen a lot of underscores in variables, lists etc...

#

what do they mean?

peak spoke
#

depends on where they are

unkempt rock
#

wdym?

#

e.g what is obj.__dict__?

#

i thought variables couldn't start with a underscore?

peak spoke
#

with double underscores on both sides it's variable used by the interpreter that you generally don't interact with directly, with __dict__ you access the instance dictionary that stores all the instance attributes

#

They can have underscores anywhere

rich cradle
unkempt rock
#

ugh my confusion at 2am starts again

#

what is a "interpreter" and a "instance dictionary"

#

i hear them everyday, but I don't know what it is and what it does

rich cradle
#

The Python interpreter is what executes your Python code.

unkempt rock
rich cradle
#

It doesn't have any special meaning in the interpreter, correct

unkempt rock
#

Ah ok understood

#

but what did the double underscores on each side do?

#

and if u can please try to describe with like friendly english

rich cradle
#

Those are dunder methods, that's a whole other thing that I am definitely not qualified to explain.

unkempt rock
#

Oh ok

#

So this is like, very advanced thing that i'll learn years later?

rich cradle
#

No, it's not a hard concept, I just don't know how to explain them very well since I don't mess with them much.

unkempt rock
#

Ah I see okay, thanks for trying tho πŸ™‚

unkempt rock
swift imp
#

Has anyone heard any updates about the 3.11 speed updates being funded by microsoft?

queen dust
#

they're basically special cases in classes that u interact with in unique ways something like that

raven ridge
#

!e If so, __dict__ is a dictionary that holds instance attributes.

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

john = Person("John Doe", 42)
print(john.__dict__)
print(vars(john))
fallen slateBOT
#

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

001 | {'name': 'John Doe', 'age': 42}
002 | {'name': 'John Doe', 'age': 42}
raven ridge
#

That is, when you assign to self.foo, that's basically an assignment to self.__dict__["foo"] (at least, normally - there are exceptions)

old void
#

@arctic ruin

elder blade
# unkempt rock but what did the double underscores on each side do?

I believe they're officially called magic methods, they allow you to have special behaviour. You already know that __init__() is called to initialize the class, well there's also __call__ that will make that class callable (like a function!).

What people have been messing around with above is the __dict__ attribute, this is a special attribute (as indicated by the __). Here is where Python stores all attributes, so when you do a.b that means that 'b' is looked up in a's __dict__ dictionary*.

*There's of course exceptions

gleaming rover
queen dust
prime estuary
#

Basically Python itself has reserved all __names__ for its own use, you aren't supposed to use them except for where the language documents you can use them. They're used for customisation hooks all over, since they're reserved future versions can add additional ones without worrying about breaking existing code.

queen dust
prime estuary
#

Yep, they do so, and in 3.11 a lot of the optimisation effort is implementing infrastructure to cache results for more opcodes.

#

3.11 is implementing a 'specialising' interpreter, which records the types used in various opcodes, then if the types are consistent across multiple calls it swaps out the generic opcodes for more specialised ones (for instance BINARY_ADD_INT, CALL_FUNCTION_BULTIN_O, etc).

mellow rapids
#

anyone familiar with XML interface using .xsd file type?

unkempt rock
#

I fell a sleep and i wake up to this, i screenshotted everything ill look into it later πŸ˜‚ i cant even feel my heart beating yet, wai what

unkempt rock
native flame
#

yeah pretty much, except __dict__ isn't a method, its just an attribute

unkempt rock
#

oh so there are also cases where something can be attributes and methods?

unkempt rock
real crow
#

guys... since dictionary updates are atomic operations.... doesn't that mean it is kind of like a lock?
let's say I have a requests.Session() and I store it in a dictionary
every 10 seconds another thread will create a new session and then update the dictionary
so I think it is thread safe for the other thread to do like
sessions[key].post(url, data)
because of the dictionary update?

even if the session is not a threadsafe object, I think it is safe if the session is given to the dictionary and not used in the thread that created it

peak spoke
#

every cpython instruction is "atomic" unless the code it invokes releases the gil (in the case of instructions that run C code underneath) or runs some other code, but you'll find that most operations consist of more than one instruction

#

the dictionary save itself won't break anything if it's threaded, but you may need to consider that threads can switch between the object creation and item assignment, and the load can switch after looking up the dictionary key but before looking up the method

unkempt rock
#
# Sets
# *args, **kwargs, packing and unpacking
# * and \ in function definitions
# Learning type hintings and mypy, doctstrings
# Annotations
# Inheritance
# List comprehension, slices and generators
# Mixins and collectons.abc
# Positional vs named arguments
# Walrus operator and match statements
# Contextlib
# Pdb, doctest and unittest
# Multithreading and asyncio
# Learn modules: collections and itertools
# Learn 3rd party libs (pandas and numpy)
# Generators, decorators
# Asynchronous programming
# Socketing
# Superclasses
# Metacasses
# Learn actual algorithms
# Datastructures
# Discrete math
# Testing frameworks
# Design patterns
# Devops and deployments

Could someone be kind and edit this list by sorting it from easier to learn to harder to learn?

main lynx
#

my brain is broken, is this homework or prep to create homework?

unkempt rock
#

Just what I need to learn in python

#

this is the final list:

# FUNCTIONS #
"1"| Positional vs named arguments
"2"| *args, **kwargs, packing and unpacking
"3"| * and \ in function definitions

# CLASSES/OBJECTS #
"1"| Inheritance
"2"| Superclasses
"3"| Mixins and collectons.abc
"4"| Metacasses
"5"| Design patterns

# LISTS/DICTS/SETS etc.. #
"1"| Datastructures
"2"| List comprehension, slices and generators
"3"| Learn modules: collections and itertools
"4"| Generators, decorators
"5"| Walrus operator and match statements

# OTHER #
"1"| Annotations
"2"| Docstrings and mypy

"1"| Socketing
"2"| Contextlib

"1"| Pdb, doctest and unittest
"2"| Testing frameworks

"1"| Multithreading and asyncio
"2"| Asynchronous programming

"1"| Discrete math
"2"| Learn 3rd party libs, pandas and numpy
"3"| Learn actual algorithms

"1"| Devops and deployments
verbal escarp
unkempt rock
verbal escarp
#

is there a specific reason why you need to learn it or is it just something you want to learn?

main lynx
#

hard to say what's difficult because it varies from person to person, could maybe comment on which things are more useful

verbal escarp
#

datastructures alone can fill books

#

as well as sockets, multithreading, async

#

devops

#

algorithms

main lynx
#

and even then depends on what you're doing, in some contexts asyncio is easily at the top of the list, in others you will never touch it

verbal escarp
#

same as algorithms really

#

if you only do GUI programming, for instance

main lynx
#

but there are some things that you almost always want like list/generator comprehensions and understanding why we care about generators

verbal escarp
#

and "annotations" shouldn't be "other"

#

i think that's more important than walrus or match (both of which you really don't need that often, at all)

#

same as metaclasses

#

never really needed them in all those years

main lynx
#

also the sooner you spin up pytest the better

verbal escarp
#

unit tests definitely should be on that list

#

ah, it is (as "other")

#

@unkempt rock what do you want to do?

#

what do you need python for?

unkempt rock
verbal escarp
#

so you're studying for a degree?

#

or do you have some concrete project in mind?

#

@unkempt rock ?

unkempt rock
verbal escarp
#

okay, that narrows things down

unkempt rock
#

Yessir, I'm just 17 and I want get the basics of python down, and then focus on more (intermediate and advanced) stuff

verbal escarp
#

well, you should stick to the basic syntax and wrap your head around the theory then before going to stuff you'll probably never need (like metaclasses)

#

datastructures, algorithms, maths

unkempt rock
#

I never need those?

verbal escarp
#

those are the theoretical underpinnings you'll need to wrap your head around

#

and advanced stuff like metaclasses you can safely ignore for now

unkempt rock
#

But I've basically learned the basics in python

#

That's why I made a full list on what I should learn next

halcyon trail
#

metaclasses in python just aren't really worth learning at this point

verbal escarp
#

then try to implement those theoretical concepts you learn (datastructures, algorithms, maths) in python

halcyon trail
#

it's very python specific, even for professional python developers it's usually used rarely

#

you should as amogorkon suggests focus more on general concepts that transcend all or at least most programming languages.
algorithms, data structures, can also look at things like classes, inheritance, data classes

verbal escarp
#

learn it

unkempt rock
#

no never

verbal escarp
#

you'll get better at it

#

i'd recommend khan academy

halcyon trail
#

you don't need super advanced math to be good at programming, but at least knowing the basics well

#

knowing how to do complexity analysis, construct a basic proof

unkempt rock
#

1 + 1 = 2, i'm not going further than this, i hate it

halcyon trail
#

Also if you want to do AI or ML, that's basically all math

verbal escarp
#

yup

unkempt rock
#

shit.

halcyon trail
#

Yeah

verbal escarp
#

signal processing, language.. that's algebra and statistics right there

halcyon trail
#

If you don't know calculus, linear algebra, or probability, you will never be more than a (sorry) code monkey in AI or ML, using existing packages on existing data, not really understanding why things work or don't work, messing around randomly

verbal escarp
#

it's true, sadly

#

(no pun intented)

unkempt rock
#

I'm in the edge of failing in my math classes in school

#

I just cant stand it

verbal escarp
#

that doesn't matter

#

you can learn it in your own time, just keep at it

halcyon trail
#

well, do your best then to turn that around, and avoid AI/ML. Also, we're pretty off topic at this point.

feral cedar
#

higher level computer science courses are very similar to a math class

halcyon trail
#

Yep, pretty much.

#

^

unkempt rock
#

Math is funny when you understand it, if you dont, then it's probably the most boring thing in the world

verbal escarp
#

same as programming ^^

still wolf
unkempt rock
#

mainmenu: https://paste.ofcode.org/CETuG6zgenvf7CepZBfT4N
Hello, I'm letting the user choose which class should be instanced by finding the class using prefix names and using the pkgutil and importlib modules. Now, how can I do this using subclasses and flags?

manic sundial
#

I was checking out the CPython implementation of generators and it's tempting to believe that generators (comprehensions) are almost always better than lists (comprehension), as it seems that the only argument for lists over generators is when you need to traverse iterables several times, which is seldom the case.

#

Do you folks agree with that?

grave jolt
#

@manic sundial str.join is slightly faster on a list than on a generator

manic sundial
grave jolt
#

hm?

manic sundial
#

so concatenation-based operations, and sorting.

grave jolt
#

no there's no generality here, that's just how str.join is implemented in CPython πŸ™‚

manic sundial
#

I get that, but the generalization I think is warranted. actually I don't know.

elder blade
elder blade
#

For a generator CPython needs to create a generator, then iterate and exhaust it normally as with any iterable/generator

#

This is slower than how CPython can optimize list comprehensions

grave jolt
#

If str.join encounters something other than a tuple or a list, it creates an array out of it. So it's going to be strictly worse than a list.

manic sundial
#

Is it regarded as "Pythonic" to compose multiple generator functions, as in

with_it = lambda it: (x for x in it if predicate(x))
with_it2 = lambda it: (f(x) for x in with_it(it))
final_gen = (x for x in with_it2(my_iterable))

?

manic sundial
queen dust
grave jolt
#

filter and map return iterators

grave jolt
manic sundial
#

It's nice to compose generator functions like any other function.

manic sundial
grave jolt
#

that wouldn't work with generators or other iterators

manic sundial
#

A composition of generator functions I think traverse the iterable just once.

grave jolt
queen dust
grave jolt
#

!e

def f():
    print('a')
    yield 1
    print('b')
    yield 2
    print('c')
    yield 3

print(list(map(str, f())))
fallen slateBOT
#

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

001 | a
002 | b
003 | c
004 | ['1', '2', '3']
grave jolt
queen dust
#

!e

list(map(lambda x: print('map2'), map(lambda x: print('map1'), (1, 2, 3, 4, 5))))
fallen slateBOT
#

@queen dust :white_check_mark: Your eval job has completed with return code 0.

001 | map1
002 | map2
003 | map1
004 | map2
005 | map1
006 | map2
007 | map1
008 | map2
009 | map1
010 | map2
manic sundial
# grave jolt I'm not sure what you mean by this

What I mean is: with a composition of generator functions, the entire set of operations defined by each individual generator is applied on every item, one by one. I think that filter and map apply their operation sequentially, i.e. the iterable is entirely filtered, and then entirely mapped.

queen dust
grave jolt
#

what do you mean by 'entirely'?

queen dust
grave jolt
#

map is (almost) equivalent to this py def map(fn, iterable): return (fn(x) for x in iterable) and filter to this: ```py
def filter(fn, iterable):
return (x for x in iterable if fn(x))

#

they don't create intermediate lists if that's what you're asking

grave jolt
manic sundial
#

That was what I had in mind.

queen dust
#

they are functionally the same

#

def is more syntactic and more readable in my opinion

#

using builtins is usually the best and clearest bet for general use cases

grave jolt
halcyon trail
#

i don't understand how it's reusable though if its assigned to a lambda in local scope

queen dust
#

i have a controversial opinion on this but lambda in Python is a bit of an afterthought (e.g. you can only use one expression), and that reflects how you should prioritize using lambda vs def

halcyon trail
#

that's not at all controversial πŸ™‚

queen dust
halcyon trail
#

python's lambdas do suck, and it's unfortunate. that does not change what idiomatic, mainstream python is.

halcyon trail
#

I think guido even has a post wher ehe says there's almost no reason to use a lambda instead of a local def. it's really just for places where the function is trivial and being passed directly to another function

grave jolt
#

I wish Python had more built-in tools for not writing lambdas. Like operator but better. I think there was a library that let you do X.foo + X.bar, but I doubt it works well with linters/typecheckers

halcyon trail
#

hot take: I think Guido looked at C++ and Java and said "oh, the only reason people complain about not having lambdas here is because they can't define local functions", and that shaped things in python, I don't know if he understood all the cool things that could be done with them, probably because languages that did cool things with lambdas were not mainstream back then

grave jolt
#

yeah, I guess

halcyon trail
#

the problem IMHO is that people want special operators for composition, and they want currying, and they want partial, etc etc

#

and it still doesn't cover everything

#

whereas if you just have an awesome lambda syntax then you don't really need these other things

queen dust
#

yeah functional programmers are bloodthirsty lol

grave jolt
# grave jolt yeah, I guess

...although this brings me to another point: all these functional things will not work well with IDEs/typecheckers

halcyon trail
#

what functional things?

#

lambdas?

grave jolt
#

like compose with varargs, flatmap with varargs, currying etc.

queen dust
halcyon trail
#

that's not really a functional thing, it's more about variadic generics

#

and you can just have a binary compose

#

and then it works fine with type checking

queen dust
halcyon trail
#

i'm not sure how currying can be considered a fundamental "general" programming concept

#

it's just a particular approach/technique, featured in a tiny fraction of overall programming languages

queen dust
halcyon trail
#

that doesn't seem to be making any inroads or convinced anyone outside of very FP languages that its valuable

#

partial application and currying are not the same

grave jolt
queen dust
halcyon trail
#

I don't know if python has variadic generics tbh

#

I've never used them

grave jolt
#

there's a PEP

halcyon trail
#

C++ has variadics

#

I've done a lot of things with them there... it can get quite.... "fun" πŸ™‚

#

but it does let you do, in certain specific cases, incredibly useful things that are difficult to write in other languages

grave jolt
#

yeah currying is a bit meh in Python

halcyon trail
#

python doesn't have currying πŸ™‚

#

so it's not meh

#

just non-existent

grave jolt
#

you can make a decorator that makes a function curriable

#

I think returns has one

halcyon trail
#

I guess that's fair. that said, why would anyone do that.

#

Currying is probably the absolutely least successful idea to come out of FP

#

(auto-currying that is)

grave jolt
#

I guess it could be useful with decorator factories

queen dust
halcyon trail
#

idk, I have trouble imagining any situation where I'd want to use it.

grave jolt
#

I get really pissed off when I need to make a parametrized decorator tbh

queen dust
grave jolt
#

hm?

queen dust
#

i don't use python outside of interviews and basic scripts

halcyon trail
#

i think fix just means that when you write a decorator that also takes arguments, which isn't that rare

#

you end up with triple nesting

grave jolt
#

yeah

halcyon trail
#

it's a function returning a function that returns a function

#

it's quite a headache

halcyon trail
#

at that point I think maybe it's easier to write that decorator as a class?

#

I forget if that helps

queen dust
#

i was replying to the wrong comment sorry

#

i wasn't meaning to reply at all lol

halcyon trail
#

nw πŸ™‚

queen dust
#

IDK basically just curious what the scope of your python use is

#

because I have fairly limited range where I use Python and then I'm primarily a Go dev at work

halcyon trail
#

in fairness you are in the advanced channel

#

so you can't be too surprised to hear that people are doing, well, moderately advanced things with python πŸ™‚

queen dust
#

yeah it's understandable i'm just curious in general

astral gazelle
#

#moderately-advanced-discussion

halcyon trail
#

We use python pretty extensively. I work in high frequency trading, the actual strategy and such is all in C++, but there's a mountain of supporting python

queen dust
#

ah gotchu

halcyon trail
#

maintaining all kinds of metadata, generating configs for C++ applications, all the deployment stuff, alerting and monitoring, devops stuff, etc etc

#

and of course a lot of quantitative data analysis and modelling

queen dust
#

are you a quant or more of a quant-adjacent SWE then

halcyon trail
#

quant adjacent

#

I started as a quant, i was recruited after I finished grad school in physics

grave jolt
#

Oh, I remember what I miss from Haskell. Higher-kinded types and type aliases. Currently, there's nothing you can put in here py T = TypeVar("T") f: ??? = lambda x: x that will mean the same as py T = TypeVar("T") def f(x: T) -> T: return T so we would need something like ```py
T = TypeVar("T")
f: Forall[[T], Callable[[T], T]] = lambda x: x

#

I tried making a lens library and failed. Because I can't make polymorphic lenses.

halcyon trail
#

and then i just decided I prefer to write code

queen dust
#

i've been pretty against working in HFT for a while because I like more customer-facing stuff but the work is growing more interesting to me

grave jolt
# grave jolt I tried making a lens library and failed. Because I can't make polymorphic lense...

TL;DR if you have this py @dataclass(frozen=True) class Isomorphism(Generic[A, B]): atob: Callable[[A], B] btoa: Callable[[B], A] You can have these: py swap_int_str: Isomorphism[tuple[int, str], tuple[str, int]] swap_bool_list: Isomorphism[tuple[bool, list], tuple[list, bool]] swap_float_float: Isomorphism[tuple[float, float], tuple[float, float]] ... but you can't express an Isomorphism that works on all of these, in other words ```py
swap: Forall[[A, B], Isomorphism[A, B]]

halcyon trail
#

Somewhat similar

queen dust
#

nice that sounds fun

#

for me i'm basically torn between my interest in creating consumer-facing (ish) solutions and current disinterest in finance vs. my love of money lol

#

i might try to give it a run in a couple years to try it out and see if i like the culture/work

fallen slateBOT
#

Hey @placid perch!

Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:

β€’ If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)

β€’ If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:

https://paste.pythondiscord.com

halcyon trail
#

yeah i don't have much interest in finance either fwiw

echo remnant
#

Hey so i need some help,know this isnt the right spot but looked like it

#

Im working on a project

#

where im splicing addons from company names

#

Like LTD and Limited in the uk and other addons in other countries

#

it works from a database with like 45 thousand company names

#

i have the basic idea on how to do it but im still looking for help

echo remnant
#

sorry

verbal escarp
feral cedar
#

type-theory-discussion

radiant spear
#

Hi

grave jolt
# verbal escarp what are polymorphic lenses?

"lenses" are basically getters and setters except for immutable values. For example:

>>> lens = item(1, attr("comments", item(0, key("posts", iden)))
>>> data = {"posts", [Post(comments=["nice work", "meh", "shared with my boss and he fired me"])]}
>>> lens.get(data)
'meh'
>>> lens.update(data, str.upper)
{'posts', [Post(comments=['nice work', 'MEH', 'shared with my boss and he fired me'])]}
>>> lens.set(data, "[REDACTED]")
{'posts', [Post(comments=['nice work', '[REDACTED]', 'shared with my boss and he fired me'])]}
#

A simple lens type looks something like this: Lens[S, A]. S is the overall structure type (here it's dict[str, list[Post]]), and A is the type of the element (in this case str because we're looking at/changing individual comments).

#

You could implement a lens like this:

@dataclass
class Lens(Generic[S, A]):
    getter: Callable[[S], A]
    setter: Callable[[S, A], A]
#

Then, for example, you could do this: ```py
@dataclass
class Post:
comments: list[str]

first_comment: Lens[Post, Optional[str]] = Lens(
lambda post: post.comments[0],
lambda post, new_comment: Post(([] if new_comment is None else[new_comment]) + post.comments[1:])
)

verbal escarp
#

looks simple enough

dapper lily
#

how different is this from a property?

grave jolt
grave jolt
#

(or, well, immutable by convention)

verbal escarp
#

you could use a property that returns a new object

#

or a set-once property

#

i'm not sure i understand the question about types though

grave jolt
#

Something like this is illegal: ```py
first_element: Lens[tuple[A, B], A] = Lens(lambda tup: tup[0], lambda tup, first: (first, tup[1]))

grave jolt
#

and, well, I can't make a property for all the possible use cases

#

especially if the object isn't under my control (like... a dict or a tuple)

verbal escarp
#

it looks overly complicated

#

why do you need this?

grave jolt
#

My use case was a graphics library. In it I have to use immutable values because otherwise the multithreading will break. (basically it's a feature)

In the library, you create complex scenes by manipulating nested objects. Like, a pair of (a triangle, and a group with (a rectangle, a circle, a circle, a LaTeX).
So if you want to alter a deeply nested element, you have to really go out of your way. Say, you want to make the circle 3 times bigger. ```py
new_pair = Pair(pair[0], Group(pair[1].elements[:2] + [pair[1].elements[2].map_radius(3 .mul)] + pair[1].elements[3:]))


But with lenses it would be: ```py
new_pair = (first >> index(2) >> radius).change(pair, 3 .__mul___)
``` and you don't even need weird methods like `map_radius`
dapper lily
grave jolt
#

???

#

that doesn't work

verbal escarp
#

i stand by my remark. it looks overly complicated

grave jolt
#

it works well in reanimate, an animation library for Haskell

#

how else would you change a deeply nested structure in my case?

verbal escarp
#

deeply nested.. ugh.. i'd probably try with a visitor or composition pattern

grave jolt
#

mind giving an example?

#

I'm completely uneducated

verbal escarp
#

one sec

dapper lily
grave jolt
#

oh, I think I remember one thing

verbal escarp
#

well, i don't know enough about your case to give you a good example, but to illustrate you can either go like ```python
class Geometry:
def init(self, children):
self.children = children # subclasses of Geometry
def mutate(self):
for c in self.children: c.mutate()

#

or you have the recursive structure fed into an external function which will operate on the tree of objects

grave jolt
verbal escarp
#

which is the visitor pattern

#

basically

grave jolt
#

I don't want to make the library user create a class every time they want to modify a pair

#

I think I don't completely understand your proposal

verbal escarp
#

then the visitor pattern is probably better suited, which operates on the existing objects, recursively

grave jolt
#

I guess I could do pair.map_second(lambda group: group.map_index(2, lambda circle: circle.map_radius(3. __mul___)))

grave jolt
# grave jolt oh, I think I remember one thing

immutables.Map has this thing where you can do something like py my_map: Map[str, int] # immutable HAMT with something(my_map) as mm: mm["key"] = 42 mm["other_key"] = 24 for key in ("foo", "bar", "baz"): mm[key] += 1 print(mm.value) # new immutable value, with the modifications So I could do this: ```py
with mutate(pair) as mm:
mm.second.at_index(2).radius *= 2

verbal escarp
#

hmm.. that does look nicer. but i'm not sure why your underlying lib doesn't support stuff like that?

grave jolt
#

like, it would be pair.group[2].radius *= 2 in imperative code

verbal escarp
halcyon trail
#

Only time I tried lenses was in Kotlin. They seem to work well enough.

#

I just think python is a strange language to try to make the whole thing work in.

#

Trying to do immutability in python is swim so hard against the current

grave jolt
#

I mean, at the type level

verbal escarp
halcyon trail
#

my overall conclusion though was that languages should provide a first class solution to this thing if they care about immutability

#

i mean, the way the current is going is just factual, I'm sorry.

#

All the built in data structures are mutable, python has very poor support for expression-oriented programming; you constantly need to create things and mutate them.

#

(poor lambdas are part of this)

grave jolt
#

In my case, it's not just my personal quirk (although I have a crush on immutability), it's just the way my architecture works to allow multithreading

halcyon trail
#

tuple isn't really a data structure, but, sure, ok

#

that's a quibble and I'm sure you know it

#

list, dict, set, all mutable

#

idiomatic python uses the built in data structures, that's just fact πŸ€·β€β™‚οΈ

verbal escarp
#

you can do a lot with tuples and namedtuples

feral cedar
#

but not everything

halcyon trail
#

they're still not really data structures, they are more like pared down versions of data classes

feral cedar
#

a namedtuple is basically a dataclass

grave jolt
#

I think it's funny that CPython has a HAMT but in Python land it has to come from a library

halcyon trail
#

anyhow, it's silly to argue that doing immutable stuff in python isn't going heavily against the grain. That's a separate discussion from whether or not it's worth it, but it clearly is against the grain.

grave jolt
#

I am not arguing that it isn't against the grain πŸ™‚

halcyon trail
#

Even in languages like Kotlin which overall have faaaaar better support for this stuff, it's still against the grain, but not as much

#

not you πŸ™‚

verbal escarp
#

me

halcyon trail
#

you πŸ™‚

grave jolt
#

no u

verbal escarp
#

πŸ˜‰

halcyon trail
#

it's me

#

couldn't be!

#

Who tried to mutate the immutable cookie jar again?

grave jolt
feral cedar
halcyon trail
#

nice!

#

but I can't take out a cookie 😦

verbal escarp
#

well, i'm arguing that it's up to your functions to not mutate in place but built new objects

halcyon trail
#

functions not mutating their arguments is not the same as immutability

grave jolt
#

!e speaking of... one of my favourite WTFs in python

xs = ([],)
try:
    xs[0] += [1]
except TypeError as e:
    print(repr(e))
    # damn this is a bad error. at least my application is in a consistent state

print(xs)
fallen slateBOT
#

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

001 | TypeError("'tuple' object does not support item assignment")
002 | ([1],)
halcyon trail
#

yeah this has come up in here like dozens of times πŸ™‚

verbal escarp
feral cedar
#

xs
your haskell is showing

grave jolt
#

yeah xs is 1 shorter than lst

#

😎

#

I also took on the terrible habit of naming variables after their respective typevars. It's like... higher-order Hungarian notation

feral cedar
#

ints, strs, intlists, listlists

verbal escarp
#

wasn't that abandoned.. in like.. the 80s?

grave jolt
#

I'm a retro guy

#

like, I could name Sequence[T] as ts if I'm super lazy and the function is very general

verbal escarp
#

iirc there even was a memo in microsoft that explicitely forbid that practice

grave jolt
#

yeah I'm not a fan of the normal Hungarian notation

halcyon trail
#

So in kotlin you have dataclasses, and you can set each individual property as val/var, basically whether that property can be reseated or not. THe issue is that if you make everything val, then you have this nested issue that lenses help with. if you make it var then things are nice but anybody can mutate your data class at any time. There's no protection even if you pass your data class into a function that it won't be mutated. So with a lens library and a bit more stuff I came up with this:

@optics data class Frob(val bar: Bar)
@optics data class Bar(val justBaz: Baz, val listBaz: FrozenList<Baz>, val mapBaz: FrozenMap<String, Baz>)
@optics data class Baz(val int: Int, val string: String)

    var y = Frob(
        Bar(
            Baz(8, "17"), immutableListOf(Baz(5, "hello")), immutableMapOf("hello" to Baz(8, "there"))
        )
    )

    y %= Frob.bar.listBaz { it + Baz(7, "goodbye") }

so you can see the better lambdas help., but IMHO it's still kinda awkward overall.

#

I use %= because in Kotlin, if you don't provide %= then y %= ... becomes y = y % .... πŸ™‚

#

a bit of a hack but I wanted to avoid repeating the immutable variable being "modified"

#

I still think that a fairly normal language (as opposed to hardcore FP languages) like Kotlin, Swift, etc could definitely do a better job supporting "immutable by default" without creating too much of a headache.
They are talking about it for the next Java I believe.

#

some kind of immutable data class type thing, believe it's called "value classes" but I could be wrong

verbal escarp
#

can't you make dataclasses immutable?

halcyon trail
#

You can, it's just that there's no syntactic sugar for working with them

grave jolt
halcyon trail
#

well, there is a bit, but not much

verbal escarp
#

hmm

halcyon trail
#

the problem is basically once you have nested, immutable dataclasses

#

it's a disaster

verbal escarp
#

nested is always hard

halcyon trail
#

Right, so lenses exist largely to solve that problem

#

Frob.bar.listBaz above is a lens

grave jolt
#

...or maybe fork it 😳 which I was planning to do, but I looked at the code and acquired existential dread

halcyon trail
#

in this particular case, Frob.bar.listBaz is a function. That function takes a Frob, and it takes a lambda, the lambda needs to map from the type of the member (Frob.bar.listBaz, so FrozenList<Baz>) to that same type.

grave jolt
halcyon trail
#

When the function is called, it gives you back a new Frob, that has had that nested member replaced, by calling the lambda on the old member and taking the result, and putting the result where that old member used to be

verbal escarp
#

ok

halcyon trail
#

But this is all a lot of ceremony, it can't really be done efficiently or maybe at all in-language so we have those annotations (@ in Kotlin) to do codegen to provide all this machinery

verbal escarp
#

why is called "lense"?

grave jolt
halcyon trail
#

it's also not very efficient or easy to optimize

#

because the lens focuses on a member of the class

#

and you compose lenses

#

to focus further and further in

#

In this case I'm actually composing two lenses effectively

neat thunder
#

hi

#

do anybody knows about PyQt5?

grave jolt
halcyon trail
#

there's a first lens that maps a Frob to a new Frob given a function that replaces the bar member

halcyon trail
#

and there's a second lens that maps a Bar to a new Bar given a function that maps the listBaz to a new listBaz

#

if you combine those two lens you get a new, "more powerful" lens that can map Frob to Frob by replacing the nested bar.listBaz member

grave jolt
verbal escarp
#

i found nested <anything> is not really nice to work with in python, we should import more tools for those kinds of jobs

halcyon trail
#

it's a fine idea but I think it's an important enough problem, if you really want to encourage immutability, that you should use language design real estate on it

#

well, if you do mutate then nested stuff is pretty nice to work on πŸ™‚

#

x.y.z = 5

#

x.y.z.append(10)

#

etc

grave jolt
#

*flashbacks to dotted trainwrecks when I tried to untangle endpoints that used a completely unrelated class stored in the aiohttp app parameters*

verbal escarp
halcyon trail
#

I mean the language can't protect you from the basic complexity of your domain

#

In python, you can use something like pydantic, declare nested schemas, it will auto parse from json/xml into your dataclasses

#

verify/convert any dated in a recursive way

#

etc

#

this is about all the help you can really hope the language will give you

verbal escarp
#

there has to be a better way :p

halcyon trail
#

Don't think so πŸ™‚

#

no silver bullet and all that

verbal escarp
#

a cross and a little bit of holy water would suffice

halcyon trail
#

but, there definitely is a lot of incidental complexity when it comes to changing nested, immutable stuff

#

so that could "easily" be fixed, i.e. you can imagine language features addressing this relatively straightforwardly

#

and an old priest and a young priest πŸ˜‰

white nexus
#

!d debug

fallen slateBOT
#

__debug__```
This constant is true if Python was not started with an [`-O`](https://docs.python.org/3/using/cmdline.html#cmdoption-O) option. See also the [`assert`](https://docs.python.org/3/reference/simple_stmts.html#assert) statement.
white nexus
#

why is this not used more often? I never have seen this in use except for checking the documentation

flat gazelle
#

most of the time you don't run python with -O, and if you do most of the things you want to do with this you can do with assert

white nexus
#

well yeah

#

but you wouldn't want to run the assert statements every time the code is ran, eh?

flat gazelle
#

assert will also be skipped under -O

white nexus
#

o

peak spoke
#

I tend to use it to setup logging, but pycharm is also annoying there where it pretends an if with it is dead code and will stop code inspection

#

It definitely could be used more as I've seen some weird solutions to determining if it's a debug environment, but maybe it's both not known that much and people don't want the other effects turning on the flag will do

white nexus
#

yeah

#

i wish there were other flags

#

like

#

i don't want to lose my docstrings

flat gazelle
#

isn't docstring elimination on -OO

peak spoke
#

It is

#

It's also pretty nice, I had unexpectedly large size improvements when distributing with the flag

white nexus
#

do you have the docs to the flag?

peak spoke
#

!d -O

fallen slateBOT
#
-O

-O```
Remove assert statements and any code conditional on the value of [`__debug__`](https://docs.python.org/3/library/constants.html#debug__ "__debug__"). Augment the filename for compiled ([bytecode](https://docs.python.org/3/glossary.html#term-bytecode)) files by adding `.opt-1` before the `.pyc` extension (see [**PEP 488**](https://www.python.org/dev/peps/pep-0488)). See also [`PYTHONOPTIMIZE`](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONOPTIMIZE).

Changed in version 3.5: Modify `.pyc` filenames according to [**PEP 488**](https://www.python.org/dev/peps/pep-0488).
white nexus
#

wow

#

lmao

ebon fractal
#

anyone down to code jam real fast?

paper echo
#

Files inside node_modules are linked from a single content-addressable storage

#

i still want ipfs package distribution but that's another story

white nexus
#

Thoughts on the proposed removal of the GIL?

verbal escarp
#

funny, i was just contemplating about using IPFS or something like that in justuse

still wolf
#

i made a simple game in a file and my main program is in different file
so i wanted that like when user gives input for game the main program should read from that game file and if not then it would leave that as it is
so how can i do that?

verbal escarp
#

but it's gotten a bit more complex because we want to compile our dependencies into a single .py file for drop-in installation, so we can't really use non-pure python dependencies i guess

verbal escarp
#

although i'm not 100% sure that answers your question

verbal escarp
#

i don't really care about the GIL on a daily basis, not sure how much it would impact my workflow, if at all

#

it may have an impact on how to approach parallelism and other naturally async problems

#

i'm wondering if our async protocol might make use of it somehow

#

if we're not constrained to run an event loop in the background anymore, maybe async could delegate transparently to threads in the future in some cases

#

(one of the reasons i find the idea of protocols awesome - free abstractions!)

golden oracle
#

Hey πŸ‘‹ guys just a question, it is possible to run Python from 2 different computers? I started to code on my desktop but when I move I would like to continue to code πŸ‘¨β€πŸ’» on my laptop but I have to download and install all libraries and dependencies.. there is a smart way to have all-in-one??

verbal escarp
#

hmm.. either you put your code and editor settings etc. in dropbox or some other cloud which will sync everything (which is what i do) or you can run a web-based IDE like pythonanywhere, vscode etc

verbal escarp
feral cedar
#

or pipenv to lock dependencies and stuff

grave jolt
#

s/pipenv/poetry

feral cedar
#

s/s\/pipenv\/poetry/

manic sundial
#

Not sure who was there yesterday for the conversation between map/filter vs generators but I've just jotted down a few lines to assess if there's a performance difference: https://goonlinetools.com/snapshot/code/#ssm1dv65tsofi0hxwu47w.
I do observe a slight difference (same memory usage but better speed for the functions using generators) but I am not sure this is outside of the error margin.

GO Online Tools

The Share Code Snippets Tool helps you to easily share code snippets online with your developer friends or colleagues.

golden oracle
astral gazelle
#

Use git with a lock file like a normal bean?

golden oracle
verbal escarp
#

you mean the site-packages? you could copy that dir and add it to your PYTHONPATH