|
Zugzwang posted:Yeah I really wish Python had something like "type hinting is purely optional, but they will be enforced if you specify them." As opposed to "the Python interpreter does not give the slightest gently caress about type hints." loving VB6 had a solution for this. "Option Explicit On" "Option Strict On" It would be a highly good thing to have the option to just stick something like that at the top of a python file, so that it explodes at import if it fails a sanity linting. Also re "poisonwomb" mentioned earlier, I assume thats a reference to "your poison womb is making heaven crowded". Because good god does this website have some shady loving history at points (For those blessed not to remember that, its one of our more shameful moments. Keep in mind, at that point, the usual result of getting your terrible website linked off here was pretty much identical to what happens if 4chan does it now. But in this case it was women who where having somewhat traumatized responses to stillbirth. Yeah, not so funny now we're all 40somethings....)
|
# ? Sep 14, 2023 05:31 |
|
|
# ? Jun 6, 2024 06:17 |
|
Entire script: https://github.com/jmruss10/netParser/blob/main/netParser.py current error: https://github.com/jmruss10/netParser/blob/main/errors.txt So I got to playing more yesterday, it seems that setting args as global changes it globally (at least below/after main). Now I'm getting a new error, but this is probably more me not understanding the argparse.
|
# ? Sep 14, 2023 14:54 |
|
duck monster posted:loving VB6 had a solution for this. That's basically also how flow and whatnot worked in Javascript for the longest time (and may still work that way, but IDK why you would use Flow now when Typescript exists)
|
# ? Sep 14, 2023 16:37 |
|
Gothmog1065 posted:Entire script: https://github.com/jmruss10/netParser/blob/main/netParser.py The error is saying that args is not defined at this line: https://github.com/jmruss10/netParser/blob/main/netParser.py#L113 Python code:
Python code:
Looking at all of the uses of dataDict as an example: - add_to_dict() should accept the dictionary as an input - create_dict() doesn't really need to accept any inputs, it can just create an empty dictionary and return it instead of modifying the globally-scoped one. Python code:
|
# ? Sep 14, 2023 17:32 |
|
QuarkJets posted:The error is saying that args is not defined at this line: Thank you for the input. My only frustration I guess is having to pass the args variable around since I'm going to be needing it as I expand the scope of the script and add more arguments. However, the dictionary can definitely be de globalized. I know there's going to be a lot of cleanup to be done as I work through this and add more functionality to it. Most of my variable scoping came from bash/kornshell so it's going to take a bit to get rid of some of those habits.
|
# ? Sep 14, 2023 21:55 |
|
Gothmog1065 posted:Thank you for the input. My only frustration I guess is having to pass the args variable around since I'm going to be needing it as I expand the scope of the script and add more arguments. However, the dictionary can definitely be de globalized. I know there's going to be a lot of cleanup to be done as I work through this and add more functionality to it. FWIW scope is going to be a big part of dev so it's worth thinking about it. It's very easy at first to take an approach of 'I'll throw everything around everywhere' but it's probably worth considering that it makes testing and reusing code a lot more complicated, and unit tests are very helpful as your program gets larger. For example, I wouldn't pass around your args object, I would extract everything you need out of it into independent variables, and then pass those individual elements into functions where required - you might have a function that needs to know what sort option you're using, but might not care about filename/etc. Edit: One big reason to do the above is that the args object produced by argparser doesn't have any type hinting/etc, so once you pass that down a few layers you have to constantly go back to your argparser to be like 'wait what is the sort attribute called? And what type is it?'. Extracting sort into a variable and then passing it explicitly (with type hinting) makes this a ton easier on you in the future as your IDE will automatically know what type it is (as well as the variable.) Falcon2001 fucked around with this message at 03:47 on Sep 15, 2023 |
# ? Sep 15, 2023 03:40 |
|
Gothmog1065 posted:Thank you for the input. My only frustration I guess is having to pass the args variable around since I'm going to be needing it as I expand the scope of the script and add more arguments. However, the dictionary can definitely be de globalized. I know there's going to be a lot of cleanup to be done as I work through this and add more functionality to it. I want to discourage you from using globalization, it's not the best way to handle CLI arguments. You should have a function whose sole purpose is to parse an object from argparse into whatever information your code needs. Defining args as a global object means defining argument-parsing behavior in multiple places, and that can lead to trouble later. If you define your own dataclass that holds the parameters that can be set via the CLI, then you can have a factory function or class method that returns an instance of that dataclass after parsing the results from argparse. If you wind up have conflicting flags then the logic for handling that gets to exist in just 1 place, and that way you can also keep adding as much CLI scope as you want while knowing that all of your CLI parsing is in a single place
|
# ? Sep 15, 2023 07:04 |
|
So wrapping my smoothbrain around this, hopefully I'm getting what you're saying. I'd have something more akin to the following (I'm typing this on the fly, just trying to get a more generalized sense of what I'm doing): Python code:
|
# ? Sep 15, 2023 15:25 |
|
Gothmog1065 posted:So wrapping my smoothbrain around this, hopefully I'm getting what you're saying. I'd have something more akin to the following (I'm typing this on the fly, just trying to get a more generalized sense of what I'm doing): You'd want to create a factory function that instantiates the dataclass. So three things are defined 1) The dataclass, which just holds the parameters that are relevant to your software 2) main() function, which creates an args object with argparse 3) A function that connects 1 and 2: given args, create an instance of the dataclass and return it Python code:
Dataclasses are not immutable unless you set frozen=True in the decorator
|
# ? Sep 15, 2023 16:35 |
|
Edit: ^^^ Dataclasses aren't immutable unless you do @dataclass(frozen=True). You're still relying on this global variable in create_dict which you don't want, and your Parser (I'd probably call it COnfig or something to be more clear that it doesn't do any parsing itself) is tightly coupled to CLI args. Maybe today you only take CLI args to configure this, but someday it may come from env vars, or a config file, or a network call, etc. What you're aiming for is to separate "the config" and "where the config comes from" in most of the code, so it doesn't have to care. Python code:
Personally, I would avoid passing the entire config object to data_display since all it needs out of it is the sort config. Passing around a big bundle of state like that can make it hard to reason about what exactly a function relies on and has led me to some hair-pulling debugging sessions in the past. Or put another way, if a year from now you need to make some changes or fixes to data_display (or call it from some other part of the codebase), which of these function signatures tells you the most about how it works? Python code:
WHERE MY HAT IS AT fucked around with this message at 16:45 on Sep 15, 2023 |
# ? Sep 15, 2023 16:42 |
|
This might be a dumb question, but what are the benefits of a data class over a regular class?
|
# ? Sep 17, 2023 00:30 |
|
oatmealraisin posted:This might be a dumb question, but what are the benefits of a data class over a regular class? Free string representation, free to_dict implementation, lots of that sort of thing. If what I'm doing at all looks like "maybe just holding data" I'll use it
|
# ? Sep 17, 2023 00:43 |
|
oatmealraisin posted:This might be a dumb question, but what are the benefits of a data class over a regular class? Convenience. If your constructor is just creating a bunch of attributes, then using the dataclass decorator lets you avoid writing a __init__ method and you'll only have to write each attribute name once instead of two or three times. With the frozen option you can emulate immutability without having to make up your own mechanism for that, which can be handy! And it gives you the other nice things that Chin Strap mentioned; a nice __repr__ method is very good and I often neglect to write one, so it's great when I can get one for free in a way that also lets me write less code.
|
# ? Sep 17, 2023 01:22 |
|
Those free methods and lack of redundant init are enticing, thanks!
|
# ? Sep 17, 2023 04:39 |
|
So frustrated now, but lead tech doesn't want to "introduce another language", so going to have to rewrite this in kornshell (because heaven forbid we use something slightly more updated), if not, gonna have to write it in C or C++ most likely. so yeah..
|
# ? Sep 19, 2023 15:09 |
|
Why write something in Python if C++ will do the job??
|
# ? Sep 19, 2023 16:25 |
|
Gothmog1065 posted:So frustrated now, but lead tech doesn't want to "introduce another language", so going to have to rewrite this in kornshell (because heaven forbid we use something slightly more updated), if not, gonna have to write it in C or C++ most likely. so yeah.. Wtf kornshell? That's a terrible decision, extra few months of training time for every new hire.. also kornshell
|
# ? Sep 19, 2023 17:08 |
|
I think this is the first time I've seen the word "kornshell" in maybe 15 or 20 years.
|
# ? Sep 19, 2023 17:28 |
|
I’ve always wondered what goes through the mind of someone who decides to build their operations around some obscure fork that hasn’t seen a release in a decade
|
# ? Sep 19, 2023 17:42 |
|
I can only assume they're just too close to retirement to want to learn something new, even if it's demonstrably better. Not that people earlier in their careers can't be stubborn or cling to garbage, either. Just IME that's been where I've seen it.
|
# ? Sep 19, 2023 17:51 |
|
Gothmog1065 posted:So frustrated now, but lead tech doesn't want to "introduce another language", so going to have to rewrite this in kornshell (because heaven forbid we use something slightly more updated), if not, gonna have to write it in C or C++ most likely. so yeah.. I used to think that I Got the Life with kornshell, but then after I Did My Time I felt like it was all Coming Undone.
|
# ? Sep 19, 2023 18:13 |
|
WHERE MY HAT IS AT posted:I can only assume they're just too close to retirement to want to learn something new, even if it's demonstrably better. Not that people earlier in their careers can't be stubborn or cling to garbage, either. Just IME that's been where I've seen it. Pretty much both of these. The guy is smart, but really stuck in his ways, and most people pretty much just go "Well, this is his way so might as well deal with it". He's been here for 25 years or something so he also has a lot of pull, and not worth fighting over it. Just do it like he wants (if I can) and move on.
|
# ? Sep 19, 2023 18:58 |
|
How should I write this to convince flake8 to calm down:Python code:
That snippet behaves like I want to, but our CI spits a warning at the @router line. The warning is: code:
rowkey bilbao fucked around with this message at 10:05 on Sep 21, 2023 |
# ? Sep 21, 2023 10:03 |
|
https://stackoverflow.com/questions/62919271/how-do-i-define-a-typing-union-dynamically Use a tuple instead of a list?
|
# ? Sep 21, 2023 10:22 |
|
Thank you Chin Strap Additionally, where can I read about types in a way that helps me understand wtf it means when I see TypeVar or T or funny brackets ? This is a huge blind side of mine and this is going to bite me in the rear end some day.
|
# ? Sep 21, 2023 18:08 |
|
rowkey bilbao posted:Thank you Chin Strap https://peps.python.org/pep-0484/ it's a little dry, but the PEP is a pretty good place to start if you're talking about Python type hints specifically. If you're just talking about the notation style, I honestly dunno.
|
# ? Sep 21, 2023 18:48 |
|
rowkey bilbao posted:How should I write this to convince flake8 to calm down: This is a bit of a smell IMO. Much better would be to setup the classes in `USERS_AND_ANIMALS` such that they have the same parent class. If not possible through inheritance, you can use a Protocol, which is essentially a way to define a class based on its behavior (e.g. any class with methods .feed() and .eat() is an Animal) without needing to touch the class implementations. I'm not super knowledgeable on pydantic if there's any trick there but probably a superclass is the easiest solution here if you have control over those implementations. Edit: I think Unions and the word "or" in names is a smell to be clear. Certainly a big Union like this one, and there's a better way to type it for sure. But I would also add that create_user_or_animal is also a bit smelly. I don't know your domain and maybe there's a good reason, but I think most likely your code would be more maintainable with different functions/endpoints for creating animals and creating users. rowkey bilbao posted:Additionally, where can I read about types in a way that helps me understand wtf it means when I see TypeVar or T or funny brackets ? Those are generics, mypy docs are pretty good on that: https://mypy.readthedocs.io/en/stable/generics.html Actually mypy docs are good in general, the section on Protocol is probably better than the one I linked above. SurgicalOntologist fucked around with this message at 18:51 on Sep 24, 2023 |
# ? Sep 24, 2023 18:48 |
|
I have two classes Plotter and Layer. A Plotter consists of an array of layers. Each layer is an array of instructions. code:
code:
If I want to update a layer, I currently do the following: code:
And one more question. I've got a directory structure code:
code:
So I feel like I'm missing something here. huhu fucked around with this message at 18:53 on Sep 25, 2023 |
# ? Sep 25, 2023 18:11 |
|
What is the benefit of adding those functions versus making the class' layers property public and just doing:Python code:
|
# ? Sep 25, 2023 18:59 |
|
huhu posted:I have two classes Plotter and Layer. A Plotter consists of an array of layers. Each layer is an array of instructions. You've already tightly coupled the two classes together pretty strongly, so Macichne Leainig's response is probably a good starting point. Although, using __getitem__ to give you dictionary style access is better than update_layer (not simply because update_layer is misleadingly named; a function called update should...well update something, not return that something. At the very least you should rename it to get_layer). This would simplify it slightly further and looks a lot cleaner than the original example: Python code:
The downside is that this would be bad if you wanted to use that get_item for something else, or you had a bunch of various options like layers, in which case then yeah, just expose the layer. FWIW: Remember that "private" doesn't mean anything real in Python, so I generally only use the _ prefix for stuff that wouldn't ever be useful to another piece of code, like decomposed methods or things like that, or client objects you want to at least ward people away from. huhu posted:And one more question. I've got a directory structure I'll be honest, Python imports are kind of a murky soup to me, despite working with it a bunch. I would also be interested if anyone had a video/blog post or something that explained it without getting into the deep minutiae of import logic, simply the 'if you run from X you pull in Y' level stuff.
|
# ? Sep 25, 2023 19:21 |
|
I added this gross code:code:
I swear, between installing a virtual environment and getting imports, I end up just abandoning Python if my code grows out of a single file with basic imports.
|
# ? Sep 25, 2023 19:42 |
|
That I think is because Python doesn't like you importing from parent-level directories, which judging from your described file structure seems like it could be the case. I think you want something more like: code:
code:
|
# ? Sep 25, 2023 19:49 |
|
huhu posted:I want to import project into demos. However, when I cd into the demos directory and try and run any variation of import statements, I get various errors. I've Googled a bunch and I cannot figure out what's wrong with my import. Or is there a better way to make a demos directory for a package I'm building? One of the stack overflow answers says You'll probably want to follow a guide like this. This will allow you to install the project path permanently to the python path. In short: 1. Create a 'src' subfolder in the root folder and move the project folder there 2. Create a pyproject.toml file in the root folder and add the appropriate contents 3. In the root folder, run 'pip install --editable .' Then 'python demos/demo1.py' should work as expected. (The --editable part means you don't have to reinstall everything everytime you modify the code)
|
# ? Sep 25, 2023 19:49 |
|
Zoracle Zed posted:You'll probably want to follow a guide like this. This will allow you to install the project path permanently to the python path. In short: Ahhhhh, this was what I was looking for. Thank you!
|
# ? Sep 25, 2023 19:54 |
|
huhu posted:I have two classes Plotter and Layer. A Plotter consists of an array of layers. Each layer is an array of instructions. A pattern I like (could be bad, actually, and I'm interested in other opinions on it) is to have add_line return itself, so if you want to add multiple lines you could do: code:
Depending on how the code grows, this can make life better or worse.
|
# ? Sep 25, 2023 22:31 |
|
I don't think it's a bad idea or anything. If anything it saves you from having to write the same boilerplate to access that class member over and over again. Might be confusing initially if someone hasn't encountered the pattern, but I don't think it's like, an antipattern or anything like that.
|
# ? Sep 25, 2023 22:37 |
|
It's called fluent interface design, and it's not a bad idea at all, especially applied to situations where the flow can read logically from one operation to the next.Python code:
|
# ? Sep 25, 2023 23:36 |
|
Armitag3 posted:It's called fluent interface design, and it's not a bad idea at all, especially applied to situations where the flow can read logically from one operation to the next. I quite liked this in LINQ in C#, although I do agree it's not used much in Python. I don't think that's an antipattern or anything though, just convention.
|
# ? Sep 26, 2023 00:12 |
|
Pretty common pattern for ORMs where query methods return objects that can themselves be further queried, Django's works that way.
|
# ? Sep 26, 2023 00:16 |
|
|
# ? Jun 6, 2024 06:17 |
|
Used all the time in Pandas too
|
# ? Sep 26, 2023 00:21 |