#internals-and-peps

1 messages · Page 56 of 1

unkempt rock
#

discord.py will prob be more help than this channel for discord stuff

unkempt rock
#

Which is better, for a docstring?

# One
class foo:
  """A cool class.

  A longer description of a cool class
  """
# Two
class foo:
  """
  A cool class.

  A longer description of a cool class
  """

I'm not sure what PEP8 tells you to do.

narrow kettle
#

I always do two personally

unkempt rock
#

Google does one

rigid holly
#
async def isOpen(ip,port):
    s = socket.socket(socket.AF_INET, socket,SOCK_STREAM)
    try:
       s.connect((ip, int(port)))
       s.shutdown(2)
       return True
    except:
       return False

why is it always returning true?

#

the server has been shut down

pseudo cradle
#

Why do you think pep8 hates camelcase so much

tawny shoal
#

Java PTSD

#

I'm not actually 100% kidding, could be that they didn't like Java's style and they wanted something that more visually resembled natural language

magic python
#

why did they take JUnit style stuff for unitest then 🤔

charred wagon
#

Because those libraries are old and possibly before pep 8 was ever published

magic python
#

oh really, i didn't really think of python without pep

charred wagon
#

Yes, Python goes back to the early 90's. PEP 8 was published in 2001

#

unittest was originally a 3rd party library named PyUnit and was released in 1999

tawny shoal
#

We sure have come a long way

charred wagon
#

Not sure if the logging module was separate too, but I do know it was outsourced to a different company

#

I don't really know why they were heavily inspired by Java. I guess Java was huge at the time and all the rage.

#

Interestingly enough, the original PEP 8 did allow CapWords style too

#

So they didn't change it until 2004, way after both unittest and logging

tawny shoal
#

Makes sense now ^^

#

Thanks for doing the research!

sacred tinsel
#

@unkempt rock I will check now but I'm almost positive PEP8 specifically allows both styles as valid

#

consistency matters

charred wagon
#

I believe it's in PEP 257 not 8

sacred tinsel
#

ah yes

#

The summary line may be on the same line as the opening quotes or on the next line.

boreal umbra
#

I usually start the text on the line after the triple quotes

#

So that it's the same as the end.

sacred tinsel
#

I don't mind either, I think both look good as long as it's consistent

boreal umbra
#

I wonder which one black does by default

#

Also regarding camel case, I think snake case makes more sense because it adds some white space and uses white space the way it's used in natural language

#

And when I see camel case, it signifies that I'm dealing with code written by someone with a non Python background and that gives me ptsd

sacred tinsel
#

I don't like 🐫 at all, there are too many situations in which it looks awkward

tawny shoal
#

Yeah I feel the exact same lol

boreal umbra
#

But I guess camel case is what's familiar for a lot of people and is what makes code look like code for them.

#

I can't really fault them for that.

tawny shoal
#

I was so glad I didn't have to write camelCase anymore when I finished high school

#

mostly because in line with that was a bye bye forever to Java

boreal umbra
#

Also I associated capital letters with shouting so when I read camel case it sounds weird in my head.

#

Like the first syllable of each word is being weirdly emphasized in a spoken way.

#

I wonder if a lot of millennials/gen Z perceive it the same way.

#

Unrelated, but did you know that a lot of young people circumvent capitalization and punctuation corrections on smartphone keyboards to make their messages look more informal?

#

If you want to comment on that I guess at me on an off topic channel. Anyway.

#

I was so glad I didn't have to write camelCase anymore when I finished high school
@tawny shoal

I'm a CS senior and I think I'm done with Java but it depends on what my professors use going forward.

rigid holly
#

oops

#

wrong key lmao

boreal umbra
#

The first few courses are all Java though except for the token class about C.

rigid holly
#
async def isOpen(ip,port):
    a_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    location = (ip, port)
    result_of_check = a_socket.connect_ex(location)

    if result_of_check == 0:
       return True
    else:
       return False

    a_socket.close()
#

why is it always returning false?

boreal umbra
#

@rigid holly this isn't a help channel. However I suspect that result of check is always not zero.

#

Also the last line of your function is unreachable.

tawny shoal
#

Unrelated, but did you know that a lot of young people circumvent capitalization and punctuation corrections on smartphone keyboards to make their messages look more informal?
@boreal umbra could never be me
@tawny shoal

I'm a CS senior and I think I'm done with Java but it depends on what my professors use going forward.
@boreal umbra hoping the best!

agile heath
#

anyone know how i'd run a python script but run pip beforehand in 1 command? if that makes sense at all..
I've tried different combinations of python3 bot.py -m pip install -r requirements.txt and tried looking at https://docs.python.org/3/using/cmdline.html but I couldnt find what i needed there, i dont think there's point claiming a support channel for a probably simple command

boreal umbra
#

@tawny shoal if I get put on a project for my senior capstone that requires Java it will literally ruin my life.

#

@agile heath why do you need to do that?

#

can't you pip install the requirements file and then run the bot?

agile heath
#

well its on pterodactyl, so it'll just make things way less tedious to go back and change the startup command with Norton extensions telling me my panel mightn't be secure

#

if there isnt a way to do it in 1 command, i can still do it 1 by 1
but i was just wondering if there's an easier way of doing it

boreal umbra
#

I think pip install -r requirements.txt && python3 bot.py will run those two commands consecutively

agile heath
#

doesnt seem to work

boreal umbra
#

what happens?

#

Also, I just noticed that we're not in #python-discussion; this channel isn't a help channel.

agile heath
#

oh, right

boreal umbra
#

If you're still getting an error message, try opening a help session and copy/paste what you've said so far along with the error message.

agile heath
#

ok, ill ask around in the pterodactyl discord first

#

thanks

pseudo cradle
#

But yeah, camelCase makes me happy

#

It's one less keystroke than snake_case

charred wagon
#

Not really

#

You have to press shift to capitalise the letter

#

Ah I suppose you need shift for an underscore

#

damn, you win this time

pseudo cradle
#

🙂

uneven juniper
#

hello, i'm new in this community. i love python

boreal umbra
#

@uneven juniper Welcome. Python loves you too.

This channel is specifically for more advanced discussions about the language itself, which you're free to engage in. #python-discussion is more... general.

rare harness
#

which gui is good in python

boreal umbra
#

I tried making a GUI once and I hated it. I heard PyQT is good though. Try asking in #user-interfaces

pseudo cradle
#

I tried doing things once and I hated it.

vivid dew
#

Anyone know how can I push my code to github without revealing my twitter API key?

last pollen
#

store your API key in an environment variable, then query for the environment variable in your code

languid dagger
#

@tidal talon This channel is for discussing the Python language itself, it is not a help channel. Please see #❓|how-to-get-help . I would also suggest that when asking your question you provide the full error message you're getting.

tidal talon
#

Okay

strange reef
#

Does python have tkinter docs?

#

I don't understand that

#

Is there some someway to understand

tawny shoal
#

I feel like every language has lacking GUI solutions unless you just use something that's written in C/C++

#

or the web

#

it's a bit of a shame

#

by lacking I mean they either lack in functionalities or ease of use

flat gazelle
#

GUIs are really hard, but there are some solid ones, like V, java and maybe haxe. But really electron is as convenient as it gets

narrow kettle
#

c# is good if you are on windows

flat gazelle
#

Forgot that, c# is very good on windows

tawny shoal
#

It is, but yeah I don't see something that's only good on win as much of an option

narrow kettle
#

For GUI that’s somewhat true

#

The language itself is totally xplat

#

Avalonia is a thing

#

And win has announced maui that is xplat as well

tawny shoal
#

yeah was only talking about GUI, although my C# experiences on Linux so far have been horrible in terms of UX, it does work, though I'd just be using something else instead if my target audience wasn't exclusively Windows users anyways

#

but we're getting off-topic I just realized

minor sinew
#

yeah, WPF makes doing stuff in c# pretty easy

tawny shoal
#

If I have a foreign executable (in my case a .jar) that is a dependency of my Python project, where would be the most logical location to store it? I feel like venv/lib/ and lib/ are good candidates. I don't feel comfortable just dropping it into the project root. (This is for a framework that'll do this for end users and developers)

flat gazelle
#

Appdata on windows, /var/ on Linux AFAIK

tawny shoal
#

oh that could work too, but it's probably rather fragile, at least that's how it feels like to me

flat gazelle
#

That is the proper way to store application files afaik

#

Chrome, twitch, Minecraft, python all use it (well, python on windows only)

tawny shoal
#

Hmm yeah maybe I can do it that way

paper echo
#

Do you distribute it along with your application?

#

Would it make sense to keep it inside the project root and access it with importlib.resources?

#

Also maybe it could make sense to allow the user to configure the jar location eg with a config file

#

Afaik var is meant for data that changes during use

#

This sounds better for lib or share

#

I dislike the existence of /var/lib in general

#

Although apparently that's where you're supposed to store things like persistent databases, I think the name is bad but it has a purpose. That purpose is different from a distributed jar

#

So my vote is /usr/share/myapp/myapp.jar and/or ${XDG_DATA_HOME:-~/.local/share}/myapp/myapp.jar

#

Or s/share/lib

#

Obviously theres no "xdg lib" dir

undone hare
#

/var is supposed to be for, well, variable content, you shouldn't store a static app jar in there, or at least it isn't intended to, you are free to do whatever you want

#

/usr/share/ seems like a better choice yeah

#

But I mean, /lib is a thing too :D

unkempt rock
#

is there a function to start a timer in python once you begin running a program? for example, im trying to compute the amount of times an instance occurs per second the program runs

paper echo
#
from time import perf_counter

t0 = perf_counter()
# do some stuff
t1 = perf_counter()
print(f'Completed in {t1 - t0:0.2f} seconds')

