#internals-and-peps

1 messages ยท Page 55 of 1

boreal umbra
#

On a related note, the way python handles class attributes is a bit awkward

raven ridge
#

They can have methods.
I mean, so can namedtuples. And namedtuples can be accessed by index, and C structs can't.

boreal umbra
#

True

#

I feel like it's rare to make a named tuple class and then do index lookup though.

raven ridge
#

which is exactly why dataclasses are better - they don't support that sort of access, rather than having it do something surprising ๐Ÿ˜„

boreal umbra
#

Don't data class instances each have their own hash table though?

raven ridge
#

You mean an instance dictionary?

boreal umbra
#

Right

#

Isn't that how it works? Any instance of a class that you make is secretly just a dictionary of its attributes that can look up methods for its mro?

raven ridge
#

depends - classes with __slots__ don't have a dict

boreal umbra
#

I've used slots before but it seemed inelegant to me.

#

Maybe I just don't understand it.

raven ridge
#

!e ```python
class Point:
slots = ('x', 'y')
def init(self, x, y):
self.x = x
self.y = y

p = Point(5, 10)
print(p.x, p.y)
print(vars(p))

fallen slateBOT
#

@raven ridge :x: Your eval job has completed with return code 1.

001 | 5 10
002 | Traceback (most recent call last):
003 |   File "<string>", line 9, in <module>
004 | TypeError: vars() argument must have __dict__ attribute
boreal umbra
#

I said instance hash table because I usually only use "dict" to refer to the class in Python rather than the underlying data structure in C.

#

But maybe that's wrong.

raven ridge
#

that is wrong - it is a real dict, the dict that vars returns

boreal umbra
#

I see.

#

But strictly speaking, python dicts are an implementation of hash tables, yes?

#

Or is there something that sets them apart?

raven ridge
#

Python dicts are implemented in terms of hash tables

#

it's not wrong to say that the instance has a hash table - it's just that the hash table that it has is encapsulated in a dict

#

the instance has a dict, and the dict has a hash table.

boreal umbra
#

Aha

#

How much memory is allocated for one dict before anything is added, do you think?

raven ridge
#

!e ```python
import sys
print(sys.getsizeof({}), "bytes")

boreal umbra
#

Is that in bytes?

fallen slateBOT
#

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

64 bytes
raven ridge
#

๐Ÿ˜„

boreal umbra
#

That's one way to answer

raven ridge
#

teach a man to fish ๐Ÿ˜„

boreal umbra
#

I guess that's pretty good. And then it grows if you ever have to use chaining, yes?

raven ridge
#

what do you mean by "chaining"?

boreal umbra
#

If two keys hash to the same value given the size of the table, don't they get chained?

#

So you iterate down the chain from there? And that's how it has an O(n) worst case?

raven ridge
#

each bucket in the hash table points to a linked list of entries, yes

boreal umbra
#

Ah, that's what I meant.

#

I wonder if it'd the same implementation as deque

peak spoke
#

mind that getsizeof doesn't look through elements recursively, and will be mostly useless on user defined classes

raven ridge
#

but it grows whenever you insert a new item, regardless of whether two things hash to the same value

boreal umbra
#

I thought each dict allocated space for a certain number of pointers

raven ridge
#

either the new item you add is the first one in a new bucket's list, or added to an existing bucket's list, it's still growing.

#

yes. and each of those pointers points to a linked list, which is of variable size.

boreal umbra
#

Aha

spark magnet
#

i'm not sure python dicts use a linked list of entries, but i'm not sure.

pseudo cradle
#

I was about to say

#

This sounds like compsci/C stuff. I don't think you get collisions in dicts, do you?

#

I actually don't know how Python handles dicts under the hood

#

But I'd assume you never have to worry about chaining in python

spark magnet
#

dicts are hashtables, and they can have collisions, but they are not visible to you

pseudo cradle
#

Right

#

It's all abstracted

peak spoke
#

python doesn't spend much time trying to make hashes unique

spark magnet
#

there were denial-of-service attacks against python web servers based on crafting requests that would collide in dicts

pseudo cradle
#

hah

peak spoke
#

is that the reason for the random string hashes?

spark magnet
#

it's impossible to make string hashes unique

pseudo cradle
#

lies

spark magnet
#

@peak spoke yes

pseudo cradle
#

Nothing is impossible

#

If you just believe

raven ridge
#

pigeonhole principle.

pseudo cradle
#

How does it apply here?

raven ridge
#

you can't generate a unique 64-bit hash for any possible string, because there are more than 2**64 possible strings.

pseudo cradle
#

Bah

#

Okay

raven ridge
#

the only way to give hashes that are guaranteed unique is to make the hash value arbitrarily large, which makes them far less useful.

pseudo cradle
#

Ideally in a hashtable we have 0 collisions

#

I'm mildly curious how python decides upon hash functions, but not enough to research it, lol

#

a polynomial hash I'd guess?

spark magnet
#

another way to have unique hashes is to have a specialized function for a known set of inputs.

raven ridge
#

indeed. for a perfect hash, though, the number of possible hash values needs to be greater than or equal to the number of values to be hashed.

#

so, no generic hash function that can accept arbitrary Python strings could generate hash codes guaranteed to be unique without making the codes arbitrarily large.

pseudo cradle
#

That makes sense

raven ridge
#

i'm not sure python dicts use a linked list of entries, but i'm not sure.
@spark magnet You're right. CPython evidently uses the other type of hash table, where collisions aren't handled by a linked list of values, but rather as a sequence of different array indices to probe.

#

TIL, and @boreal umbra

boreal umbra
#

Thanks, I'll have to look at this soon

raven ridge
#

instead of a bucket pointing to a list of values that fell in that bucket, it will keep trying new buckets in a predictable order until it finds an empty one when it wants to store a key, or a never used one when it wants to look up a key

sand lily
#

what is the best resource for learning the ins and outs of setattr ?

#

the documentation & every stack I've looked at have only helped a little, at best

charred wagon
#

What do you feel the documentation is missing?

sand lily
#

I feel like it isn't explicit enough in clarifying when exactly it (and other magic methods) are called

#

so when I try to write my customized versions of them, I get behavior that isn't what I expect and it's really tough for me to diagnose why

charred wagon
#

That's documented in the data model

sand lily
#

is it somewhere besides the description for __setattr?

charred wagon
#

I don't know. It's a long document and I'm not intimately familiar with it.

#

But if it's going to be documented anywhere, it's most likely going to be in there.

sand lily
#

alright well, I appreciate your attempt to help

#

does anyone else have any better resources for learning about setattr and other magic methods?

feral bane
#

what are you having trouble with @sand lily

sand lily
#

if I write a simple class, I'm trying to figure out exactly when setattr is called within it

#

so I know where to put a customized version of it

#

for ex. if I want to create a debug tool that notifies me whenever a class variable or instance variable is set

charred wagon
#

As the docs state, __setattr__ is used if it's defined, otherwise __dict__ is used. Did you not find that to line up with your observations?

feral bane
#

one important thing to note is that it's called always when an attribute is set on the object

charred wagon
#

Though I don't know when __setattr__ wouldn't exist in normal circumstances

feral bane
#

if you need to set something without using it [which may be needed especially when setting up structures used by __setattr__ itself] you need to use __dict__ directly or super().__setattr__]

#

yeah, it always exists. __dict__ is used [along with descriptor behavior] by object.__setattr__

#