@unkempt rock like this?

unkempt rock
#

import time
start=time.time()
doSomething()
print(time.time()-start)

#

yes i think something like this work too?

#

@paper echo

paper echo
#

use perf_counter not time

#

but yes

unkempt rock
#

thank you 🙂

boreal umbra
#

If PyPy is faster than cpython, what's the point of cpython? Is it more portable?

brazen jacinth
#

Because cpython its the original implementation

#

Pypy has its drawbacks

spice pecan
#

PyPy is still on 3.6.9, isn't it?

boreal umbra
#

For two different distros of python, aren't the third numbers not required to line up?

urban hollow
#

Hi i am trying to given an action to text box. whenever i wrote something i want it to see in label_3 how can i do that help please

from tkinter import *

root=Tk()
root.title('Word Counter ')
root.geometry("500x500")




lbl_1=Label(text='Paste your sentence here : ')
lbl_1.place(x=10,y=5)

lbl_2=Label(text='Total Word:  ')
lbl_2.place(x=10,y=340)

lbl_3=Label(text='2312  ')
lbl_3.place(x=100,y=340)


def count_words():
    
     lbl_3.configure(text='test')




box=Text(command=count_words())
box.place(x=10,y=30, width=300,height=300)
box.focus()



boreal umbra
brazen jacinth
#

Not sure, since bytecode can change even in patch versions afaik

#

By distros you mean implementations?

boreal umbra
#

uh right

#

I figure different implementations will have different bugs and thus have different bugfix releases.

brazen jacinth
#

Hmm youre right, they must uphold the language spec but the implementation specifics of versioning im not sure how its handled

#

Im gueesing that the answer to your question is probably yes

gritty pebble
#

@unkempt rock using time.time for calculating time deltas is bad because it's adjustable

#

Unlike perf_counter

#

Also perf_counter has higher resolution

junior sandal
#

Can somebody explain to me why when my computer is slow, my pygame program would close and return Killed: 9 in my terminal?

low lagoon
flint agate
#

Quick question: how do you add a directory to the sys.path or $PYTHONPATH?

charred wagon
#

It's just a list, you can append to it

flint agate
#

@charred wagon so its has nothing to do with environment variables? And how do I “code” it?

#

Do I do something important sys.path?

#

And then what do I append exactly?

charred wagon
#

Python loads the environment variables into sys.path

flint agate
#

*import not important lol

charred wagon
#
import sys
sys.path.append("path/to/another/dir")```
#

It's literally a list of strings. Each string is a different path it searches for modules

flint agate
#

@charred wagon ok thanks will try out. Just trying to find solutions to import one of modules in another python file

charred wagon
#

!!!!!!

#

Don't do this.

#

If you need help with fixing your imports open a help channel and I can help you there

#

You really shouldn't be editing sys.path to fix imports unless you're trying to import something really weird

flint agate
#

@charred wagon oh shoot. Sure thing. How do I open a help channel?

charred wagon
flint agate
#

@charred wagon opened up a help channel in #help-pie

#

And just asked my question in there

dire wing
#

guys do you have any idea on how to do a research bar that shows suggestion based on a list? if u know tkinter pls dm me so we not spam too much in general chat

charred wagon
#

@dire wing This is not a help channel. Please ask in #user-interfaces. Also, you're more likely to get an answer if you don't ask for DMs.

dire wing
#

@charred wagon ok sorry 👌

thin dawn
#

hello what does


obj = Object()/x/y/z

mean?

paper echo
#

@thin dawn where did you see this?

#

classes can define custom behavior for /

#

is there a "correct" way to monkey patch a method onto a class? e.g. automatically set the __qualname__ and do any other required bookkeeping

#

!e ```python
def f(self, x):
return x

class Q:
def g(self, x):
return x

Q.f = f

print(Q.g.qualname)
print(Q.f.qualname)

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

001 | Q.g
002 | f
paper echo
#

not sure what other bookkeeping you would even want

next thicket
#

Is this the right channel to ask how exactly the for loop works in python

#

I just fixed an problem in my code because I was editing an array I was looping through.

#

So I was curious if the python for loop works in the background like the for(int i = 0; i < array.length; i++) syntax

paper echo
#

not the right place @next thicket , ask in a help channel: #❓|how-to-get-help . but yes it's kind of like that

next thicket
#

Ok, sorry, my bad

misty linden
#

not the right place @next thicket , ask in a help channel: #❓|how-to-get-help . but yes it's kind of like that
@paper echo what is this channel for?

next thicket
#

bruh did you have to ping me

misty linden
#

bruh did you have to ping me
@next thicket do you mean me?

next thicket
#

bruh, again

unkempt rock
#

lol

#

if u quote a ping

#

it pings

torpid bridge
#

As in the channel description, the channel is for:

Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language.
Things like __qualname__ as you see above, the MRO, multi-inheritance, pypy, and other interesting details specific to python

paper echo
#

speaking of which, still accepting answers to the qualname question 🙂

last pollen
#

@paper echo I don't think so, you'll have to do it manually

#

not sure what other bookkeeping you would even want
__module__ if the function is not in the same place as the class

#

and probably some more stuff

#

monkey patching always feels icky to me

peak spoke
#

If it's monkeypatching, just do what you need for it to work

last pollen
#

true, this does sound a bit like infiltration and assuming a new identity

paper echo
#

the application is to add a method to a class by decorating it

#

!e

def magic(cls):
    def i_love_python(self):
        print('i love python')
    cls.i_love_python = i_love_python
    return cls

@magic
class MyClass:
    pass

obj = MyClass()
obj.i_love_python()
fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

i love python
paper echo
#

but obj.i_love_python.__qualname__ is wrong and i'm skeptical of how well it will behave with other tooling

#

maybe it's wrong to expect qualname to change

#

and maybe it should stay as is

torpid bridge
#

Well, if __module__ isn't changing either I think it probably should stay as it is

#

because any code searching through __module__ for __qualname__ is going to find it

#

!e ```py
def magic(cls):
def i_love_python(self):
print('i love python')
cls.i_love_python = i_love_python
return cls

@magic
class MyClass:
pass

obj = MyClass()
print(obj.i_love_python.qualname)
print(obj.i_love_python.module)
print(obj.i_love_python.module.file)

fallen slateBOT
#

@torpid bridge :x: Your eval job has completed with return code 1.

001 | magic.<locals>.i_love_python
002 | __main__
003 | Traceback (most recent call last):
004 |   File "<string>", line 14, in <module>
005 | AttributeError: 'str' object has no attribute '__file__'
torpid bridge
#

Depends on if the tool is going to look for stuff in actual files with __file__ too I suppose

paper echo
#

@torpid bridge ideally magic is defined in a utils module and MyClass could be anywhere

#

maybe i just dont worry about it

torpid bridge
#

Well yes, the idea is that if a utility wants to go and look at the code of magic for whatever reason, if it walks to __module__.__file__ and searches for magic it won't find it

#

But I don't think it'll matter too much honestly

paper echo
#

hm

#

i wonder if mypy would know what to do with it

languid dagger
#

You could do it this way

import functools


def magic(func_name):
    def decorator(cls):
        def func(self):
            print('i love python')

        setattr(cls, func_name, functools.update_wrapper(func, getattr(cls, func_name), updated={}))
        return cls
    return decorator


@magic('i_love_python')
class MyClass:
    def i_love_python(self): ...


MyClass().i_love_python()
print(MyClass.i_love_python.__name__)
print(MyClass.i_love_python.__qualname__)```
Which requires you to define the function and then overwrite it
#

Only problem with using functools.update_wrapper is it also adds MyClass.i_love_python.__wrapped__ so if you don't want that you just need to update it yourself

#

Which you can just copy/paste from the functools code or handle __wrapped__ after updating it

paper echo
#

I don't mind the extra attribute

#

That looks like it works

#

Oh

#

Yeah I don't want to have to manually define the function

#

As silly as that sounds, I have a use case

languid dagger
#

Then I can only think of getting the attributes off the class and copying them over to the function

paper echo
#

hm

#

maybe some of this is clarified in the language reference

jade knot
#

I just started

unkempt rock
#

In a try finally block, what's the point in finally? Wouldn't it be better to use py try: Code() Cleanup() than this? py try: Code() finally: Cleanup()

languid dagger
#

finally is always run even if you return, or an error is raised

unkempt rock
#

Ah ok

#

So what does happen if you return?

#

It executes finally and then returns after?

languid dagger
#

Fun fact, if you would return in the try before the function itself yields the value back to the caller , finally is run

#

This means that if your finally block also returns, you get that value instead of what was in the try block

unkempt rock
#

Oof

languid dagger
#

!e

def f():
    try:
        return 1
    finally:
        return 2

print(f())
fallen slateBOT
#

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

2
unkempt rock
#

Yeah that sounds awkward

#

Oh cool the bot can execute code!!

#

!e py print("Hello world")

fallen slateBOT
#

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

unkempt rock
#

._.

#

I appreciate the explanation btw, ty

hot trellis
#

does someone know how to control a drone through a network

true hollow
#

read the specs of the drone

#

also wrong channel :)

magic swallow
#

can someone explain to me how to install sublim text

#

in private message, if possible

gleaming rover
#

can someone explain to me how to install sublim text
@magic swallow try #tools-and-devops

magic swallow
#

ok thx

obtuse crater
#

Does anyone knows a program were i can write with python? similar to visual studio?

#

nvm i found one

tawny shoal
#

Please don't use this channel to get help :)

obtuse crater
#

for simple questions i am allowed

#

they told me that on a healp channel

spice pecan
obtuse crater
#

a

#

then okay

spice pecan
#

This channel is for discussing python as a language, the direction it's heading in, advanced use cases, etc

fluid stone
#

How can i make so if i click it prints "Clicked"

fiery patrol
#

pattern[:k]

#

how is this called ?

flat gazelle
#

Slice

fiery patrol
#

sub elements for an array

#

@flat gazelle when doing this patter[:k] is the k-th element included ?

flat gazelle
#

The kth element is, but not the element at index k

#

A slice a[:k] is k elements long

fiery patrol
#

so it gives all elements from 0 to k ?

flat gazelle
#

Yes

pearl river
#

in general, python slices [a:b] are b-a long - it's a nice property.

fiery patrol
#

k including ?

#

ok thx

flat gazelle
#

K excluding

fiery patrol
#

ah

#

k - 1

#

thx

spice pecan
#

the result of list_[start:stop:step] is the same as doing [list_[i] for i in range(start, stop, step)]

fiery patrol
#

in py

#

can you do this ? O.o

#

return transition_table, len(pattern)

pearl river
#

that's just returning a tuple.

fiery patrol
#

so when calling the function I retrieve to values ?

#

aight py is fire

pearl river
#

!e

def my_func(x,y):
  return (x,y) #same as `return x,y`
a = my_func(1,2)
print(a)
x,y = a #unpacking a tuple
print(x,y)
#same as:

x,y = my_func(1,2)
fallen slateBOT
#

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

pearl river
#

^ example.

red solar
#

you know how like with instance members, when you assign to them they call __setattr__ and some other stuff internally?

#

what happens when you assign to a variable?

spice pecan
#

the name gets associated with that value

peak spoke
#

if it's just in a function or outside of anything, the name gets stored in the code object and I think that's it

pearl river
spice pecan
#

I believe nothing extraordinary happens when you access/assign to a var, unlike with instance attributes. It just maps a value to the name in the appropriate dict, be it the function scope, global scope, etc

#

Instance attributes call __getattribute__ and __setattr__, which in turn may call __get__ and __set__ on the attribute if it's a descriptor

red solar
#

sry i got distracted by food

#

i'm back

#

damn ok nothing then :/

spice pecan
#

You can't monkey patch __getitem__ and __setitem__ on the __dict__ or overwrite __dict__/monkey patch __getattribute__ and __setattr__ on the module object, or at least so it seems

wide shuttle
#

Right, yeah, you can monkeypatch the __class__ on a module object, but it only works when setting attributes on the module object, not by using the assignment statement

spice pecan
#

Ah, fair enough

wide shuttle
#

If you have something like this in one module:

import sys
from types import ModuleType


class WeirdModule(ModuleType):
    def __setattr__(self, name, value):
        print(f"Hello from __setattr__ with {name=}, {value=}")
        print(f"I'm going to ignore {value=} and just set `10`!")
        super().__setattr__(name, 10)


mod = sys.modules[__name__]
mod.__class__ = WeirdModule
#

And then do this in another file that imports this module:

import file_one


file_one.a = "b"
print(file_one.a)
#

It works

#

but, yeah, that's not changing the assignment statement directly

red solar
#

i had an atomic class where i wanted to be able to do atomic_int = 3, but i've just decided to do atomic_int.store(3) and atomic_int.value = 3

#

also realised that even if i could monkey-patch assignment, it would cause other issues

spice pecan
#

Can you overwrite the __dict__ attribute on the module by monkey patching __class__? That might work with the assignment statement

red solar
#

oh you guys moved beyond what i was saying, and into modules

spice pecan
#

Go big or go home

red solar
#

i feel like assignment on class instances is bigger than modules 😂

#

in an atomic class, would you implement __imul__ and document that it's not atomic, or just force people to do atomic_int.store(atomic_int.value * n) to make it explicit that it's multiple operations?

#

idk how far the python mantra goes with explicitness

mystic cargo
#

explicit all the way baby

red solar
#

ok

fathom harness
#

Wait

#

What does .store do?

unkempt rock
#

Can you type hint a name globally?

#

For example so variables or arguments named foo are always the same type

red solar
#

store is like set

#

you could just create a global variable with that type hint

#