the behavior of __getattr__ and __getattribute__ is more complicated [though all the logic for that is handled, again, in object.__getattribute__, so there's again no such thing as it not existing and you can use super() to make multiple levels of override compose]

#

if you have an example that's not working i can look over it if you want

sand lily
#

is it ok to post code in here?

lament leaf
#

Looking at previous posts, I'd say yes.

sand lily
#
class Foo2(object):
    
    def __setattr__(self, attr, value):
        print("setting {0} to {1}".format(attr, value))
        self.__dict__[attr] = value
    
    
    class_attr = 0
    
    def __init__(self, x):
        self.x = x
    
    def bar(self, v):
        return (self.x, v)

a = Foo2(1)
#

so this is my simple example. I believe I've taken setattr and redefined it by just having it print out what it's doing

#

so when I run the last line, a = Foo2(1), it starts the class and what I expect is a printout for class_attr and another one for x, but I only get one for x

#

and then I have a more complex example where I move my setattr redefinition to a metaclass, and get no printouts at all

#

although I maybe just don't understand metaclasses enough yet, so I figured I'd start as simple as possible

charred wagon
#

__setattr__ is only used by instance attributes

#

Note that it has self as a parameter

#

Class attributes are set by updating __dict__ directly

sand lily
#

so how could I adjust this to capture both class attributes and instance attributes?

feral bane
#

@charred wagon i don't think that's true

#

[er, but it wouldn't be your __setattr__, unless you've written a metaclass]

#

plus class_attr isn't set when your object is created, it's set when the type was created

charred wagon
#

I'm pretty sure __setattr__ is for instances only, but not sure if __dict__ is directly used for class attribute

feral bane
#

the trick is that it's __setattr__ on the type object

#

which you can't do anything about without a metaclass

charred wagon
#

Do you mean it may use type.__setattr__

#

Yeah ok

feral bane
#

but types aren't special for this, is my point.

#

the more important part is that you're not actually setting Foo2.class_attr = 0 at any point

#

you're setting it in the class dictionary before the class is created

#

not doing it when each object is created

sand lily
#

yeah I had suspected that I need a metaclass to do what I want, but I couldn't get it to work and didn't understand why so I simplified first so I could understand the individual pieces

#

so, it makes sense that my custom setattr is only going to work for instances of the class that I create afterwards

feral bane
#

even with a metaclass i don't think you'll get __setattr__ called in this particular scenario

#

it'd only be called if you did Foo2.class_attr after the class is created

sand lily
#

that lines up with my results so far so I believe it

#

but it still leaves me wondering how to write a metaclass that has a setattr that is actually useful to me

feral bane
#

[now, of course, you're free to also add hooks that inspect the dictionary before and at class creation time]

#

you could override your metaclass's __new__ to print all the contents of the dictionary

#

or have a __prepare__ that creates a dictionary that prints when things are added to it [the dictionary created by prepare is used during class creation but does not become the class dictionary - its contents are copied into the class dictionary]

sand lily
#

hmm ok, so it sounds like I need to look into the other magic functions

feral bane
#

i am curious why you feel the need to print definitions that are part of the class body and never changed though

sand lily
#

specifically, I'm playing around on codewars and all the kata I've done so far have been easy, just algorithm stuff

#

this is the first one that tests concepts of python that I never really learned, like metaclasses

feral bane
#

link?

sand lily
#

so rather than skip it I wanted to really understand the problem before I solved it

#

sec

feral bane
#

i find metaclasses fascinating and i have spent quite a bit of time playing around with the details

#

did you know metaclasses don't have to be derived from type, or even classes at all?

#

[the object created does have to have a type that is an instance of type, but the metaclass is free to choose a different one from itself]

sand lily
#

I did not know that, but that's because I don't really understand what a metaclass is or does yet, let alone how it interacts with regular classes

#

the reason I wanted to print was because I figured if I could get it to print, I know it's working and I can change it to append and solve the kata

#

so far I've figured out how to do the first part (capture the method calls)

#

but the 2nd part (attribute accesses) is tricky

feral bane
#

huh really?

#

the method call part seems trickier to me

sand lily
#

well they were both way tougher than all the other kata I've done

feral bane
#

anyway, i don't think the assignment inside class initialization really counts for what they're asking for

sand lily
#

but at least I pieced together a solution from a million stack overflows that worked

#

wasn't sure if that was the case, but I figured I'd shoot for it anyway in case it was

#

if I can get a metaclass to capture both instance and class variables then more power to me right?

feral bane
#

well

#

not really

#

if the real tests work the way their sample tests do, adding extra captures will mess it up

#

i think it does want to capture class variables [or you wouldn't need a metaclass], but that's not the same as wanting to capture initialization of class variables

sand lily
#

what is the difference between the two?

feral bane
#

well, for one thing, initialization can't be captured by setattr ๐Ÿ˜›

sand lily
#

excellent point

feral bane
#

[it's also not plausible for it to be a performance bottleneck, getting into the supposed reason for the project]

sand lily
#

I'm just concerned that this kata will do the same thing that most other kata do, which is give you an easy simple test, and then once that works test it on way more complex examples

#

that you don't yet have access to

#

but that's probably just anxiety talking

feral bane
#

looking at it again, I don't think it's clear that they want to log access to class variables at all

sand lily
#

so, I'm happy to scrap the class variable part

feral bane
#

it seems to me that you wouldn't need a metaclass for that, but

#

i don't know

#

it talks about getter/setter methods that you might create by meta class.

#

which is... a very different approach than what I would use

#

what really bothers me is that it doesn't permit modification of the base class, which makes this a lot harder for no good reason

#

you're apparently supposed to use the metaclass to inject methods, but how do you do that without injecting the methods redundantly to all subclasses

sand lily
#

yeah, I could solve it right now with what I understand, if I could do that

#

how do you inject a method with the metaclass? I thought I was doing that, but wasn't getting the result I wanted

feral bane
#

they don't provide a sample definition of a derived class either

#

er what were you doing

#

you can put whatever you want in the dictionary in your metaclass.__new__

sand lily
#

here's my full attempt thus far

#
class Debugger(object):
    attribute_accesses = []
    method_calls = []

from functools import wraps

def debug(f):
    @wraps(f)
    def wrapper(*a, **kw):
        method_call = {}
        method_call.update({'class': f.__qualname__.split('.')[0]})
        method_call.update({'method': f.__qualname__.split('.')[1]})
        if a:
            method_call.update({'args': a})
        if kw:
            method_call.update({'kwargs': kw})
        Debugger.method_calls.append(method_call)
        return f(*a, **kw)
    return wrapper

def debugmethods(cls):
    for key, val in vars(cls).items():
        if callable(val):
            setattr(cls, key, debug(val))
                
    return cls
  
class Meta(type):

    def __setattr__(cls, attr, value):
        print("setting {0}.{1} to {2}".format(cls.__name__, attr, value))
        return super().__setattr__(attr, value)
           
    def __new__(cls, clsname, bases, clsdict):
        obj = super().__new__(cls, clsname, bases, clsdict)
        obj = debugmethods(obj)
        return obj
    



class Foo(object, metaclass = Meta):
    class_attr = 5
    
    def __init__(self, x):
        self.x = x
    
    def bar(self, v):
        return (self.x, v)
#

the setattr in my metaclass doesn't work, and I was on the road to trying to figure out why, which led me here

feral bane
#

ok, you're not doing anything there about instance variables

sand lily
#

yeah, when I run this, setattr reports the creation of init and bar in Foo

#

but not the variables

#

so that's another piece of the puzzle I don't understand yet

feral bane
#

you need to add a '__setattr__' to clsdict in __new__

#

[and what if there already is one? more complexity that I have no idea if the tests care about or not]

sand lily
#

isn't it just replacing it / redefining it?

feral bane
#

well presumably if it already has one then you don't want to interfere with it being called

sand lily
#

oh I see, b/c then it will recursion loop me out of the game?

feral bane
#

er no

sand lily
#

which is a problem I've run into before

feral bane
#

it'd just, not do whatever it's supposed to do

#

since you don't want to replace it you want to layer on top of it

#

but i don't know if they care about that case at all

sand lily
#

so would the setattr be added in the definition of new?

feral bane
#

yeah

#

once you have your own getattribute it might be worth changing your approach to method call logging too

sand lily
#

good thinking, what I have works but it feels awfully clunky

feral bane
#

what i'd do is

#

leave the methods themselves alone

#

but in getattribute, if the result is a function or a bound method [not any callable], wrap it in something that does the logging and then calls the original method

#

maybe even only if it's a bound method

#

gah

#

part of the problem is, in the real world you'd at least have a vague idea of if there are any funky patterns you have to work around like functions or other callables stored as data

#

to account for all of those you'd have to implement the whole damn descriptor logic in __getattribute__ to make sure you don't wrap anytihng that shouldn't be wrapped

sand lily
#

eek

feral bane
#

and they haven't provided nearly enough sample tests for me to know if any of this is what they want or not

sand lily
#

ok I see how that might be different from this toy example

#

yeah I'm hoping that a solution that beats their small sample is enough to beat their big one too but I'll find out I guess

feral bane
#

[i feel like if it is this really should be higher level, but then again i've never done code katas myself so i could just have a wildly different understanding of what the levels mean]

sand lily
#

yeah I do not have a great grip on what the levels imply yet, all I know is that every one I've done prior to this point has been relatively easy and this one required/is still requiring a LOT of study

#

so I'm trying to get a grip on the difference between the solution I wrote for the method calls, and the one you proposed

#

right now I'm defining a wrapper that adjusts functions, then creating another function to replace a class's functions with that wrapped version IF it's callable, then defining a metaclass that applies that function to all of its initialized methods - is that an accurate description?

feral bane
#

ugggggh neverfuckingmind

#

my approach can't log the call to dunder methods, and the sample tests require logging __init__

#

yours is right

#

i thought i was so clever

#

well

#

i've managed to make an implementation that doesn't give a crap about class stuff but passes all the sample tests which are for instance stuff

#

woo my implementation passes the full tests too

#

i guess this wasn't as sophisticated as all that...

#

@sand lily

#

ah shit, i deleted my solution

#

when i went to the sign up page

#

ah well, I know I passed, and I also know many of the ways in which the implementation is deficient ๐Ÿ˜›

#

so, given that the sample tests, at least, rely on each log item it expects having a specific index, definitely don't try to log class attributes

#

and your approach looks ok for methods

#

the getattribute and setattr functions you have to inject are just two lines, one to log and one to do the original access [i got fancy but you can probably just get away with dict tbh] - do it after your debugmethods loop to satisfy the requirement of not logging them

#

anyway goodnight

sand lily
#

thanks for your help @feral bane I learned a lot ๐Ÿ˜

feral bane
#

no problem

unkempt rock
#

@fossil pumice Thanka man!

fossil pumice
#

yep, no problem

vivid dew
#

For the time.sleep function would it restart the whole program or begin where it left of?

hasty thistle
#

it would just pause the program, so continue where it left off

vivid dew
#

Ok cools thanks

fathom harness
#

Can anyone explain what is pigeonhole and why is it used so much in python?

magic python
#

@fathom harness do you have an example

fathom harness
#

Na I just heard from my friend

#

He's a programmer in C+

deep coral
#

is c+ a new language

raven ridge
#

@fathom harness it's possible you're thinking of the pigeonhole principle, a mathematical principle simply stating that if you have N containers and want to put more than N objects into them, at least one container must hold more than one object. I've often used this to explain why hash collisions are inevitable.

boreal umbra
#

How probable is it that there will ever be an Android api for python?

#

There's an app I use to make android programs that uses a flow chart. I think I'd find it a lot easier to maintain the programs if I could write an async python thing.

clever escarp
#

@boreal umbra I assume you're aware of kivy and how that process of compiling into android apk's works? It's pretty involved and I assume there's just no good way to use python on the android os because of how permissions work, there's probably a better explanation available somewhere

boreal umbra
#

@clever escarp I'm not. I could look it up but I'm just musing during my shift.

clever escarp
#

OK, long story short, you have to use a program called buildozer with a spec file that tells it what python packages to include. Buildozer downloads all the necessary android packages and also handles translating python into java. It's been a while since I've looked at the details, but the process is such as hassle that it implies there is no good way to natively run python based apps, does that make sense? It's the officially recommended process on the kivy website, and it sucks. The guys working on kivy are pretty knowledgeable so if something better existed I'm sure it would be recommended

boreal umbra
#

Is there a reason why only Java and Kotlin are supported?

feral bane
#

@weak solar P.S. I know we'd talked about changing it to a class variable anyway, but just so you know, global declarations apply to the whole function so they should generally be at the top of the function instead of inside an if statement

weak solar
#

Yeah, and that's how it got fixed.

#

I just added the top part, so I didn't think of that.

#

Usually, I have them at the dead top.

unkempt rock
#

is adding a module to PYTHONPATH the only way to import a module from a parent directory?

flat gazelle
#

Except messing with importlib, yes afaik

#

Or just running from the parent directory with a __main__.py

unkempt rock
#

hmmm

#

pythonpath is shared between all python programs running on the system right

flat gazelle
#

What you sometimes see is sys.path.append(Path(__file__).parent)

unkempt rock
#

lets say i had two python scripts running at the same time, they share the same pythonpath right

flat gazelle
#

Depends. It is an environment variable and follows the same rules as any other. I would link sth, but am on phone

unkempt rock
#

cuz i want to keep my projects isolated from each other

#

so i kinda dont want to mess with env vars

flat gazelle
#

If you wish to modify that path, do it in code with sys.path

#

Not with env vars

unkempt rock
#

i mean like if i had two projects running at the same time

#

if one project changed pythonpath

flat gazelle
#

They would be different

unkempt rock
#

oh

#

they r different

flat gazelle
#

Env vars are per process

unkempt rock
#

i didnt know

#

so every new process generates a new path

#

ic

raven ridge
#

they're inherited from the parent process.

alpine thistle
#

Hi, I have a class which isn't supposed to be an instance, but I need to pass it's reference into a class member. How can I do that? I tried to avoid it by importing the "PipeClient" class in script with target class "Commands" but it raised error messages

lost nexus
#

type(self) or self.__class__ is the class of the instance

peak spoke
#

You'll have to do it after the definition as the class is not available in its definition, or through something like a metaclass

alpine thistle
raven ridge
#

in other words:

class PipeClient(object):
    __write_pipe = None
    __read_pipe = None
    @classmethod
    def connect(cls):
        ...
PipeClient.commands = Commands(PipeClient)
alpine thistle
#

@raven ridge I was afraid of something like this because of autocomplete. But it works pretty well now. Thanks

spark magnet
#

@alpine thistle btw, don't bother with double-underscore names like __write_pipe

raven ridge
#

@spark magnet what's your take on the "private" name mangling? Why avoid it? Should it ever be used?

spark magnet
#

@raven ridge i just don't see the point. those names weren't create to be private, they are they to avoid conflicts in deep inheritance hierarchies.

#

they make the names ugly, and hard to debug, and don't really make them private. This is just Java culture bleeding over to Python.

raven ridge
#

Do you think it's worth adding them when extending a library class that may have been subclassed by other users outside your control?

minor locust
#

qq: how do I get 9 from '9' - '0'

#

do I need some transfomration

spark magnet
#

@raven ridge that might be reasonable (like the deep inheritance case): so you don't have to know your entire inheritance chain.

minor locust
#

ord('9') - ord('0') it seems

#

or there's a better way?

raven ridge
#

Yeah, that's usually my take - I usually don't use them, but I usually don't even use them when I'm extending a class that may have been subclassed - and I probably should in that case, heh

spark magnet
#

@minor locust what about int('9') ?

crystal pebble
#

Why does Python lack privates anyway?

spark magnet
#

@crystal pebble Python's style is an unstructured language that you can use in structured ways.

crystal pebble
#

:(

#

Do they flip a coin when making some of these decisions?

spark magnet
#

they have long email threads.

raven ridge
#

but even in that subclassing case, if I were to use them for adding new attributes to a function that may have been subclassed, a) it only works for attributes, not methods, and b) it means that there's no consistent naming between new and old attributes, which bothers my sensibilities as well - it seems like there's no great answer there.

spark magnet
#

@crystal pebble but "no privates" happened long before it was "they".

#

why does Python need privates?

crystal pebble
#

It doesn't. It's just the only OOP language I'm aware of of that doesn't have them

peak spoke
#

Haven't used java but never had a need for any property protection, sometimes a _ prefix to keep the code cleaner

raven ridge
#

JS doesn't, nor does Perl (afaik; I'm no Perl expert)

crystal pebble
#

JS isn't a real language though, so I don't know if that counts as fao examples of just one :P

raven ridge
#

privates cause more problems than they solve, I'd argue. Compare the easy of monkeypatching mocks in for unit testing in Python to doing it in Java or C++ - it's way more difficult in a language without duck typing and with privates.

minor locust
#

maybe stop "real" language nonsense, JS gets shit done

#

it's real as any

raven ridge
#

Ruby doesn't have private variables either.

crystal pebble
#

I hate privates. They just seem like extra l boilerplate

raven ridge
#

@minor locust it can be real and still be bad, though. ๐Ÿ˜„

crystal pebble
#

Func: I can't, I hate JS too much

#

JS is almost everything I hate about languages rolled together into one language lol

void fox
#

Most languages have a specific strong point so it's hard to call them bad, unless they really are just bad

raven ridge
#

JS has very good performance for a scripting language, but beyond that, from a language design perspective, it has a lot of decisions that are strange or limiting. Prototype based OOP isn't better than class based, it's just different. Weakly typing isn't better than strongly typing, it's just different. JS's biggest strength is its ubiquity, not anything about its language design.

crystal pebble
#

Weakly typing isn't better than strongly typing

Why does weak typing exist again?

#

I always forget

spark magnet
#

"weak typing" isn't a black/white thing. it's a spectrum.

#

also, people use weak/strong to sometimes mean dynamic/static

crystal pebble
#

I like strong static typing. Now if only type hints meant something for the interpreter :O

spark magnet
#

I think we run the risk of people over-specifying their types.

crystal pebble
#

But I also (actually) believe that if 1: ... is bad so I'm kind of an extremist

raven ridge
#

"weak typing" isn't a black/white thing. it's a spectrum.
@spark magnet How so? Either every function and operator accepts every type of input (potentially returning garbage if the types aren't reasonable or compatible), or functions and operators validate that the arguments are of reasonable and compatible types and signal an error if so. What's the gray area?

crystal pebble
#

A boolean is a boolean, and only boolean are booleans

See, Python seems really well suited to avoid making types too strict

#

All those dunders seem really great for giving objects properties

spark magnet
#

@raven ridge JS lets you do 1 + "1", python doesn;t. But Python lets you do 1 + 1.0.

raven ridge
#

true, but it's a question of what to do when the types are not compatible

spark magnet
#

so JS is more weakly typed (it will coerce more things) than Python.

raven ridge
#

does it ever not coerce? Does it ever raise something akin to Python's TypeError?

crystal pebble
#

Maybe Python already does this with duck typing, but the ability to define behaviors and ignore types would be super nice

Requiring __hash__ instead of being strict about the type of a variable would be really nice, IMO

#

(I think in the case of hash that's already true though)

spark magnet
#

@raven ridge JS will raise errors for some combinations

#

Python mostly duck-types, and doesn't care about the actual type.

gleaming minnow
#

might want to fix that typo @crystal pebble

raven ridge
#

I thought it always returned NaN or undefined, but I'm no expert...

crystal pebble
#

Lol thanks for the heads up

raven ridge
#

that's mypy's "structural subtyping" that you're describing.

#

it exists, but it's pretty limiting, and it cannot begin to express everything that you can do with duck typing.

#

@crystal pebble ^

crystal pebble
#

Hmm... Well, I hope what I'm asking for makes sense

#

I hate to say anything positive about C++, but constraints and concepts seem like a really nice step forward

spark magnet
#

Use mypy, and see what it can do

crystal pebble
#

I do :+1:

raven ridge
#

and have you noticed the structural subtyping stuff it supports?

#

Python and C++ approach this from different directions. With Python, it's possible to do things that the typing system doesn't (yet?) have the ability to express. With C++, static typing means you're more constrained.

pseudo cradle
#

Dynamic typing makes me feel like I'm doing trust falls and hoping the other person doesn't drop me on my ass

raven ridge
#

if they do, an exception is raised, and life moves on.

crystal pebble
#

No, TBH I haven't written more than a lines of code in months. MyPy is my first line of defense but I only use it for super simple typing :(

#

Things like what though?

raven ridge
#

I think it supports more of what you're thinking in the concepts direction than you realize.

#

see things like Reversible, SupportsAbs, Awaitable, etc

crystal pebble
#

I think I need to stop thinking about FP so much. To me all these rules and behaviors are almost a part of the type themselves :/

#

Like... you make a type, and then you make it follow some rules. Once you do that you get a ton of other things for free

spark magnet
#

How does FP fit in here?

#

That sounds like Python

crystal pebble
#

Everybody tells me my understanding of duck typing is wrong. I base almost all of my thinking on FP stuff though :(

spark magnet
#

lets fix up your undertstanding of duck typing then.

raven ridge
#

Like... you make a type, and then you make it follow some rules. Once you do that you get a ton of other things for free
@crystal pebble That sounds like a succinct description of Python's dunder protocols.

crystal pebble
#

So maybe other people were wrong then

#

Wooh lemon_swag

narrow kettle
#

Weakly typing isn't better than strongly typing
i cant even begin to agree with this, static vs dynamic is discussable point, but weak typing just leads to awfully hard to find bugs

raven ridge
#

That doesn't contradict what I said (and I agree with you, heh)

narrow kettle
#

ya edited

#

just woke up ๐Ÿ˜

#

implicit behavior is rarely a good thing and to base an entire type system on it just leads to bad things

spark magnet
#

@narrow kettle do we have the same definition of weak typing?

narrow kettle
#

id hope so, its a spectrum oc but its a pretty clear distinction

#

grab a help channel @alpine thistle

spark magnet
#

@narrow kettle which languages are you saying use weak typing?

narrow kettle
#

Js

#

and C

#

are probably the two biggest ones

spark magnet
#

but JS works the same as Python.

narrow kettle
#

Js has pretty lax type coercion

raven ridge
#

C!?

narrow kettle
#

C is weakly typed yes

raven ridge
#

no, it's very much not... if you pass a char* to a function that wants double, you get a compilation error

narrow kettle
#

C very much is, you can convert pretty much any type and the compiler will be ok with it

#

the terms weak and strong are nebulous oc, but C is for sure considered a "weaker" language

#

because its most certainly not strongly typed

spark magnet
#

i've given up on "weak typing" meaning anything.

narrow kettle
#

its a range, theres not HARD rules about it

#

but its a good shorthard way to discuss various type systems

raven ridge
#

C very much is, you can convert pretty much any type and the compiler will be ok with it
@narrow kettle Not implicitly. You can tell the compiler that you intend the bits to be interpreted in a different way, but I would certainly not call that weak typing.

spark magnet
#

but here we have two people who agree it's a range, but don't agree where C falls in that range.

narrow kettle
#

that is weak typing tho...

crystal pebble
#

Isn't weak typing just implicit type conversions?

narrow kettle
#

not fully

#

weak also means how easily the compiler will allow you to attempt to coerce types to eachother

#

which the C compiler will let you attempt freely

raven ridge
#

that's not a definition of "weak typing" that I've ever heard before.

narrow kettle
#

you can have a static weak langauge

spark magnet
#

next lets do "lexically scoped"! ๐Ÿ™‚

narrow kettle
#

im out on that one lol

crystal pebble
#

Really? I've always heard weak typing means implicit conversions are allowed, strong typing means they're not

narrow kettle
#

been down there way to many times lol

crystal pebble
#

But I also rarely paid attention to or even attended class

narrow kettle
#

it can also be taken to mean how free the compiler is with allowing you to TRY to convert a type

raven ridge
#

I'd say that implicit conversions are weak typing, and explicit conversions are part of stronger typing systems - the fact that you need explicit conversions is because the type system is stronger.

narrow kettle
#

i never said Cs wasnt stronger then Js

#

i said they are both examples of a colloqiually weak lang

raven ridge
#

yes, and that's what I'm disagreeing with.

narrow kettle
#

C certainly isnt strong, you can do whatever you want basically

pseudo cradle
#

I'm with gg here

raven ridge
#

it is strong, there are relatively few implicit conversions (perhaps more than there should be, re signed vs unsigned types)

pseudo cradle
#

C is strongly typed

crystal pebble
#

When you say signed vs unsigned you mean +/- as opposed to just + numbers, right?

pseudo cradle
#

Yes

#

you take up one extra bit for a positive/negative sign

crystal pebble
#

Yee, just making sure I follow

pseudo cradle
#

even then, you have uint vs int, so...

narrow kettle
#

C is STATICALLY typed, it is not strong

#

strong would imply that the compiler will validate type conversions for correctness

#

it does not do that

raven ridge
#

again, that's a definition of "weak typing" that you seem to be making up on the fly.

narrow kettle
#

the compiler will verify correctness within your declared types, but it does not verify the conversion between them

#

thats quite literally an example of Cs type system being MUCH looser

pseudo cradle
#

Cursory google search seems to indicate that there are arguments for being less strongly typed than C# and Java

#

But also that there's no widely agreed upon definition

narrow kettle
#

c# has a pretty strict type system as does java, c# will tell you what casts are invalid

pseudo cradle
#

Well, they're all strongly typed compared to assembly

#

๐Ÿ˜„

raven ridge
#

Java has System.arraycopy(), which is just memcpy. You can break out of Java's type system pretty easily.

crystal pebble
#

Isn't there some typed ASM now?

#

Maybe that's WASM?

narrow kettle
#

ya javas type system is interesting

#

i dont claim to know java so i wasnt going to comment

pseudo cradle
#

Maybe, I don't keep up with all the different ASM

narrow kettle
#

all i know is that generics do type erasure

pseudo cradle
#

Haven't used assembly since college

crystal pebble
#

Same. Low level stuff makes me want to die :(

narrow kettle
#

i pretty much only use C# and python now adays

#

prob should learn js too tbh

crystal pebble
#

Don't

narrow kettle
#

ive heard Ts is nice

crystal pebble
#

If you're gonna waste your time on JS, at least try TS or maybe PureScript

#

Or just transpile instead

narrow kettle
#

need wasm to be a bigger thing asap

north root
#

let's try to keep this channel on-topic with Python, please

crystal pebble
#

Vectorization

pseudo cradle
#

Here's a segway, think Python has the ability to beat other languages on microcontrollers?

#

or the potential to, one day?

crystal pebble
#

Any tips on writing cache friendly code? Or code that the computer can vectorize?

#

That are specific to Python, I mean

raven ridge
#

Here's a segway, think Python has the ability to beat other languages on microcontrollers?
@pseudo cradle That's a "segue", ;)
But yes, check out MicroPython and CircuitPython

pseudo cradle
#

How sure are you I wasn't talking about hopping on a 2 wheeled vertical contraption and moving from one topic to another

raven ridge
#

it beats other languages on microcontrollers in the same way as it does on any other sort of machine. It's usually much less memory efficient and slower, but it's much easier to write and maintain.

pseudo cradle
#

(But yes, my mistake)

raven ridge
minor sinew
#

put an asterisk on "easier to maintain" if you happen to work with people who are clumsy lol

#

languages like python and matlab really rely on people paying attention to the inputs and outputs of functions

unkempt rock
#

never gotta worry about matlab when trump bans it lol

pseudo cradle
#

Wait what

#

I love my matlab

#

@minor sinew I think the same could be said for any language?

raven ridge
#

Sloppy coders can do more damage in a dynamically typed language than a statically typed one

#

Because so much more is based on convention, naming, and documentation than is enforced by the compiler

pseudo cradle
#

Yeah, that is true

#

I'm surprised what the Python compiler lets you get away with, honestly.

shy belfry
#

I just want to say I'm thankful for the walrus operator:python if reddit_user := session.query(RedditUser).filter(and_(RedditUser.discord_user == ctx.author.id, RedditUser.verified == false())).first():

glass robin
#

well the walrus operator only gains you only one line

radiant fulcrum
#

that low key seems like that would be a bad use of that operator

tawdry gulch
#

It's good for code golfers I feel lol

sullen widget
#

so assign and return?

#

kinda like ++i would do?

undone hare
#

well the walrus operator only gains you only one line
It also gains some speeds, since you won't have to load the name twice, you can just duplicate the stack value ยฏ\_(ใƒ„)_/ยฏ

brazen jacinth
#

nitpicking, but yea

devout heart
#

can someone help me understand the difference between a regular method and a method with a classmethod decorator?

spice pecan
#

A regular method receives the class instance as its first argument (traditionally named self), while a classmethod receives the class itself as its first argument (cls)

#

You can also call classmethods directly from the class, without creating an instance

#
>>> class Example:
...     @classmethod
...     def some_classmethod(cls):
...             print(cls)
...     def some_method(self):
...             print(self)
... 
>>> e = Example()
>>> e.some_method()
<__main__.Example object at 0x0000022B546C2640>
>>> e.some_classmethod()
<class '__main__.Example'>
>>> Example.some_classmethod()
<class '__main__.Example'>```
#

@devout heart

devout heart
#

but if I initialize the class, will both kinds receive the same value as the argument?

wide shuttle
#

No, the class method will receive the class object itself as the argument

devout heart
#

so I won't be able to edit any instance attributes?

wide shuttle
#

You don't have direct access to the instance, no

#

However, if you need access to the class as well as the instance, you could use a regular method and access the class through the instance

#

!e

class MyClass:
    def method(self):
        print(self)
        print(self.__class__)

my_instance = MyClass()
my_instance.method()
fallen slateBOT
#

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

001 | <__main__.MyClass object at 0x7fce682059d0>
002 | <class '__main__.MyClass'>
devout heart
#

ohh

#

why would I want to access the class though? won't the instance be what I need?

#

is there a special use case where this becomes helpful?

wide shuttle
#

You typically don't have a need for that no, but maybe you want to assign a class attribute or the name of the class

#

It's sometimes used in the __repr__ to avoid hardcoding the name of the class to allow for subclassing without having to override the __repr__

devout heart
#

oh

#

thanks for explaining!

boreal umbra
#

@devout heart a popular use of class methods is to have alternative constructors

devout heart
#

wdym?

boreal umbra
#

You only get one __init__ method per class. Often that's all you need because you can have default arguments in the signature for init

#

But if some instances need to be created in a special way that doesn't easily map onto the signature for init, you can make a class method that does that mapping, creates the instance, and return it.

devout heart
#

oh

minor sinew
#

@pseudo cradle you could say it for any language, but it's just a lot easier in statically compiled languages to know exactly what your inputs and outputs are than in runtime compiled languages because they force you to be explicit about the input and output data types

boreal umbra
#

Are there any ways that OOP in Python is especially counterintuitive or weird to people who learned OOP differently?

#

I know a lot of people get upset over the lack of method overloading

visual shadow
#

Self not being a magic Keyword. I love it, and have had to defend this design choice against some very vehement opposition

#

Self or this or something similar.

boreal umbra
#

A friend of mine didn't like that either @visual shadow. It makes more sense when you know that you can technically call methods statically.

raven ridge
#

The lack of privates makes OOP harder to explain. It's easier to sell encapsulation as an advantage of classes when things are actually rendered inaccessible outside the class

boreal umbra
#

I never liked encapsulation because I was taught to create getters and setters in Java even if they don't do anything.

#

So my first impression was that it's pointless.

raven ridge
#

It's not pointless, it's that Java doesn't have descriptors, so there's no way to make instance.attribute perform something more sophisticated when the need arises, so you need to always use getters and setters to avoid painting yourself into a corner

boreal umbra
#

So it's just inelegant

raven ridge
#

Well - Python's approach is more flexible, but that comes with a higher runtime cost. In Java you know that a.b is an attribute lookup. In Python you need to figure out whether it's an attribute lookup or a method call to a property every time you see it. That isn't free.

boreal umbra
#

Fair enough

#

I'm going to keep hating getters and setters though.

spice pecan
#

C# handles this well with properties and autoproperties

#

On the outside it looks like attribute lookup, but it's then replaced with get_PropertyName and set_PropertyName calls

boreal umbra
#

Interesting

#

I was reading Google's style guide for Python. They mandate that you should only use properties if the computation it does is light weight

spark magnet
#

that's so the API makes sense to callers

boreal umbra
#

Which I think is fair because I think people except attribute lookup to be quick but don't necessarily have that expectation about method calls.

spark magnet
#

right

final whale
#

what about cached properties then ?

spark magnet
#

that's a case where most of the time, it's very fast.

boreal umbra
#

I've been working on a project that uses cached attributes so that disk reads only happen (and only once) if that information gets used.

shy belfry
#

that low key seems like that would be a bad use of that operator
@radiant fulcrum I was wondering myself as I wrote the code but couldn't figure out why it would be bad - do you have any concrete reasons?

radiant fulcrum
#

in that example you seem to only be saving maybe 1 or 2 lines

#

for that sake of a very long 1 liner if statement that is harder to read

shy belfry
#

Hmm... That is true. The walrus in this case is resulting in super long lines...

#

So is that the only way to determine poor use of walrus?

radiant fulcrum
#

i mean that line goes against the general Pep8 system

shy belfry
#

I have my line length at 119 for all my projects. x)

radiant fulcrum
#

just because the operator exists doesnt mean you should use it in every situation

shy belfry
#

Agreed. I noticed since learning about it I've been using it a lot, but also need to learn when not to use it.

pseudo cradle
#

Okay, I have to ask

#

Wtf is a walrus

wide shuttle
#

It's the nickname of the operator used in assignment expressions (:=)

#

During discussion of this PEP, the operator became informally known as "the walrus operator". The construct's formal name is "Assignment Expressions" (as per the PEP title), but they may also be referred to as "Named Expressions" (e.g. the CPython reference implementation uses that name internally).

pseudo cradle
#

ah... because it looks like a walrus

mystic cargo
#

;=

narrow kettle
#

how often do yall find yourselves using the walrus

#

im on 3.7 rn

radiant fulcrum
#

not often tbh

narrow kettle
#

but in the course of my code i find tons of cases where im like "damn an assignment expression would be nice here"

radiant fulcrum
#

i maybe use it once with like 10k lines of code

narrow kettle
#

interesting

radiant fulcrum
#

alot of the stuff i do tho i try to keep compatible with 3.5.5+ tho

narrow kettle
#

ive found multiple cases just today where im like whew that would be nice

near coral
#

walrus can still make things a bit messy for me

#

and I worry about someone else reading the code and saying 'WTF is that symbol?!'

#

not sure it is well known enough yet

#

if it saves me a few lines, then not worth it. If it can save 5+, I would use it.

upper gazelle
#

quick question can someone tell me what <> does in python (example: if name <> name2)

near coral
#

doesn't equal

#

same as !=

#

are you using Python 2+?

#

I didn't know you could use <> in python

upper gazelle
#

yeah im following an old tutorial so thats why its being used

#

thanks for the answer

near coral
#

<> is obsolete

upper gazelle
#

yeah i was getting an error thats why i asked

boreal umbra
#

I don't use the walrus even when I want to because I don't want to have to change it if I'm running on a machine without 3.8

#

But that's always an issue for the first few years after a release.

strange jasper
#

tbh it looks sick

#

walrus all around

near coral
#

it is helpful if I ever want to make a variable only if it meets a condition...or is that what assignment expressions are?

#

I always run into: if len(a_list) > 0:

#

then create some variable

#

if the list isn't empty then a variable is needed. It happens to me daily at work.

swift imp
#

I'm still playing with descriptors

#

Is it possible to add methods, and meta data to data descriptors ?

prime estuary
#

They're regular classes so yes of course.

#

help() will for example read __doc__ and display that. Though since you're probably going to be returning a different object, using said methods/attributes might be inconvenient.

peak spoke
#

Where does the misconception that you must have __init__.py for packages come from? Implicit namespace packages have been a thing for quite a while, but I still see adding an empty init being suggested a lot in the server when it doesn't change anything, and some stdlib modules too have yet to catch up with it

spark magnet
#

it changes one slight thing, so it's still recommended

#

with __init__.py, the package is imported as soon as it is found in sys.path. Without, the whole path is searched before going back to the package to import it.

narrow kettle
#

also from what i can tell with my experimentation today, pkgutils.walk_packages wont recognize a subfolder as a package without one

#

i encountered that exact issue a few hours ago

peak spoke
#

Is that done to prioritize normal packages/modules on imports?

narrow kettle
#

also not having an __init__ fucked up my vscode imports

#

and it just failed completely on linux without them

peak spoke
#

Makes sense if that's the case, but it feels like the feature is commonly overlooked

raven ridge
#

that's not the only thing it changes - Python has implicit namespace packages, but not implicit regular packages. I've been having the exact opposite problem, of trying to explain to people that __init__.py is still very much required to make a regular package, PEP 420 notwithstanding.

#

for instance, pkgutil.get_data doesn't work on data inside namespace packages, and requires a regular package.

#

Last I checked, mypy doesn't work with implicit namespace packages by default, and you have to pass extra arguments to make it work.

peak spoke
#

Well, pkgutil is not something a regular user uses. My issue is with where they're perfectly fine, but init is recommended as a "fix" when it has no inpact on it. For example people importing from a directory somewhere is common but the structure can mess things up, the first suggestions to fix that is usually an empty init

raven ridge
#

There are problems that it fixes, and it still is the right way to make a package. What PEP 420 changed is that you now never need to have an __init__.py that only contains:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
#

In all other cases - if that wasn't what your __init__.py was going to contain - having an __init__.py is still the right thing to do.

fringe tusk
#

Hello, if I compile my Python script with py2exe, would my, for example let's say, friend be able to execute this .exe file without having to even install Python?

#

Thank you very much beforehand :)

pseudo cradle
#

I'm 90% sure they can't, but I'm 10% not sure

gritty pebble
#

I think the point of converting it to an exe is so that you don't need to have python installed

#

py2exe is aย Pythonย Distutilsย extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation.

#

Says it right on the front page

#

@fringe tusk

pseudo cradle
#

oh nice!

#

Good thing I hedged 10%

fringe tusk
#

Says it right on the front page
@gritty pebble Thank you SO much!

#

And what would be the equivalent of py2exe in Linux? So someone just does ./program and that's all

#

I found that cx_Freeze could be an option for this, what do you think?

brazen jacinth
#

PyInstaller is an alternative

#

or cx_freeze looks good yeah

fringe tusk
#

Good :)

proper charm
#

Soemone can invite me to help it to his project?

pearl river
#

Does the following snippet:

try:
  #main code
except Exception:
  raise

change anything compared to just running the main code? If not, would it be a good idea to use this to allow a program to write crash-reports and save the data whenever anything goes wrong (by adding that code into the except block before the raise)?

tawny shoal
#

A lot of programs do that albeit in a more sophisticated way

#

for instance a lot of them implement error handlers

pearl river
#

Is there a library for that or something, or is it just common practice? For some reason I'm not getting much results even searching for python save data on exceptions - you'd think that would be a common problem.

paper echo
#

what does "save data" even mean?

#

try/except is in common standard use

pearl river
#

what does "save data" even mean?
Spend 10 minutes, say, evaluating a function on a large mesh of points to plot it, and if the plotting code turns out to have a bug, you lose the computed data. This is a somewhat artificial example as you can just save it right after computing.
More generally, if you have some data that you normally save to a file when a program is shut down gracefully (player data in a game, say), you may want to save it (in another place, perhaps) if the program ends not-so-gracefully, too.

paper echo
#

sounds like you should just save the data anyway

#

even if temporarily

#

try/except/else/finally is definitely they way to go here

pearl river
#

hmm, I see, maybe. Thanks

shy belfry
#

Damnit.

#

I just found out that in Js = is the assignment expression.

#

So this line in JavaScript:js let i = j = k = 0;Is the same as this in Python:py i = (j := (k := 0))

#

I don't know if I'm mad or impressed.

pearl river
#

It's how most languages do this I believe - a = b is assignment that also evaluates to b.

shy belfry
#

Yeah I just realized Java and C# do it too.

#

Python's version seems so ugly now.

brazen jacinth
#
a = b = c = 0
``` ๐Ÿคทโ€โ™‚๏ธ
pearl river
#

^ yeah, that works in python too. Assignments are not expressions, but multiple assignment like a=b=c=d(set a,b,c to d) is just a special feature.

spice pecan
#

chained assignments work, yeah

sterile kernel
#

By the way, why is assignment not an expression in Python ? We have = and :=, why not just say "a=b is an expression" ? Is it just because it would make the command line waaaaay too verbose, or is there a more profound reason to separate = from := ?

spice pecan
#

There were some reasons for that in the pep that proposed walrus iirc

wide shuttle
#

@sterile kernel One of the reasons is that in languages where it is allowed, accidentally making a mistake like if a = 10 would actually assign 10 to a without giving any obvious errors.

peak spoke
sterile kernel
#

Oh, it's just about not mixing = with ==, then ?
I get that now a decision's been taken, it's too late to change, but I wondered about the motives behind it. Thanks for your pointers on the question ^^

unkempt rock
#

What's your favourite ide for python? I search a good ide

austere moat
brazen jacinth
#

idle ofc GWmemetownOMEGALUL

austere moat
#

Please, can anyone point out the error in that line of code cause I've not been able to.

brazen jacinth
#

for real though, thonny is nice, Pycharm or vscode is a popular choice

spice pecan
boreal umbra
hazy mesa
#

Hey what is parallel to {0} from c# to python?

#

like print("something {0}",x*y)

brazen jacinth
#

python has many string formating utilities

val = 2 * 2
print(f"val is: {val}")
or
print("val is {}".format(val))
...```
are 2 of the more modern ones
sand lily
#

what's the difference between type.new and super().new ?

#
type.__new__()

and

super().__new__()
wide shuttle
#

super traverses the method resolution order while type.__new__ calls the __new__ method of type directly

#

Imagine that your metaclass inherites from another metaclass, with super, it would go to the parent metaclass while with type it will always end up going to type directly

sand lily
#

oh I see, so if you only had one class & one metaclass they would be identical, but if you had multiple cascading metaclasses, super() would stay with the parent metaclass?

wide shuttle
#

Do you know how super works (in Python) in general?

sand lily
#

not too in depth I suppose, my understanding is that you can use it in metaclasses to call magic methods for any of its subclasses

#

but I saw someone do the same exact thing with type.__new so I was curious

marsh nacelle
#

Can you use type hinting to enforce more than just the type? For example, forcing an arg to be in a certain range.

#

More importantly, would it by pythonic?

peak spoke
#

you can do anything with them at runtime, but enforcing arg values in general is usually not pythonic

flat gazelle
#

You mean sth like def fun(a: Between[10,20})?

marsh nacelle
#

Is that from typing?

#

I assume so

flat gazelle
#

No, pseudo code

marsh nacelle
#

Oh, fair. But yeah, that was my general idea

flat gazelle
#

It does not exist because it is close to impossible to check as it is dependent typing

peak spoke
#

you could use typing.Literal I guess

brazen jacinth
#

Given that its just a static type check i dont see why it wouldnt be possible

#

Also when do you actually need to tinker with meta classes

flat gazelle
#

Literal is an option, not sure how type checkers deal with it tbh

brazen jacinth
#

Very rearly do i find myself needing to dynamically construct a class

peak spoke
#

There aren't that many uses in regular projects after python introduced things like init subclass

brazen jacinth
#

You mean inheritance?

peak spoke
#

The __init_subclass__ dunder

brazen jacinth
#

Oh havent used that one before, ill give it a look

#

The amount of dunder methods that i havent used before.. yikes

#

Thanks again

wide shuttle
#

David Beazley has some cool videos that demonstrate a lot of these techniques using the example of type/value checking

keen spoke
#

What are some of the Python libraries that I MUST know how to use?

charred wagon
#

Only the built-ins, I suppose

#

And even then, not all of them

#

There's no such thing, It totally depends on what you're doing.

keen spoke
#

Oh, okay, I see

modest hatch
#

what does async do?

charred wagon
unkempt rock
#

where we can find librairie ?

#

(i'm biginner)

unkempt rock
#

u can type import library name

#

for the built in ones

#

or u can grab the other ones online

#

ok ok thanks you

#

on the website of python for example ?

#

@unkempt rock

#

i think u can just type in command line pip install <library name>

#

ok ok

#

ty

swift imp
#

When using getattribute is there a way to get the class to return a specific attribute if the name argument is "class"?

Basically if I don't access an attribute, I want the class to return a specific attribute rather than the instance itself


class foo(object):
   bar = "blah"
   def __getattribute__(self, name):
      if name == "__class__":
         return super().__getattribute__("bar")
      return super().__getattribute__(name)

f = foo()
f

This raises some error that class str has no attribute __name__

#

Ideally if I do just f, like if an operation or something, it would pass f.bar

#

Get what I'm saying ?

last pollen
#

how are you intending to use that?

fiery geode
#

@keen spoke if you are doing anything with apiโ€™s youโ€™ll want to learn the requests library. If you are found any data analysis you want to learn the pandas library.

unkempt rock
#

Why did that ping me

fair galleon
#

same

unkempt rock
#

some dude abused a ping spam

shy belfry
#

Is there a method such as __dict__() that is conventional to override in Python so my object can return dictionaries of itself, or is it better to make a custom method like get_dict()?

torpid bridge
#

I think to_dict()/as_dict() would be appropriate, but I don't think there's a standard

shy belfry
#

Alright, thank you! ^^

wide shuttle
#

There's also vars if you want to get the values out of the object's dict

#

!e

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


ves = Person(name="Ves", location="The Netherlands")
print(vars(ves))
fallen slateBOT
#

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

{'name': 'Ves', 'location': 'The Netherlands'}
raven ridge
#

And if your object supports the mapping protocol, your users could pass it to dict() to turn it into a dictionary - but that's a special case.

shy belfry
#

How would one go about implementing that? It sounds like that's what I want to be able to do.

#

vars(...) unfortunately doesn't work for me at least without an override because I need to change the form of some data as I call the method.

torpid bridge
#

Is the mapping protocol for c objects mostly? Or things that derive from dict as well?

raven ridge
#

No, it's for any Python object

wide shuttle
torpid bridge
#

I know __getitem__ and __setitem__ but

raven ridge
#

If you provide an __iter__ that returns an iterable over your keys, and a __getitem__ that takes a key and returns its value, the dict constructor should be able to create a dict from an instance of your object.

torpid bridge
#

Huh

#

TIL

shy belfry
#

If you provide an __iter__ that returns an iterable over your keys, and a __getitem__ that takes a key and returns its value, the dict constructor should be able to create a dict from an instance of your object.
@raven ridge oh cool! It might be worth implementing that in this case! ^^

wide shuttle
#

Another way would be to have __iter__ provide an iterator that yields tuples of keys, values

#

!ban 732817076028440679 ping spam

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied ban to @gentle gust permanently.

wide shuttle
#

Hello everyone! Yes, you were pinged. A spammer used a mass ping script in order to be "funny". Let's not give them the satisfaction of now derailing the channel ourselves with a million "was I pinged" messages.

fathom dawn
#

unless it was discussed already

charred wagon
#

Yeah it was discussed the day it was posted I believe

#

You could use the search in Discord to go back to messages on that date

wide shuttle
#

Hey,@burnt wind, we like to reserve this channel for actual discussion of the Python programming language. We have up to 32 help channels (dynamically scaled) and #python-discussion for shorter questions or more general discussion. This channel is specifically for higher-level, more abstract discussion of the Python programming language itself. That's why we moderate this channel like we do, we really want to have a place where higher-level discussion can take place.

burnt wind
#

ah alright

#

I guess now I know why there are two of them

eager turtle
#

wait wat happeend here yd i get tagged

final sequoia
#

Spam pinger, nothing exciting sadly

unkempt rock
#

hey

desert void
#

does anyone know how to evaluate a type hint forward reference?

brave badger
#

@desert void I think you could use typing.get_type_hints for that

desert void
#

I'd need to do that on the dataclass itself, which I didn't want to do to be honest ๐Ÿ˜„

boreal umbra
#

One of my coworkers is asking for help installing anaconda, but my position for a while has been "anaconda doesn't afford you anything so just use normal Python". Is there something I'm not seeing?

radiant fulcrum
#

if they really want it give them intel python dist

flat gazelle
#

It takes less setup for data science if you use the things it ships with, and some packages are only on conda and not on pypi

boreal umbra
#

Why would they make conda exclusive packages?

flat gazelle
#

It has some things which make it more convenient afaik, and if all your users use conda, why bother with pypi

brazen jacinth
#

Anaconda has many prebuilt packages, alot of convinience is added and alot of effort to building packages from source is saved

#

Geodjango for example uses some obscure geospatial libs, that are an extreme pain to install on a certain version of py on windows (aka, requires 6 dependant geospatial libraries that all require building from source)

#

Or that support for packages on new distros is added quickly

sand lily
#

can you get spyder without anaconda? I really like spyder ๐Ÿ˜ž

fair star
#

multiple options depending on platform

visual shadow
#

anaconda (and conda specifically) makes some things absolutely painless to install that are an absolute nightmare otherwise

charred wagon
#

Isn't that just cause they distribute binaries? That's what wheels were supposed to solve

visual shadow
#

aye, and i understand they keep track of dependencies and install those for you too

#

im not too familiar with why exactly pip would misbehave for those packages in the past for my environment though, and perhaps some issues arent as bad anymore

#

i presume at least tf probably isnt as bad to install anymore via pip

charred wagon
#

It's really up to package maintainers to provide all the wheels

#

Sometimes they do a bad job of it

#

Also manylinux wheels don't work for the poor souls on muslc-based distros

#

Or really anything that isn't glibc

worldly pebble
#

When we encode a utf-16 string to utf-8 why does it change it's data type to bytes instead of keeping it string

#
string = 'pythรถn!'
print('The string is:', string)

string_utf = string.encode()
print('The encoded version is:', string_utf)
fallen slateBOT
#

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

worldly pebble
#

Output

The string is: pythรถn!
The encoded version is: b'pyth\xc3\xb6n!'
#

and if hardcode to string the b character also comes along :/

flat gazelle
#

A string is a sequence of Unicode characters wholly independent of encoding. encode encodes it into a given encoding, so it is no longer a string, but rather a sequence of bytes

worldly pebble
#

Aah

#

Shouldn't be a string encoding a string too?

flat gazelle
#

No, because the result of encode are bytes such that they form a given string according to the given encoding

#

Strings themselves do not have an encoding (well, as an implementation detail, they do)

#

You use bytes.decode to go back to a string

worldly pebble
#

What if I do str(bytes)?

#

str(bytes)[2:-1] that would give me utf-8 encoded string right?

flat gazelle
#

That actually returns repr(bytes), which is a string such that eval(repr(obj))==obj

#

Use decode, if you want the escapes, there is an encoding for that as well

worldly pebble
#

decode gives it back in utf-16

#

So the problem is I'm using loggin module

#

and then whenever someone enters emojis it breaks

flat gazelle
#

I would use ascii(some_string)

#

Which is like repr, but may not return non-ascii chars

#

Alternatively, use an urlencode function

worldly pebble
#

ascii would do the job it seems

#

thanks

#

if i want the original back how will i do it just for information sake

flat gazelle
#

I guess ast.literal_eval would do the trick, though I would suggest against going backwards if possible

low narwhal
#

Why was I pinged

worldly pebble
#

Okay! Thanks for the information of this

No, because the result of encode are bytes such that they form a given string according to the given encoding
@flat gazelle

paper echo
#

@charred wagon conda includes non-python deps

#

openssl, libc, etc

#

that to me is the big advantage

charred wagon
#

Yeah, I know

paper echo
#

i hate that conda won't let me install openblas and mkl in the same env

#

if i try to install julia into an mkl-based env

#

it tries to switch everything over to openblas

#

which is just... wrong

charred wagon
#

It's nice on Windows I suppose, but usually your OS package manager will have those other things anyway

paper echo
#

i'll take my openblas julia and my mkl numpy thank you very much

#

meh

#

my OS package manager has whatever versions it has

charred wagon
#

I use arch btw ๐Ÿ˜Ž

paper echo
#

i'm often at the mercy of IT people

charred wagon
#

Yeah I get you, even arch has outdated stuff

#

Well, anaconda does too

#

But thankfully there's conda forge

paper echo
#

you know what i really hate the most?

#

anaconda's channels system

#

because there's no way for the channel maintainer to list any information about themselves

#

or to upload an informative package info page

#

so i have to find out about channels from outside sources

#

and if someone recommends me a channel, there's nothing on the channel page that tells me if i can or cannot trust it

#

i only heard about conda-forge through what is effectively hearsay

#

its truly weird

#

so in practice the only channels i trust are defaults/intel/anaconda and conda-forge

fiery maple
#

i cant think of anything funny - wait a bit , or until next beer

unkempt rock
#

what is the @runtime decorator used for?

red solar
#

where'd you see it?

boreal umbra
#

I noticed that the assertions in unittest.TestCase aren't static

#

Seems like they could be.

#

In fact, I don't really get why test case is a class

languid dagger
#

I think the main reason is because it was ported from Java

unkempt rock
#

quick question how to use random
generating random number 1-10

hexed maple
unkempt rock
#

never mind

raven ridge
#

@boreal umbra I'd strongly suggest checking out pytest if you haven't already. I think it's much easier to wrap your head around than unittest is

keen sentinel
#

hello all

tawny shoal
#

pytest has a bitter taste to it nowadays :| but it's certainly better as a software than unittest imo

last pollen
#

why do you say that?

magic python
#

Clean Code by Robert Martin is a reasonably famous book that I've heard recommended - I'm wondering if there's much advice in there which clashes with best practices in Python?

#

get/set and so on, i've heard that 'getters and setters' aren't something to be used in python ๐Ÿค”

brave badger
#

Properties do a good job of replacing getter/setter functions while still being Pythonic

magic python
#

@brave badger this is @property ?

brave badger
#

Yep

magic python
#

hrm, i don't use oop very much tbh. Are you familiar with the book tho?

last pollen
#

re: Clean Code, it suggests good concepts, but I'd still not follow it blindly

#

an interesting article about it surfaced recently: https://qntm.org/clean

magic python
#

@last pollen thanks i'll have a read - my suspicion was that it might be out of date a bit in relation to python, but I don't have much/anything to back that up

wide shuttle
#

get/set and so on, i've heard that 'getters and setters' aren't something to be used in python ๐Ÿค”
@magic python

Languages differ and that also means that style conventions and recommendations differ from language to language. In Python, the general recommendation is to follow a universal access principle, meaning that as far as the external API is concerned, it just looks like you're accessing/setting an attribute. Whether or not you're actually setting/getting the attribute directly or calling getters/setters via the descriptor protocol is an implementation detail as far as the public API goes.

#

In other languages, if you expose the attritues as-is, you run the risk of not being able to (easily) change the accessor logic without changing that public API. In other words, if you later decide that you actually need to some getter logic, you need to switch to a getter method and that's a breaking change. The API of the object changes. That's why it's better to start out with getters/setters even if there's no real logic associated with them.

#

That way, you can safely add that logic later when needed without risking a breaking API change.

#

In Python, you can add getters/setters after the fact without changing the API by creating them and using the descriptor protocol (e.g., using property)

magic python
#

Interesting, I need to do some OOP as I have got away without it for ages.

wide shuttle
#

Since I've seen you play around with Python for a while now, there's an interesting discussion of what a "Pythonic object" is in Fluent Python. It may be a good book for you.

magic python
#

I guess part of my question was whether anyone who'd read that book had the feeling that it would be good for someone learning python to follow, or if it would be a bit misleading in places

wide shuttle
#

It never hurts to read good books, but it also doesn't hurt to keep an open mind when applying things to other languages than the one the book is mainly using and/or talking about

#

A lot of people go into a language with a lot of biases they learned from other languages and that can do them harm. (Obviously, experience with programming also helps greatly; it's not a single dimension thing.)

magic python
#

play around with Python for a while now
yeah - mainly processing/analysing data in pandas etc, more recently I've started to have a need for more "software design" stuff I guess, like packages and such. I think I might have heard "Fluent Python" recommended as a book before actually, it's a semi-standard intermediate book?

wide shuttle
#

It's a solid intermediate Python book and pretty much considered a "standard". There's a new edition coming out early next year.

magic python
#

one thing that Clean Code says, which I really disagreed with, was that bool flags to functions are negative. Maybe i have bad practice idk, but it's pretty common in python from what i've seen (str.contains( ... , case = False) )

last pollen
#

I've read it before but I don't remember the exact details? What does bool flags to functions are negative mean?

magic python
#

@last pollen he said that if you have bool flags then that's a case for writing two different functions

#

perhaps "negative" is a bit of a strong word

sacred tinsel
#

here's the bit

#

Martin says that Boolean flag arguments are bad practice, which I agree with, because an unadorned true or false in source code is opaque and unclear versus an explicit IS_SUITE or IS_NOT_SUITE... but Martin's reasoning is rather that a Boolean argument means that a function does more than one thing, which it shouldn't.

magic python
#

I disagree with that too - unless pandas and such are poorly designed i guess

spice pecan
#

It really depends on the specific case, I could definitely see bool flags being abused to the point of absurdity

magic python
#

what could you not say that about

spice pecan
#

Although there are lots of cases where these kinds of things are completely acceptable, like "ignore_case" in parsing functions

#

Plus, using kwargs makes these flags way easier to understand than just a random true/false in a function call due to explicitly stating what it affects

magic python
#

how is a kwarg easier to understand, if anything it's less explicit isn't it?

#

if i see

def f(case = False)

i know what that's doing more than a kwarg that can be passed in

spice pecan
#

That's a default value, not exactly a kwarg

#

A kwarg is when you specify the argument's name during a function call, like this:

print(10, 20, 30, sep='; ')```
magic python
#

right the kwarg would have def f(**kwargs), and i'm saying they're less clear

#

using kwargs makes these flags way easier to understand than just a random true/false in a function
unless you're talking about passing values by order rather than name, in which case I agree, and often use * to enforce

#

kwarg is being overloaded here i feel

sacred tinsel
#

yeah, there's a substantial difference in the readability of the function call between something like is_valid("value", case=False) and just is_valid("value", False)

spice pecan
#

**kwargs is a catcher like *args, by default you can pass any argument as either positional or a keyword (unless they are marked as positional/keyword only in the signature or there's something like *args at play preventing you from specifying an arg as positional)

magic python
#

i feel like the latter between f(False) vs f(case = False) is quite obviously better so i assumed we were referring to something else

spice pecan
#

The thing is, in languages like Java (IIRC) you don't have the luxury of being able to specify the name of the argument you're passing, so the function call is just a dump of various values

sacred tinsel
#

yeah, then the API must be designed much more carefully

magic python
#

which is one of the reasons i questioned the value of someone learning python i guess, but I don't know java ( I wasn't aware of what you're saying for example )

sacred tinsel
#

I suppose what they meant with the bools is that if you don't have the luxury of doing case=False, passing an enum flag like CASELESS makes more sense?

spice pecan
#

yeah, an enum would be preferable I believe

#

Since it would explicitly state what the effect will be without having to rely on your IDE of choice inserting argument names, etc etc

#

Though yet again, there are cases where it's fine to use a bool because the signature is not complicated and/or creating a separate function for doing the same thing with minor tweaks would be overkill, like some of C#'s Parse and TryParse methods

magic python
#

@spice pecan thanks for the examples, to be honest I never touch langs like c# / java etc, i use python and sometimes R, but it's interesting to hear from these perspectives

sacred tinsel
#

out of interest, what other langs allow passing arguments by keyword?

#

looks like C# and Kotlin support named args

flat gazelle
#

Raku has something like that.

brazen jacinth
#

c#, kotlin, r, ruby, scala, swift, sql, lisp

flat gazelle
#

I think haxe as well, and if you count passing records/objects, js and elm

magic python
#

... what i really need is a "clean issues" for github/lab projects ๐Ÿ˜ฉ

spice pecan
#

swift is big on named args, they are the default way of passing arguments IIRC

#

you can have function overloads where the only differences are the names of the args

torpid plinth
#

hey guys, can somone point me in the right direction to learn ray casting?

#

me and my mate have a idea how to make doom

#

from scratch.

unkempt rock
#

Does anyone else also think that defining functions should be function name(): instead of def name(): in Python? As "def" stands for define and you can define classes too but then it'd be class name:. It's more of a mess this way.

last pollen
#

I don't mind it either way

gaunt condor
#

Does anyone else also think that defining functions should be function name(): instead of def name(): in Python? As "def" stands for define and you can define classes too but then it'd be class name:. It's more of a mess this way.
@unkempt rock def is shorter pithink

unkempt rock
#

func works too hAha

gaunt condor
#

But I donโ€™t care

#

xD

#

Func or def is the same

radiant fulcrum
#

i dont see it as a big issue

#

alot of other languages go with def some go with fn like rust, then there is Js that has function but we dont talk about js

west robin
#

@unkempt rock in Golang it is func to call a function, it's very similar to python

unkempt rock
#

Yeah, all I am saying is that it would make more sense. It feels like they originally created functions first and thought of them being defined, so they named them "def". Then they most likely added classes later on and realized they're also being defined; was however too late to rename "def" to "func". Does that make sense?

brazen jacinth
#

to be honest, after you use python for more then a month it's hardwired behavior anyway

narrow kettle
#

imo the use of def is a good choice, i certainly like it better then fn or fun

brazen jacinth
#

imo, if it would have been fun, i wouldn't really care ๐Ÿคทโ€โ™‚๏ธ

#

as long as it's succint

unkempt rock
#

i think you get used to whatever the syntax is for the language you're using. it is interesting to consider if how a language handles anonymous functions might also impact on particular keyword choices

narrow kettle
#

pythons anonymous functions are like the red headed stepchild of programming langs lambdas

radiant fulcrum
#

everyone likes a red hair tho at some point

narrow kettle
#

relevant avi thinkmon

cursive obsidian
#

Hey guys, I have a question.

#

What is the programming language that is most worth learning for leisure? If the answer is Python, then why? Sounds like a very cliche question, but it's serious.

Thank you for your attention ^-^

unkempt rock
#

i think its the crazy number of libraries allowing u to do a crazy number of things and maybe syntax

warped crystal
#

I mean it depends on your definition of leisure

#

if it's for building things with python would be good for non performace constrained things

brazen jacinth
#

not the right channel

cursive obsidian
#

By leisure I mean learning it for the sake of it and not for doing anything specific right now. Hoping that it will someday open opportunities.

unkempt rock
#

@cursive obsidian although itโ€™s not a programming language I think html and css is something to learn just for fun

true hollow
#

Well I think def is a great keyword for defining functions because:

  1. It's unique
  2. def probably means "Define Function"
rose cloak
#

I dont know if this is the right place, and honnestly i don't want to waist the time for the guy awnsering the questions on the #python help category, but what are the uses of __ init __ in python

true hollow
#

Basic question but nvm

#

__init__ is called every time a class is converted into an instance

#

It is useful because sometimes init sets up some variables and it sometimes setups class instance behavior

rose cloak
#

ok

#

thanks

minor sinew
#

it's basically a constructor

#

__new__ wouldn't be something you would want to use as a constructor, if you happen to come across it

tawny shoal
#

The __init__ method initializes a new instance (read: object) of its class (read: object blueprint) and returns it

#

The instance that it initializes is its first argument, called self

#

"initializing" here often means assigning instance variables to the instance that are (or can be) different for every instance (rather than the same for every instance)

rose cloak
#

wait so if im getting this right, its like if you have a class grav

#

and its like yourvar = new class grav()

minor sinew
#

yeah, except you would just do:

yourvar = grav()

in python

tawny shoal
#

In Java it's Grav yourVar = new Grav();

rose cloak
#

not java

tawny shoal
#

Ah

rose cloak
#

i don't know what, but a relative of mine explained it to me like, 5 years ago

#

actually it might be java

tawny shoal
#

Ah

#

probably

#

but yeah I think you grasped the concept

rose cloak
#

ok

#

ima try doing something with it

tawny shoal
#

the __init__ method initializes a new class instance, basically, to put it short

rose cloak
#

thx alot

tawny shoal
#

Let's just move on.
What are your thoughts about this? https://github.com/Project-Dream-Weaver/Sandman by @radiant fulcrum (no affiliation on my side)
It shows that boosting Python's web performance with Rust is totally possible and effective. I think it's promising! What are your thoughts?

#

Mentioning this here because I'm interested on people's perspective on this kind of approach

spring delta
#

Well I think it's like the modules with C implementations

#

(epic)

cloud crypt
#

this is not very related to the actual question, huh?

spring delta
#

? what

radiant fulcrum
#

Its not really embedding rust into to python via native modules but its the idea of essentially letting a production grade server mount to python asgis

spring delta
#

uh @cloud crypt ?

tawny shoal
#

I was asking for perspectives rather than whether you think it's good or not ^^'

spring delta
#

well my perspective is that it's epic and good and promising and a lot of good words

#

๐Ÿ˜ƒ

tawny shoal
#

@radiant fulcrum ah that makes sense, I looked at your code and couldn't see any signs of PyO3 or anything like that

cloud crypt
#

if server can be written in rust not sure where python can have the use

radiant fulcrum
#

Ive worked on it a bit more trying to stop the system bottle knecking

tawny shoal
#

Hmm, what are your thoughts on using PyO3? Would that even play well with asyncio?

radiant fulcrum
#

I have, if you look a PyO3's repo they have a event loop based off the tokio runtime

#

tho its outdated now and for fair reason

cloud crypt
#

PyO3 is really pretty

radiant fulcrum
#

Its great for native sync stuff

#

async stuff is pretty much not really a thing

cloud crypt
#

async as in async, yep

radiant fulcrum
#

GIL basically removes any use of async rust

tawny shoal
#

Ohh that makes sense

cloud crypt
#

sadly, yeah

tawny shoal
#

damn it

radiant fulcrum
#

Why i went with the dedicated Rust server that binds to light weight workers rather than directly like uvicorn

tawny shoal
#

I see now, clever ^^

#

I like this approach

#

from the perspective of a framework dev, would it make sense to write the bulk of a web framework in Rust and use PyO3 to allow developers to write applications in Python but leverage the power of Rust?

#

wait, maybe not PyO3

radiant fulcrum
#

im not sure, most of my work is with async so i dont work with native level stuff too much in terms of extensions

tawny shoal
#

I feel like it'd be great to be able to combine the best of both worlds this way

radiant fulcrum
#

I think if i remember PyO3 were going to try make their own runtime at some point?

tawny shoal
#

ohh sounds interesting

young wedge
#

I have a quick question to ask you guys. I'm working on a Discord bot, and I came across a situation in Python that I've never crossed before. Are you allowed to put an if statement after using or?

#
if friendRole in member.roles or if
#

Like I want to check if someone has another role as well as that one

#

Can I say "or if"

#

Or do I just say the role in member.roles?

hardy glen
#

i have a question i am coding in py and developing a kiss cmd but i dont know how to refer to yourself

young wedge
#

ctx.author

#

Make sure to pass context to your command.

#
async def kiss(ctx):
  executor = ctx.author
  blah blah blah
boreal umbra
#

@young wedge this isn't a help channel, however you don't do successive ifs in a conditional statement

#

So it would be if a in b or c and not if a in b or if c

young wedge
#

So if friendRole in member.roles or anotherRole in member.roles etc?

#

Thanks.

#

And sorry about that.

boreal umbra
#

That looks right, though when you get a chance the best practice is to switch camelCase to snake_case

young wedge
#

Why?

#

I've always used camelCase.

radiant fulcrum
#

its just the pep8 style guide thing

boreal umbra
#

The official python style guide is snake_case

young wedge
#

Oh... Pfft.. I've never really paid attention to any "language grammar rules."

#

But will do.

boreal umbra
#

That's style rather than grammar

#

If you break a grammar rule, your code won't work ๐Ÿ˜•

young wedge
#

Oh, ye

#

๐Ÿ‘

#

Appreciate it.

hardy glen
#

ahh

#

it says slash instead of

#

voids

#

how do i fix

unkempt rock
#

call the author of the person that invoke the command

#

@hardy glen