(if you're not doing multithreaded stuff)

#

but other than that i don't think so

shy belfry
#

I'm aware the solution for this might not necessarily involve a low-level solution nested within the Python language, but I was hoping this more advanced chat could have some users that have faced this challenge in the past and might be able to offer some insight on how to solve it.

I'm working on a little framework that fetches items from the Reddit API through the aPRAW wrapper and need to give the items based on what they are some added functionality to the methods that are already bound to the models. So at the moment I'm doing this and I'm not very happy with it:```py
class RedditItem:
def init(self, item: Union[Submission, Comment, ModAction]):
self.item = item

def do_something_with_item(self):
pass

...```What I mainly don't like is that if I want to call a method or read an attribute of the item, I have to do reddit_item.item.bound_method() and for some reason it just doesn't feel clean. I don't know, maybe you guys see things differently but I was wondering if there's a way to just add the new methods and/or attributes to the original item, maybe with a subclass and still retaining all its functionalities?

red solar
#

override __mro__ maybe?

#

never tried it

wide shuttle
#

Manipulating the MRO wouldn't make the instance attributes available

red solar
#

why not?

#

(ok i see why not)

#

but if the other class doesn't use them

wide shuttle
#

My guess is that the methods still expect an instance of the item, not the instance of RedditItem. If you were to override the MRO by inserting those classes, the methods would get the instance of RedditItem when you access it on a RedditItem instance, not the underlying item's instance we assinged self.item to.

red solar
#

ohhh i completely missed it was bound :/

wide shuttle
#

I'm not sure I understand the structure correctly. Should RedditItem dynamically reflect the methods/attribute available to the specific item or do all three item types share the same interface/attributes?

shy belfry
#

It would need to dynamically adjust based on the item it encapsulates.

#

The only possible solution I've thought of so far (haven't executed anything as of yet) is to just assign pre-written functions but I'm assuming that then the self parameter gets "lost" as it's an unbound method?

red solar
#

classes like that are a pain to use since the IDE can't help you :/

shy belfry
#

Is there some way to bind methods to an instance instead of a class? Lol. That'd do a pretty sick job of solving my issue.

red solar
#

why are you trying to combine Submission, Comment, and ModAction under one roof?

tawny shoal
red solar
#

if they share methods, can't you just use them directly as they are?

shy belfry
#

Well, because essentially I only need two add two or three methods. get_embed() would create a JSON embed based on the item and return that, but just with slight alterations to the layout based on its type.

red solar
#

You can't create a separate class that has these 3 methods and each method (probably staticmethod) takes an item as the argument?

shy belfry
#

https://stackoverflow.com/questions/8980676/dynamically-bind-method-to-class-instance-in-python
@tawny shoal using descriptors? Interesting approach... I'm on this thread right now and it would work... But this lead right into issue #2 where I want to be able to customize those functions, so I'd be creating an abstract descriptor class and then just feeding it the function, huh?

#

You can't create a separate class that has these 3 methods and each method (probably staticmethod) takes an item as the argument?
@red solar I could... But I feel it's nicer to write item.get_embed() vs bot.get_embed(item).

#

It's mainly about creating a really nice interface for the users of the framework. Internally it'd not matter if it's one or the other.

red solar
#

maybe nicer to write, but using dynamically generated classes sucks

wide shuttle
#

Why don't you create a mixin class that adds those shared methods to the actual item types?

red solar
#

(unless you have brilliant documentation)

shy belfry
#

But this framework is returning those items to an end user... So for them utility methods seem meh.

#

Why don't you create a mixin class that adds those shared methods to the actual item types?
@wide shuttle how would it do that if the item comes from another library?

#

(unless you have brilliant documentation)
@red solar care to see my efforts on the aPRAW documentation so far? 😛

red solar
#

uhh

#

yeah sure

#

i think the mixin you could do class EnhancedSubmission(Submission, JSONMixin, OtherMixin)? or something similar (never used mixins before)

shy belfry
#

How would this enhanced class be instantiated though? aPRAW is returning a class Submission, and I don't think there's a way for me to change the items it builds, no?

#

The thing is aPRAW and this framework are completely separate. They're both by me, but aPRAW shouldn't have to adjust to fit this new stuff.

red solar
#

or is there a simpler way to check?

wide shuttle
#

Well, you could probably implement __setattr__ and __getattr__ to check if an attribute exists on self.item if it does not exist on self

shy belfry
#

Yep! The attributes are dynamically assigned because the API doesn't always return the same schema. It's best to check for the special ones. Later when aPRAW leaves alpha I'll add a more optimized hasattr() kind of function since I have the original data returned by the API.

wide shuttle
#

But it feels a bit too dynamic and magical

red solar
#

i like the documentation, to me it's nicely laid out - but i also feel it being dynamic and magical gets in the way :/

#

ever since working with amazon's boto3 dynamic classes are ruined for me

shy belfry
#

Unfortunately I have very little control over that. :/ Reddit's API is so finicky. I'm just going to try my best to add utilities to aPRAW's base class (which is used by all the dynamic models) so that it's as painless as possible to work with them.

red solar
#

if the attributes were always there, but sometimes returned None, and that was documented (which ones returned None), i think it would be easier to work with

smoky torrent
#

guys does any1 know some good beginner python projects ? all i have coded so far is a rock scissors paper game.

red solar
#

write a function where you give it a word, and it gives you the urban dictionary result (first one)

shy belfry
#

At the risk of going off-topic - my warnings about Reddit's API go beyond the models. It also switches complete types in the same endpoint and doesn't follow typical REST schemas for the endpoints.

red solar
#

that sounds like a nightmare to work that 😂

#

but shouldn't your framework abstract away that complexity, rather than propogate it to the user?

shy belfry
#

if the attributes were always there, but sometimes returned None, and that was documented (which ones returned None), i think it would be easier to work with
@red solar as @wide shuttle mentioned I can do this via __setattr__ going down the road, but I'll have to be very careful because I'm using (apologies for connecting literally every library I've ever made) ReactivePy which already overwrites those property accessors and setters, even so far as to implement the descriptor protocol for every model attribute. 😂

#

but shouldn't your framework abstract away that complexity, rather than propogate it to the user?
@red solar it will... I 100% swear. But it's in 0.5.5a0. Right now my focus is covering the endpoints, and abstracting away that pain won't be too hard since my class design is already using base classes where I'd be implementing the functions.

red solar
#

damn 0.5.5a0? you could teach me a thing or two about versioning 😂

#

was also gonna ask how you did your docs, but found the link

#

sorry idk if we mentioned this above, if you have class X, can you add a bound method to the class itself that any instance will be able to access?

#
class X:
    def __init__(self):
        self.a = 0
        self.b = 0
    def sum(self):
        return self.a + self.b

if __name__ == "__main__":
    x = X()
    try:
        print(x.mul())
    except Exception as e:
        print(e)

    def mul(self):
        return self.a * self.b

    setattr(X, "mul", mul)
    print(x.mul())
#

works as expected

#

from reddit_item_extensions import json as rie_json and then the act of importing it would change the original classes if they were already imported

#

nevermind this sounds like a terrible idea

#

very implicit :/

lost rain
#

Is there a way to get time into of user through discord bot?

narrow kettle
#

wut

lost rain
#

I wnt to get author timezone @narrow kettle

red solar
#

wrong channel - you want #discord-bots but to answer the question, no (but you can get their locale, which can give you a hint as to their time zone)

lost rain
#

@red solar how?

#

Plz ping me when u answer

boreal umbra
#

I learned recently that you can do something like comma_join = ', '.join and then you have a stand-alone function, but what does that say about how methods work?

#

I figured that when you do __getattr__ on an object and it doesn't find it in its instance dict, then it looks to the class, and if it's a method in the class, it just calls the function with the object itself as the first argument

#

but this suggests that a callable is being created that's bound to the object you accessed it from.

peak spoke
#

The function object from the class is bound when accessed through an instance

boreal umbra
#

Interesting

wide shuttle
#

This is how methods work in Python, although these built-in methods are slightly different from the methods you define yourself

#

Still, the same principle applies

boreal umbra
#

!e

bound = ', '.join
unbound = str.join
print(bound, unbound)
fallen slateBOT
#

@boreal umbra :white_check_mark: Your eval job has completed with return code 0.

<built-in method join of str object at 0x7f14a9203ef0> <method 'join' of 'str' objects>
wide shuttle
#

Yes

#

We can go through it, if you like

#

It involves something called "descriptors"

boreal umbra
#

Someone linked me to a page about descriptors (in this channel actually) and I said I'd read it. Then I forgot. But as I recall they're objects with extra control over their own state and are what underpin @property.

wide shuttle
#

Yeah

#

Let's back up a bit first and start from the start

#

A lot of people think that if you use a def statement within a class definition, it creates a methon; if you use it outside of a class definition, it creates a regular function. However, that's not the case: A def statement always creates a regular function object.

#

From our high level perspective, it does two things:

  • It creates a function object in memory
  • It assigns a name to that function object so we can use it
#

So, if we have:

def interesting_name():
    print("Hello!")
#

It creates a function object and then assignes the name interesting_name to it

#

It's very much like:

interesting_name = Function(...)
#

(There are a few simplifications here, but that's not important for now)

#

So, when we use a def statement within a class definition, we create a function like we always do, but instead of assigning a "module global" name, we assign a class attribute to the function:

class MyClass:
    def interesting_name():
        print("Hello!")

is more or less:

class MyClass:
    interesting_name = Function(...)
#

What we call "methods" are just plain regular function objects that we've assigned class attributes to

#

!e

class MyClass:
    def method():
        pass

print(MyClass.method)
fallen slateBOT
#

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

<function MyClass.method at 0x7f80a19dfe50>
wide shuttle
#

As you can see, it's just a function object and we've assigned MyClass.method to it

#

So, where does the argument for self come from?

boreal umbra
#

The instance you called it from. (Please don't be a trick question 😮 )

wide shuttle
#

Yeah, but if this is just a regular function, what inserts it?

boreal umbra
#

the class?

wide shuttle
#

I can call the method above just fine, without any insertion of self happening

#

!e

class MyClass:
    def method():
        print("called!")


MyClass.method()
fallen slateBOT
#

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

called!
boreal umbra
#

Wouldn't it try to pass the instance to it, and then it would break?

wide shuttle
#

The trick here is that when you access an attribute (name.attribute), it's not a simple name look-up, but there's a much more interested "chain of events" going on

boreal umbra
#

Of course in this usage there is no instance, since you're using the class itself.

wide shuttle
#

Yeah, so accessing the class attribute using the class object or an instance makes a difference here, but why?

boreal umbra
#

right. doesn't it look in the dictionary for the instance and then travel up the MRO?

wide shuttle
#

Right, that's part of it

#

Another part is that you have hooks to "hook into" this look-up process and those hooks are special methods called __get__, __set__, and __del__.

#

Instead of returning the object the name is assigned "as-is", Python will look if the object implements the method it needs and then calls it

boreal umbra
#

are descriptors kind of like how with pointers in C, you can just change what's at that memory location? And those three methods are what control that access? Or am I getting off track?

wide shuttle
#

No, they're more like the other specials methods we have, like __init__ and/or __eq__: They play a role in Python's data model and get called in certain situations

#

In this case, if __get__ exists, it gets called to handle the "look up" process so we can modify that

#

That means that in stead of just "looking up and returning a value", we can do something special and return anything we like

#

And the interesting part here is that function objects have a __get__ method.

boreal umbra
#

so __get__ behaves differently if you access it via a class?

#

well, an instance?

wide shuttle
#

That depends on the implementation of __get__

boreal umbra
#

for functions

wide shuttle
#

Yes

boreal umbra
#

so if you access a function via an instance, the __get__ method of that function returns a version of that function bound to the instance?

wide shuttle
#

A __get__ method gets called with the instance (the instance of the class you're accessing the attribute on) and the owner (the class) as arguments.

#

Yes

#

That's exactly right

boreal umbra
#

😮

wide shuttle
#

That's why this works:

#

!e

def strange_method(self):
    print(f"Hello from {self}")


class MyClass:
    method = strange_method

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

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

Hello from <__main__.MyClass object at 0x7f5ae51c39d0>
wide shuttle
#

A "method" is just a regular function object, but the way it's accessed is what's triggering that "binding" of the instance to the function

#

And that's what you were doing above: You had a str instance and you access the str method join on it.

#

That returns the join function, but bound to the instance

#

Since strings are immutable and calling join does not change the instance, you can create easy helper functions with that

#

!e

comma_joiner = ", ".join

print(comma_joiner(["a", "b", "c"]))
fallen slateBOT
#

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

a, b, c
wide shuttle
#

There's a bit more involved and I've simplified some parts

#

Fluent Python also has a great write-up

boreal umbra
#

I'll have to read this at work tonight when I don't want to work

#

I got Fluent Python from a humble bundle a few years ago. I hope they write a new edition.

#

I really appreciate you taking the time to explain all that

wide shuttle
#

A new edition is coming out early next year

#

February 9, 2021 according to eivl

boreal umbra
#

📖 lemon_hearteyes

#

why is eivl the one who knows specifically?

wide shuttle
#

eivl is a big fan of Fluent Python and has multiple copies, with at least one of them always on his desk.

boreal umbra
#

Aha

#

Speaking of humble bundle, the python bundle in 2018 was really helpful for getting me started. I haven't bought any sense since, but the current one actually looks useful.

#

Huh, actually the data science item looks like it's a fresh intro to python for data scientists rather than python users trying to learn data science.

paper echo
#

Data science item?

boreal umbra
#

So it's presumably a license to access online content rather than something that could be distributed to people asking questions in the data science channel.

#

It also has the "managing python dependencies" material that RealPython was hyping two or so years ago. Though I'm not sure if that conveys anything other than using pip and venv.

formal echo
#

What's the equivalent for __add__ but for unions like x |= <something>? I got a class that handles sets, and I want to be able to do x |= class_instance by using the correct function for it. thought python -m trace --trace script.py would show these calls but apparently it doesn't heh.

charred wagon
#

__or__?

#

Don't think it's any more complicated than that

flat gazelle
#

when __or__ is not present, it never gets called, so nothing appears in trace

#

you can look at the data model docs to see most dunders

spice pecan
formal echo
#

Cheers, yepp it's __or__. I always find it hard to google for these things, python union function class gives little to nothing. Thanks for the quick replies! : )

#

@flat gazelle are they called dunders? o0

#

Thanks @spice pecan !

spice pecan
#

double underscore

formal echo
#

aaah haha, nice one! ^

flat gazelle
#

dunders or magic methods are the most common names I hear. You would want to lookup bitwise or, not union, as that is the more common meaning of the operator in context of general programming

charred wagon
#

What's good practice for type aliases used in annotations of public functions? May the aliases be "private" or should they always be public too? I don't really want to pollute the namespace with them.

boreal umbra
#

@charred wagon I have no idea but using a private enum comes to mind.

#

That might be a terrible solution.

charred wagon
#

I don't understand how an enum fits in here

pseudo cradle
#

Enums are a thing but they don't feel very Pythonic

#

Maybe that's just me though

boreal umbra
#

I didn't even know Python had enums until a friend of mine who at that time hated python asked how to use them

#

so I think a lot of Python users feel the same way

#

But you could have all your type aliases in an enum, and the enum can be private. That way there's only one extra thing in the module namespace, and it's private.

charred wagon
#

I like them. Using strings as identifiers is error-prone

#

Oh I see. I think that would be too verbose and pretty much make the aliases ineffective

boreal umbra
#

I thought aliases were only parsed by linters doing static analysis

charred wagon
#

Technically yes but humans read them too

#

It's in the code, after all

boreal umbra
#

hmm

#

if you have an __all__ then isn't everything not in all not importable?

charred wagon
#

That only applies for star imports

boreal umbra
#

hmm

#

I hate those anyway.

charred wagon
#

Besides, what would be the point of using a public naming convention if they couldn't be accessed?

boreal umbra
#

Mainly because it makes it hard to do help sessions on here when you don't know where the person's code is coming from.

charred wagon
#

That seems a bit out of context

#

Oh I see

#

ABout the star imports

boreal umbra
#

I'm just saying why I dislike star imports.

charred wagon
#

Well here are my type aliases

#
Argument = t.Union[int, str]
BoundArgs = t.OrderedDict[str, t.Any]
_IdCallableReturn = t.Union[t.Hashable, t.Awaitable[t.Hashable]]
_IdCallable = t.Callable[[BoundArgs], _IdCallableReturn]
IdApplyFunc = t.Callable[[t.Any], _IdCallableReturn]
ResourceId = t.Union[t.Hashable, _IdCallable]
#

I don't know if anyone would find this crap useful outside the module

boreal umbra
#

are those types that you return?

charred wagon
#

No. They are for parameters

boreal umbra
#

I see

#

idk

charred wagon
#

same

boreal umbra
#

Have they ever amended pep 8 for this kind of thing?

charred wagon
#

Doubt it

#

I've seen private aliases used before I'm just trying to figure out when that's applicable

boreal umbra
#

I've been thinking, it's pretty clear that Python is going to remain dynamically typed

#

but

charred wagon
#

Like it lets you do isinstance checks I think, but I doubt anyone will be doing that, especially for callbacks

boreal umbra
#

if they decided to make it so that type hints were a commitment when you use them, do you think they could optimize the language any further?

charred wagon
#

No idea

boreal umbra
#

Come to think of it, I'm not sure it's feasible to implement because if your return type is t.Union[...] then you just get less and less guaranteed going forward

#

And if it's t.Any then you're back where you started.

charred wagon
#

Well, this is probably a bad example since passing around functions is relatively complicated in terms of typing

shy belfry
#

Well, this is probably a bad example since passing around functions is relatively complicated in terms of typing
@charred wagon shudders Callable[Any, Awaitable[Any]] lmao.

charred wagon
#

Async support thumbsupsmiley

#

@shy belfry What they do depends on the type. Anything with equals is basically the equivalent of what += does but with a different operator e.g. x |= y is x = x | y

shy belfry
#

Async support :thumbsupsmiley:
@charred wagon I'm writing two asynchronous libraries at the moment.

#

I guess you could say I'm writing them...

#

Concurrently.

charred wagon
raven ridge
#

May the aliases be "private" or should they always be public too?
@charred wagon What I've been doing is making them public if the user of your library might want to use them for their own type hints (because they pass an object of that type to your library at some point, or get one back from you), and to make them private if users never see them (because they're passed from one of your public functions to one of your private ones, or something like that)

shy belfry
#

@shy belfry What they do depends on the type. Anything with equals is basically the equivalent of what += does but with a different operator e.g. x |= y is x = x | y
@charred wagon ohhh... I see! I so often fail to use and and or properly in general when it comes to knowing what they return. I so often end up doing shit like x = x if x else y. 🤦🏽‍♂️

#

I guess I like the explicit approach. :P

raven ridge
#

the return of and and or is pretty easy. x and y returns x if x is falsey and y otherwise. x or y returns x if x is truthy and y otherwise.

charred wagon
#

@raven ridge Thanks. That's what I was suspecting when working with public functions. What would you do for unions? Only make the unions public or the aliases they use too?

#

Is that too dependent on context?

raven ridge
#

same logic applies - if users would want to declare a variable using one of the aliases inside the union, make it public. If they wouldn't, it's OK to be private.

sacred tinsel
#

I was annoyed recently about my IDE raising a warning about importing something private, but it was an actual class (imported for the purposes of type annotating)

charred wagon
#

I this case I'm dealing with passing functions, so I am kind of doubting the usefulness of making them public.

raven ridge
#

leave them private til your users complain, then 😄

shy belfry
#

How do you guys write private classes? Just _?

raven ridge
#

yep.

#

or no _ but it's in a private module (whose name starts with _)

charred wagon
#

I've actually been moving stuff over to a utility module, so it wouldn't be as annoying to leave them public. But you're right, i shouldn't try to overthinking it too much. Just becomes a guessing game.

shy belfry
#

the return of and and or is pretty easy. x and y returns x if x is falsey and y otherwise. x or y returns x if x is truthy and y otherwise.
@raven ridge thank you! I'll try to memorize this!

raven ridge
#

@shy belfry the logic is that, since both short circuit, x or y may know that the proposition is true after only looking at x - if x is truthy, x or y is truthy , so if x is truthy it can just return that and have a truthy value without ever evaluating y. Likewise, x and y may know that the proposition is false after only looking at x - if x is falsey, x and y is also falsey, so if x is falsey it can just return that as a falsey value without ever evaluating y.

#

And in the case where it can't know by just looking at the first argument, then the second argument proves the proposition if it's truthy, and disproves it if it's falsey, for both and and or, so in that case it can just return whatever y evaluates to

#

or, to try to put that more simply - x and y is truthy if x is truthy and y is truthy. If x is falsey, then x and y needs to return a falsey value, and x is a falsey value, so it can return that. If x is truthy, then x and y is truthy if y is truthy, so it can return y.

shy belfry
#

@raven ridge that is truly a fantastic explanation! I think I can say I fully understand the purpose of those operators now, and just need to focus on remembering to use them where it makes sense!

crystal pebble
#

What's the difference between truthy and falsy? I thought all truthy values were made true and similarly for falsey

shy belfry
#

Thank you so much!!! ^^

#

What's the difference between truthy and falsy? I thought all truthy values were made true and similarly for falsey
@crystal pebble well, I hope this one I can explain. Truthy just represents the boolean evaluation. A non-empty string, list, numbers that aren't zero and non-NoneTypes are all truthy. Whereas the opposite is falsey.

crystal pebble
#

Right, but don't they just get evaluated to true or false?

shy belfry
#

They retain their original value AFAIK to do stuff like @raven ridge elaborated.

raven ridge
#

!e ```
print(None and [1])
print(False or 42)

fallen slateBOT
#

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

001 | None
002 | 42
crystal pebble
#

What's confusing me is needs to return a falsey value. I think I was misreading it

raven ridge
#

a truthy value is one where, if you use if value on it, the branch is taken, and if you use bool(value) on it, True is returned.

#

falsey values are the opposite.

shy belfry
#

For some reason in Js this has always made more sense to me...

raven ridge
#

in C, && and || return a bool. In Python, and and or don't - they return one of their operands.

crystal pebble
#

I know about that, I think I just misinterpreted something before

#

:+1:

raven ridge
#

and the operand that they return is the last one that needed to be evaluated in order to determine whether or not the x and y or x or y expression itself is truthy.

native lynx
#

im running a sha256sum on a Minecraft map. I have determined 2 things: first a sha256 sum has 2^256 possible combination for hashes, and secondly a Minecraft map (random seed generation) is not generating anything with enough entropy to be different at the hash level. i would like to be able to determine small discrepancies in the map using some sort of file hash/fingerprint but with each block being only an 8bit value with 256x256 square blocks at an average height of 80 the map tiles are too small to produce uniquely identifiable values. i ran a sha sum of a 12 Gig map and have 451 out of 4,023 maptiles that are showing the same hash. with a random noise generation function for the world gen i find this hard to believe that those tiles are identical. (lol i almost want to swap the tiles around based strictly on the hash just to see how screwed up the map gets) but long story short aside from doing a binary diff is there a way i can assign each title a UID based on the contents that wont produce a hash collision?

crystal pebble
#

Have you looked at perceptual hashes?

raven ridge
crystal pebble
#

https://en.m.wikipedia.org/wiki/Levenshtein_distance Use this to check the difference

But yeah, wrong channel

In information theory, linguistics and computer science, the Levenshtein distance is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletion...

native lynx
#

but im writing the script in python?

raven ridge
#

sure, but all the channels are about Python (except the 3 off-topic ones). This channel is specifically for discussing things about the Python language itself (like the conversation above about the way that and and or above).

native lynx
#

ah ok i didnt realize it was the wrong channel for brainstorming 🙂

magic python
#

would it be possible to have df[['somethi*', 'another*', 'this*']] to match pandas column names using globs?

#

obviously it's not default behaviour, i'm not sure how it would even be done though

raven ridge
#

pandas could do that in the dataframe's __getitem__, yes.

magic python
#

@raven ridge this is something that would have to be added into pandas, and it would be in the __getitem__ 'dunder' ? 🤔

raven ridge
#

yes. because dataframe.__getitem__ is the function that handles df[anything]

magic python
#

would it be possible to make a package that sort of 'overwrote' that? Obviously it wouldn't be considered for pandas, but if i wanted that functionality what would be a typical approach ?

raven ridge
#

you could subclass dataframe to make your own class, and define a different __getitem__ for your version.

magic python
#

interesting, idea of globs sounds nice for terminal sessions... is this sort of thing often done - subclassing this kind of thing and overwriting?

#

or is it considered a bit hacky

raven ridge
#

it's hacky. less hacky would be defining your own class that wraps a dataframe without subclassing from it.

magic python
#

is monkey patching related to this?

raven ridge
#

that would be even more hacky - you could monkeypatch a different __getitem__ onto dataframe, without subclassing from it or wrapping it.

#

subclassing is a bit less hacky, but still hacky, because you'll have to be very careful to avoid violating the Liskov Substitutability Principle - but if this is the only change you want to make, it should be OK, as long as your behavior for a glob without any wildcards matches what Pandas would do by default.

#

creating a new class that holds a dataframe as a member variable, rather than inheriting from dataframe, gives you the most flexibility, and doesn't come with any Liskov Substitutability concerns - since you're not a subclass, users wouldn't expect that they could pass your dataframe to a function that expects a Pandas dataframe and that it would necessarily work.

magic python
#

I think i get how i could have a class and have some way of indexing with blah* and passing that to pandas, but i dont' see out id' have all the other pandas methods for that new class by default, unless it inherited

#

say i have df = NewDataFrame(), i might be able to do df[['blah*']], but what about df.groupby or whatnot, if i didn't inherit then I'd lose the standard pandas functions wouldn't i?

raven ridge
#

right, you wouldn't be able to have them by default, you'd need to define each of those methods, and pass the arguments to the pandas dataframe that you're wrapping.

magic python
#

that would be a lot 😅

raven ridge
#

you can avoid that if you can make your class a true, Liskov-substitutable subclass of the dataframe, but it would be a hack to do that if you wouldn't be able to work in places where a Pandas dataframe is expected

#

that is, if the only thing you want to change is __getitem__, and you're comfortable defining your __getitem__ so that any arguments that would have been valid for a Pandas dataframe are also valid for you and do the same thing, and the only change is that some things that would have failed if you passed them to a Pandas dataframe now work when passed to your dataframe, then subclassing is reasonable.

#

if there's any cases where an argument would be valid for both a Pandas dataframe and your dataframe, but your dataframe will do something different if it gets that argument, then subclassing would be a hack, because you're violating the basic is-a relationship of subclassing.

magic python
#

right - so if there was a single augmentation, that globs worked as column names, then it would work with my DF but not with a pandas df, eg df[[thing*']] would work if it was mine, but not pd.DataFrame. Globs are not valid for both, although * can be in a column name, so I'm not too sure if that violates it

#

I guess it does 🤔

#

yeah, because you can do df['a*'] = None and have a* as a column, then df['a*'] would return something different if it was a pandas dataframe vs if it was my dataframe, mine would return ['a', 'aaa', 'apple'] etc

raven ridge
#

right. But you could maybe define that to work...

#

you could maybe say that a* will look up a column named a*, but if one isn't found that it will do your new special behavior - then you could probably get away with it.

unkempt rock
#

i need help in cv2

#

if someone know anything about cv2

magic python
#

@raven ridge yeah, interesting. I've not done anything like this before - so in summary the approach could be to subclass pandas dataframe and create a new __getitem__ which permitted globs?

raven ridge
#

yep, being careful not to change the behavior of existing, valid operations.

paper echo
#

Behold, a valid use case for inheritance

#

Or you can monkey patch the method on

#
pd.DataFrame._old_getitem = pd.DataFrame.__getitem__
pd.DataFrame.__getitem__ = my_custom_getitem

Then the custom method can still call the original

pliant tusk
#

I’d say monkey patching is really only a valid use case if you want another library to have the new functionality for DataFrames

tawny shoal
#

Even for external libraries I think a PR is better than monkey patching

#

but that's just my experience so far

pliant tusk
#

Well if you only want it for one project

#

Like if I for some reason wanted to log every call to externalmodule.cls.func or something like that

tawny shoal
#

Often times you missing a feature in a library that you can't get by subclassing could hint at a design issue of the library

#

or it could mean that you're trying to do something the wrong way

pliant tusk
#

More often the second

tawny shoal
#

more often than not it's at least either of them is what I'm trying to say ^^

pliant tusk
#

The only time I condone monkeypatching is when you’re patching python internals to add more functionality

tawny shoal
#

Like if I for some reason wanted to log every call to externalmodule.cls.func or something like that
@pliant tusk that's probably an exception yeah

#

The only time I condone monkeypatching is when you’re patching python internals to add more functionality
@pliant tusk what would be an example of that?

spark magnet
#

@pliant tusk that sounds nasty also. Why would you need to do that?

pliant tusk
#

Oh it’s nasty but it can be fun

tawny shoal
#

If you mean changing how some internals work then I'd never do that because people who contribute to your project could be really confused by what's going on in your code/why some builtins are suddenly doing something unexpected

#

I appreciate the way you wrote that description though :p

pliant tusk
#

Ya I never said it was a good idea

spark magnet
#

i don't think @pliant tusk means for people to do this in real code

tawny shoal
#

at least you tell users what they're getting themselves into

pliant tusk
#

But it can be fun

tawny shoal
#

yeah I see that now haha

pliant tusk
#

Just a warning if you want to mess with that lib, it segfaults sometimes if the replacement function throws an exception

tawny shoal
#

Adding to the builtins seems fine tho. I for instance have this line in my code:

builtins._ = translate

so I can easily handle i18n across my entire project

pliant tusk
#

I personally wouldn’t use ._ cause that’s used in the interpreter for the last returned value

tired trellis
#

Has anyone here messed with Pandas before for Python to scrape csv files?

I have been trying for some time now to basically export data in a csv file that in a certain column contain something I am looking for

I have tried

for x in filename[column name]:
and did some if statements here

i removed the for x in stuff because it was not working earlier

tawny shoal
#

I don't think it matters

#

@tired trellis this is not a help channel

tired trellis
#

Oh sorry

pliant tusk
#

In most cases it won’t, I just tend to explore libs in the interpreter, dunno if other people do stuff like that

tired trellis
#

The entire channel is not for help?

tawny shoal
#

I see what you mean though, like

_, something = func_that_returns_tuple()

could mess with it

peak spoke
#

It's only used like that in a repl session, outside of it it's nothing special. Both using it for i18n and for unused variables is common

spark magnet
#

@tawny shoal patching builtins is also confusing. Just import that name where you need it.

tawny shoal
#

I generally agree with that actually

#

Explicit is better than implicit

peak spoke
#

I don't think it's all that bad with i18n, gettext also does it

tawny shoal
#

doesn't mean it's good I definitely get Ned's point

#

I still do it though, simply because of how convenient it is and because people are somewhat used to it thanks to gettext

peak spoke
#

It is also something that's almost completely irrelevant to how the app works, apart from the i18n part of it. So taking up the least visual space by using the _ name and not cluttering the imports is an improvements in that case imo

tawny shoal
#

can just do

from .i18n import translate as _
#

don't think it's that big a deal to do that (I think at least that that's what Ned meant)

unkempt rock
#

sounds weird but i also need some to help me extract data from a website hashes database

tawny shoal
#

This is still not a help channel :x

pliant tusk
#

@tawny shoal i wrote this a while back for hooking builtins/whatever py def hook(func, new_func=None): def deco(nfunc): @functools.wraps(func) def hfunc(*args, **kwargs): return nfunc(func, *args, **kwargs) hfunc._hooked = True if globals().get(func.__name__) is func: # allows for hooking of functions imported into the global scope `from module import func` globals()[func.__name__] = hfunc setattr(sys.modules[func.__module__], func.__name__, hfunc) return hfunc if new_func is None: return deco return deco(new_func)

tawny shoal
#

beautiful

pliant tusk
#

it looks weird cause i wanted it to work as a decorator as well as a 2 arg function

#

used it to hook __build_class__ cause i wanted to mess with class bytecode

tawny shoal
#

sounds like funTM

pliant tusk
#

it made classes act like functions

tawny shoal
#

cool cool

#

never got into that kind of stuff myself but it's intriguing, even just to mess with stuff and to see what you can do

pliant tusk
#

part of the reason why i like python so much is because its so dynamic as a language that you can do stuff like this (relatively) easily

loud summit
#

@unkempt rock automating snapchat is against their ToS and we wont help you with that by our rule 5

pliant tusk
#

^ also afaik it would be impossible without extracting private keys from the app

tawny shoal
#

The most I ever did was make a function act like an async one if called from an async context and like a regular one when called from a non-async context

#

actually that was a descriptor

#

for an ORM

pliant tusk
#

see that has an actual use case, thats dope

tawny shoal
#

(Django's)

#

that stuff is weird because there isn't really a clear way to check if you're in an async context

#

asyncio.get_event_loop is the closest you get and even that has caveats

#

gotta check if that loop is running, too

pliant tusk
#

did you use asyncio.get_event_loop or something else?

tawny shoal
#

I'd have to look it up again, second

pliant tusk
#

thats clever

tawny shoal
#

async_using_db is asgiref.sync.sync_to_async with thread_safe=True and some extras

pliant tusk
#

makes sense

#

pretty damn clever

tawny shoal
#

ty :)

#

Basically if you had a Model instance and would try to access a ForeignKey attribute, you'd have to await that attribute access if you're in an async context, and if you're not you don't

pliant tusk
#

thats helpful

tawny shoal
#

I made it that way because in Django, accessing a ForeignKey attribute can be a database operation depending on whether or not the value is cached

pliant tusk
#

im re-reading thru my py_future code and realizeing so much of it is just wrong

tawny shoal
#

So for that to work I'd have to make sure it's a threadsafe operation

pliant tusk
#

i wrote it before i learned C so its even more unsafe than i realized

tawny shoal
#

obligatory Rust comment

pliant tusk
#

i learned C for arduinos

#

afaik rust doesnt support arduino, but i also have not done any research on that so dont quote me on that

tawny shoal
#

It does

pliant tusk
#

huh maybe i should have learned rust

tawny shoal
#

I mean C is fine

#

for now at least

pliant tusk
#

well im learning Golang now for an internship

#

gotta tack rust on after that one

tawny shoal
#

gonna be difficult but rewarding, learning Rust will make you a better programmer overall, even in other languages

#

but yeah topic,,

pliant tusk
#

to get back on topic, i wonder if it would be possible to make python statically typed at runtime

tawny shoal
#

There's only mypy that I know of

pliant tusk
#

like using builtin and internal hooks

#

oh i meant like make it possible for ```py
import typechecking

... # regular python that has type hints, now enforced at runtime

#

its prob possible for funcs/ classes but idk about the global scope

tawny shoal
#

you can typehint globals as well, why not?

pliant tusk
#

its not stored anywhere tho

#

and to get typechecking on the inside of functions you'd have to force reload typechecking after the module it was imported to and patch the code of each func

tawny shoal
#

good point @pliant tusk

#

In that case you'd probably have to code it into the interpreter

spark magnet
#

@unkempt rock also, don't put the same messages in many channels at once

unkempt rock
#

im sry

pliant tusk
#

@tawny shoal if you could somehow know what file typechecking was imported into, you could maybe grab the file's contents, edit them, then eval them to create/run the module, then abort importing the original file

tawny shoal
#

That raises a lot of red flags for me

#

lots of consequences that are not accounted for

pliant tusk
#

i mean, if it just ignored each non typehinted variable then it couldnt end too badly

tawny shoal
#

I'd just modify how type hints are implemented on the interpreter side

pliant tusk
#

yea that would prob be easier

#

be cool if that modification could be done in pure python too

tawny shoal
#

PyPy is a thing :p

#

TypePython? TyPython?

pliant tusk
#

TyTy /s

tawny shoal
#

Or maybe mypy

pliant tusk
#

weve gone full circle at this point

tawny shoal
#

but yeah I think static typing for Python is at a pretty good place rn with mypy and type annotations

narrow kettle
#

its as good as your gonna get without just being a static language

tawny shoal
#

Just my thoughts ^^

magic python
#

how stable is it? do people use it in production?

spark magnet
#

@magic python it doesn't run when you run your code, so it's not risky

#

it's a linter, and people use it on real code. Dropbox wrote it for their code.

magic python
#

ok, i need to read about it... i don't know the diff between typing and this really

spark magnet
#

mypy is a tool that uses the annotations from the typing module.

magic python
#

def fib(n: int) -> Iterator[int]: right - this -> is part of typing isn't it?

narrow kettle
#

that is a type hint yes

magic python
#

when people say types they're referring to data types i guess - but what about something that contains datatypes

#

like, what if it should be a list of ints, you'd just have def f(...) -> list: I guess? Or - what if it's a pandas dataframe?

narrow kettle
#

when people say types they're referring to data types i guess
uhh wdym datatypes

#

its just types

tawny shoal
#

I think what you mean are nested types

unkempt rock
#

Bruh

#

Watch me hack into an acccount

tawny shoal
#

for that the typing module provides some helpful things

unkempt rock
#

But this shit will take time

narrow kettle
#

nested types doesnt really make sense?

magic python
#

<@&267629731250176001> @unkempt rock

tawny shoal
#

It's probably not a term professionals would use :p

shy vine
#

!ban 360131765182136324 No thanks

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied ban to @marsh timber permanently.

tawny shoal
#

I'm talking from the perspective of the typing module

magic python
#

yeah sorry I might have used the wrong word @tawny shoal 😅
list is not referred to as a type?

narrow kettle
#

do you mean like list(int)

#

kinda thing

shy vine
#

I don’t think there’s a mechanism to hint types for data frames

narrow kettle
#

list is a type yes

tawny shoal
#

typing.List[int]

narrow kettle
#

ahh thats what you meant

magic python
#

oh sorry - i mean if the return was [1, 2, 3]

tawny shoal
#

if your list contains exclusively ints, then use typing.List[int]

narrow kettle
#

thats just a list type

#

you can also specify the internal type if you want

tawny shoal
#

though that's entirely optional

#

you can just type hint list

magic python
#

right , so if there are mixed types then it can't be checked for, guess it makes sense

tawny shoal
#

Yeah

spark magnet
#

this is a risk with typing: are you sure you want to say List? Maybe Iterable would be better.

narrow kettle
#

hinting iterable is usually preferred imo

tawny shoal
#

typing.List[Any] is an option if you want to be explicit about it

narrow kettle
#

same way you would return an enumerable in other lnags

magic python
#

it just felt as though it only went "one level deep" i guess - not sure how to better describe that

spark magnet
#

hard to say: it might be that it has to be a list.

narrow kettle
#

ik what you are saying rie

tawny shoal
#

Good point, if it can be any type of iterable then sure, Iterable is better

narrow kettle
#

hints are only a bandaid oc

#

you wont be able to perfectly match the capabilities of a static lang, because well python isnt static

tawny shoal
#

yeah, they're just hints/annotations, not strict limitations

#

they help your fellow devs understand and use your code though

narrow kettle
#

they are for the devs, not for the compiler

tawny shoal
#

And fellow devs includes future you :p

magic python
#

interesting, i've been playing more with tools like pylint, pre-commit and stuff recently, i guess there's a fairly hard ceiling to how much can be caught because of pythons design tho

tawny shoal
#

yee, it's very dynamic

#

hmm I suppose it's good if you follow the Google style

magic python
#

yeah i use google

tawny shoal
#

just know that

#

!pep 287

fallen slateBOT
#
**PEP 287 - reStructuredText Docstring Format**
Status

Active

Created

25-Mar-2002

Type

Informational

magic python
#

this is in the pandas code - they should have that on a single line, no ? 🤔 I get a warning for this lol

tawny shoal
#

is the standard

magic python
#

rst is awful tho :/

#

(imo)

tawny shoal
#

Yeah you don't have to use it ^^ it's just neat for Sphinx

magic python
#

i battled with sphinx and lost

tawny shoal
#

That warning seems wrong but I'm not 100% sure

magic python
#

for what - the docstring?

tawny shoal
#

yeah

#

pretty sure I read it's up to the developer as long as they're consistent about it

magic python
#

i can't recall the code - but if there's a docstring that's a single line then it should be on a single line, apparently

tawny shoal
#

but yeah I'd put single line docstrings on a single line myself

peak spoke
#

Docstrings don't have much style set, beyond the quotes and some very general things. After that it's all the dev's opinion

magic python
#

@tawny shoal you can use darglint with sphinx style btw

tawny shoal
#

thing is, all these style guidelines are just that, guidelines

magic python
#

just it defaults to google

narrow kettle
#

i do new line

#

fwiw

magic python
#

monster

narrow kettle
#

but i dont really have a reason

#

i just think it looks nicer

tawny shoal
#

Docstrings don't have much style set, beyond the quotes and some very general things. After that it's all the dev's opinion
@peak spoke well there is

#

!pep 257

fallen slateBOT
#
**PEP 257 - Docstring Conventions**
Status

Active

Created

29-May-2001

Type

Informational

magic python
#

what's newline

"""
i am a newline
"""

or

"""i am a new line
"""
tawny shoal
#

and pep8 also has a thing or two to say about them

#

newline is \n

#

I don't understand the question x)

magic python
#

i get warnings about not using imperative grammar in my docstrings

#

sorry - i meant which of those two does J mean when they say "I use new line"

#

and missing full stops

tawny shoal
#

oh yeah the first one is new line

#

it does look more symmetric

#

and Python usually is symmetric so it'd make sense to do it that way

magic python
#

i think

"""I am a newline."""

is nicer as it takes less space

#

but it's not something i'd ever argue for lol

tawny shoal
#

although one liners should just be on a single line yeah

peak spoke
#

some parts of style guides are de facto rules in the community (or normal rules in a project), but globally for docstrings that is usually just the simplest things - because well, it is a form of a comment and influenced by other things like the max line length and perhaps even the language

narrow kettle
magic python
#

I'd get told off for not having a full stop there

tawny shoal
#

some parts of style guides are de facto rules in the community (or normal rules in a project), but globally for docstrings that is usually just the simplest things - because well, it is a form of a comment and influenced by other things like the max line length and perhaps even the language
@peak spoke I probably agree with you ^^

narrow kettle
#

I'd get told off for not having a full stop there

a what?

tawny shoal
#

full stop: .

narrow kettle
#

a period?

tawny shoal
#

yes

magic python
#

to a given would be flagged, and should be to a given. by my linter

narrow kettle
#

ya my grammar isnt perfect, not really something i think about real hard

#

uhhh why woudl ur linter tell you to put a period there

magic python
#

maybe these settings would be nice for you too then

tawny shoal
#

all good ^^ but yeah a lot of people call that a full stop esp in the context of a sentence

narrow kettle
#

that makes no sense

magic python
#

because it's the end of a sentence I guess, idk

narrow kettle
#

i have never heard someone say full stop to mean a period lol

magic python
#

It's very common

narrow kettle
#

because it's the end of a sentence I guess, idk
uhh event is the end of the sentence

tawny shoal
#

bri'ish people I swear

violet flare
#

Ever heard interrobang, octothorpe?

narrow kettle
#

Subscribes a method as a callback listener to a given event.

magic python
#

@narrow kettle lol 😆 yes sorry, after event

narrow kettle
#

im american tbf

#

is that a weird british thing 😁

tawny shoal
#

yeah I think it's a brit thing lol

magic python
#

I've been outed by full stop.

tawny shoal
#

hehe

violet flare
#

Exposed

magic python
#

here's the error that i get btw:

D200 One-line docstring should fit on one line with quotes
tawny shoal
#

Good point though (heh), why would you have to end a docstring with a full stop?

magic python
#

D400 First line should end with a period

tawny shoal
#

pydocstyle o.o

#

yeah sounds weird, I'd disable that one

magic python
#

I also get D401 First line should be in imperative mood; try rephrasing

narrow kettle
#

i have alot of stuff disabled tbf

#

i dont strictly follow pep8

tawny shoal
#

Who does

narrow kettle
#

like i have line length set at 130

magic python
#

🤢

tawny shoal
#

I mean, imagine limiting your lines to 79 chars

narrow kettle
#

which is still too short imo but ehh

tawny shoal
#

my limit is 100 because some people do have small screens

#

including myself cause im poor

magic python
#

if you limit to them ~ 80 then you're more likely to get nice pandas formatting with black

#

In my opinion at least

narrow kettle
#

im on a tiny ass mbp and 130 is fine lol

tawny shoal
#

my eyes are not good enough for that x)

magic python
#

For me, 130 is too much, we use 100, i could probably be fine with 90 tho

narrow kettle
#

i despise using \ to break up lines

#

i hate it

tawny shoal
#

100 feels like it's the new standard, wouldn't be surprised if it actually is

magic python
#

very rare that I do that to be honest

peak spoke
#

in almost all cases you can break up long lines with parentheses

narrow kettle
#

id have to do it all the time if i dropped down to 100

magic python
#

if i did then i'd usually just have ("one" "two") on different lines

tawny shoal
#

I do it only if I have a file full of multiline strings and nothing else

magic python
#

idk why you would have so many long strings 🤔

tawny shoal
#

laziness, basically.

#

What I meant to say: It's Complicated™️

magic python
#

does anyone not use black?

peak spoke
#

I think it's only the with where it's currently syntactically required to use \ for a line continuation, or then in things like long string literals

tawny shoal
#

I don't use black, don't need it

#

pep8 is ingrained in my brain

magic python
#

so when you pass black over your code and diff there are no changes?

peak spoke
#

I've never used it, just flake8 on precommit on bigger projects and pycharm's linter warnings

magic python
#

i love black

tawny shoal
#

I don't think so, no

narrow kettle
#

long string are where i use them

tawny shoal
#

I also use PyCharm*

* actually I use IntelliJ but same thing

narrow kettle
#
    "python.linting.flake8Args": [
        "--max-line-length=130",
        "--ignore=E402,F841,F401,E302,E251,E305,W291,W292,W293,W391,E265,E128",
    ],
#

my defaults

peak spoke
#

(meant skipping newlines in """ literals for the \s)

magic python
#

do you have much in pre-commit @peak spoke ?

tawny shoal
#

yeah that's what I use them for too

peak spoke
#

Pretty much only flake8 in general, which runs its plugins

queen acorn
#

when you have a method, and you put __ either side of the method name, but the method is standard like __repr__, are you basically just rewriting that method for that class?

magic python
#

@peak spoke is that using a dot file for flake?

tawny shoal
#

@queen acorn yup, your name would clash with that of an existing method so you'd end up overriding it

magic python
#

oh it was pylint i was looking at recently with pylint --generate-rcfile not flake

queen acorn
#

@tawny shoal Ahhh, I see. Thank you :)

tawny shoal
#

avoid creating new "magic methods" unless you have enough experience to be really confident in knowing their meaning

queen acorn
#

Gotcha 👍 That makes sense.

narrow kettle
#

metaclass shenanigans

peak spoke
#

Well you should never create completely new dunders, they either exist as a part of the datamodel or a 1st party module, or they shouldn't be used because they're reserved for those

magic python
tawny shoal
#

It really depends on how far meta your code goes I feel like

#

yes rie

magic python
#

ok cool, i've never heard of it, i don't do oop tho

tawny shoal
#

you do though, all the time when using Python

#

Highly recommend to give it a chance

magic python
#

bc everything is an object?

tawny shoal
#

It's so essential

#

correct

peak spoke
#

Not the page directly, but what it refers to. The data model is how (c)python organizes its data

magic python
#

i get that, i just don't do anything in terms of making classes for things, I never make a class in the code that I write

#

I use modules and packages, and have things running various different analysis 🤔

#

but, no OOP

tawny shoal
#

I'll just recommend you to give it a try because there are so many use cases that oop covers

#

I personally use it all the time

magic python
#

i feel people who use it are working on larger projects I guess, but i probably should have a look

tawny shoal
#

yeah if you want to grow beyond simpler things I think there isn't much of a way around it

#

at least in Python

magic python
#

depends what you mean by simpler I guess?

tawny shoal
#

which is not to say you can't possibly write only functional-style code in Python, but you'd probably not do yourself a favor :p

magic python
#

something could be mainly functional but still doing some non-trivial work

#

are there any go-to examples of a functional approach being worse than OOP ?

tawny shoal
magic python
#

😅

#

I'm going to read and try and convince myself they're wrong so i don't have to learn something...

#

ok tbf I do use attrs sometimes

tawny shoal
#

If you're gonna be serious about programming, I think I'll have bad news for you

#

You'll never stop learning.

magic python
#

yes I'm aware

tawny shoal
#

Better get used to it :p

narrow kettle
#

are there any go-to examples of a functional approach being worse than OOP ?
write a large state based system and come back to me 😁

tawny shoal
#

I think the article I sent is actually not bad at all, I'm Feeling Lucky

magic python
#

lol, i'm reading now, the encapsulation bit sounds kinda useful

#

A lot of the stuff I do involves processing / generating / shaping data tho, so i don't see how OOP would really make much of a difference there

narrow kettle
#

umm thats the whole point of oop?

#

you model your data as objects and act on that

magic python
#

maybe I is the key word there then 🤦‍♂️

narrow kettle
#

what?

magic python
#

I mean - I don't mean to say that there isn't a case for it - just that I don't personally see it

#

you'd model a survey as an object?

narrow kettle
#

oc

#

a survey has many parts

spark magnet
#

and you might want many of them

narrow kettle
#

it has a name, it has a desription it has options it has results

#

these are all atributes of an object

#

which you can then create an arbitrarily large amount of as ned said

magic python
#

But if you have a bunch of surveys, and you have to clean them up and bind them together, i really don't see how objects are going to help you achieve that any easier than functions and pandas

narrow kettle
#

i mean you havent told use specifics but im assuming rn you are just passing around primitives and such and using that

magic python
#

A lot of the time one set of data is completely different to the next , and needs different functions written for it, there wouldn't be some catch all class Survey: that would satisfy this, I doubt.

narrow kettle
#

i mean if youve written functions for it then its known

#

and if its known then youve modeled its state already

queen acorn
#

Is there guidance for the order of Classes and Functions in a python file? i.e. do classes all go at the top, and then all functions below?

narrow kettle
#

just using probably named primitives

magic python
#

right - and by that point the job is done, people aren't then going to pay to have someone refactor it into OOP when it won't apply to the next task

spark magnet
#

if you have different kinds of surveys, you might need differeent classes

narrow kettle
#

how do you currently pass survey data, what is an example method signature

magic python
#

I'm trying to think - because a lot of the time it's not passing around a survey as such but operating on subsets of the survey columns to start with, it might be an spss format and need metadata and stuff extracting, there are often differences and inconsistencies in the way that things have been coded (both values and names), it might be a case of joining open data into private data sources and so on

narrow kettle
#

whats an example

#

i have a felling you are already using classes

#

just via pandas

#

in which case you would be somewhat right in your assesemnt you dont need abstractions on top of that

magic python
#

hrm, well DataFrame would be a class then

narrow kettle
#

but you ARE using oop in that case

#

yes oc

magic python
#

right well, I kinda took that as a given, but yes I use others classes

#

But I was saying that I don't get the feeling writing oop would benefit my work that much. I do think I should look more at oop tho, as i'm clearly not going to spot patterns it can solve as i don't make good use of it

narrow kettle
#

only you know your workflow

#

but over abstracting on top of stuff is a very real consideration

magic python
#

Custom exceptions
i've actually heard this is something to be avoided

narrow kettle
#

i write my own

tawny shoal
#

@magic python Honestly, I can't help but like your way of thinking, just, it doesn't work that well in Python. It does work well in the data-oriented, traits-based world of Rust

#

it's late over here

magic python
#

i wish i was cool enough for rust

tawny shoal
#

you can be if you just try hard enough

#

steep learning curve at the beginning, but the compiler will be your strict teacher helping you get there

magic python
#

I've actually been thinking about using something "faster" for some stuff around crosstabulation of large data, maybe there's something in rust for that 🤔

tawny shoal
#

but yeah if you wanna keep going with Python, know that with Python, you'll be helping yourself by getting comfortable with classes and objects

#

Rust is certainly much faster than Python

magic python
#

yes, I have recently found "Fluent Python" and think it looks like a good resource for me

tawny shoal
#

for one Rust doesn't have a GIL so it can easily make use of all the processing power of your computer without being awkward in the form of multiprocessing

magic python
#

@tawny shoal is there a rust discord , i'm guessing there is - i keep finding games tho

#

oh i found one

tawny shoal
#

There's the official Rust language server that kinda focuses on Rust itself, and then there's the Rust community Discord which focuses more on learning and using Rust, which is probably what you want

magic python
#

i've got one with a crab or something as a picture

spark magnet
#

Rustacean

tawny shoal
#

Yup that's the one you probably want

narrow kettle
#

fwiw ive heard from multiple people that the rust discord is not a friendly place for beginners

vernal sapphire
#

Can anyone tell me, Where I can find the beginner course, I'm a Ntework student and I want to learn Python for Automation.

pseudo cradle
#

Omfg

#

I just learned that Python functions can return multiple variables like matlab

#

I don't have to deal with tuple unpacking nonsense

#

Wait, or does it? I'm so confused now