|
SurgicalOntologist posted:I guess I mean, whatever you're doing in the cell, its causing one request and another to not actually be the same despite appearing to have the same parameters. The actual request you're sending might be different, in some way, depending on the state of all that code you're running in that cell. It's the only way I can make sense of it. Aye! dem potent response
|
# ? Aug 20, 2022 01:54 |
|
|
# ? May 25, 2024 13:16 |
|
SurgicalOntologist posted:I guess I mean, whatever you're doing in the cell, its causing one request and another to not actually be the same despite appearing to have the same parameters. The actual request you're sending might be different, in some way, depending on the state of all that code you're running in that cell. It's the only way I can make sense of it. Python code:
Josh Lyman fucked around with this message at 15:35 on Aug 20, 2022 |
# ? Aug 20, 2022 15:29 |
|
I have a weird question. I inherited a codebase that's got an interesting decision in it and I'm trying to decide whether to start reverting it.Python code:
I'm not a CS major so I might be missing something, but my understanding of enums is that it's used to define a finite list of things in code, not in your data. It seems like if we're building the list dynamically we should just store it as a list/set of valid strings? My biggest problem with it is that because of this, you can create this enum in two ways: Python code:
Is this as dumb as I think it is? Falcon2001 fucked around with this message at 18:49 on Aug 20, 2022 |
# ? Aug 20, 2022 18:33 |
|
Falcon2001 posted:I have a weird question. I inherited a codebase that's got an interesting decision in it and I'm trying to decide whether to start reverting it. That's a reasonable way to define an enum, it's why the functional interface exists I think what you and some members of your team may not understand is that enum members are singletons. Area('xyz') is not creating a new Area instance, it's returning the member of Area that corresponds to value 'xyz'. Not only are those two variables equal, they're exactly the same object: Python code:
Python code:
Python code:
Python code:
Python code:
Python code:
QuarkJets fucked around with this message at 22:50 on Aug 20, 2022 |
# ? Aug 20, 2022 22:15 |
|
Falcon2001 posted:I have a weird question. I inherited a codebase that's got an interesting decision in it and I'm trying to decide whether to start reverting it. You are typically expected to define enum members by hand. As long as "get_all_valid_Areas_dict" is reliable, easy to understand, and never removes keys over time, it might not be a problem. It's especially defensible if the alternative is having to update multiple places when a new area is added, and if you need to add areas frequently. Your IDE (and probably mypy) will not be able to distinguish between valid and invalid enum members in the code, so that is a bummer. If you need a few valid operations for areas, you can add methods for them, which is more confortable if you use the class-based syntax (class Area(Enum): ...) instead of the functional syntax Area=Enum(...). Using the class-based syntax means abandoning the easy way to dynamically create the enum unfortunately. The pitch for enums is that you provide more clarity to your domain and code by being more specific. An area e.g. is not something that you can do arbitrary string operations on, and the result of those operations are not necessarily areas themselves. People reading your code will understand that it doesn't represent e.g. an unverified freetext field that a user can write anything they want in. It also a "proof" of validation - if your function only works with valid areas, then the fact that the caller was able to supply an Area member means that it's already validated. If you only use strings, then it's easy to send unvalidated areas to functions that expect validated ones, so every function that expect validated areas has to do an extra round of validation to help prevent mistakes. Dynamically typed languages like Python don't reap the benefits from wrapper types (in this case wrapping string values) as much as statically typed languages do. Unless you use type annotations you need a way to distinguish between parameters that are meant to follow the Area protocol (comparable with other Areas, has a "value" and "name" properties) and the string protocol (has contains(), startswith() etc. methods). It's easy to confuse what something is supposed to be without a naming convention like "blah_area" and "blah_area_str". Even so, the caller might send the wrong thing, especially if they don't use keyword arguments. You should only convert enums from and to strings when communicating with the user and with apis outside your control that only understand strings. In the rest of the code you should refer to hardcoded enum members like so "Area.XYZ". That way it's harder to confuse if you working with enums or their string counterparts. In short, if you are able to apply certain conventions then enums can greatly benefit your code.
|
# ? Aug 20, 2022 22:37 |
|
Thanks to both of you for context! I think the problem is that we don't ever refer to a single area in code; it's only used for validation of things like 'Ah, this input file has an area, let me see if it's a valid one'. The closest we get in being able to refer to a passed in variable as an Area instead of just str.Deffon posted:The pitch for enums is that you provide more clarity to your domain and code by being more specific. An area e.g. is not something that you can do arbitrary string operations on, and the result of those operations are not necessarily areas themselves. People reading your code will understand that it doesn't represent e.g. an unverified freetext field that a user can write anything they want in. This part makes me think it might be worth keeping this around, and just removing the case discrepancy between their names and values, so we always interact with them using the same casing, which would remove some of the weirdness from interacting with them. QuarkJets posted:That's a reasonable way to define an enum, it's why the functional interface exists Thanks! I didn't actually realize they were singletons, so that's handy to know. QuarkJets posted:Since an Enum is a class like any other, you can attach helpful methods to it that every member will then receive. This part, however, I'm reasonably confident this gets a lot messier if we're defining the enum dynamically. I looked into using this before using the class-style declaration and it looks like you have to do a bunch of subclassing. https://stackoverflow.com/questions/43096541/a-more-pythonic-way-to-define-an-enum-with-dynamic-members I think is what I found before. Overall, It sounds like using enums to basically be a clarity/validation point isn't a terrible idea (seeing a method that calls for an Area is clearer than a str), but the fundamental problem we're running into is that of the casing confusion - since you can interact with the enum using either a lower or uppercase, and the difference between () and [] is subtle enough to skip notice sometimes. I'll look into what we gain by standardizing on one case, and then doing .upper() or .lower() whenever we have to write out/etc and see if that helps.
|
# ? Aug 21, 2022 00:54 |
|
Your internal code should use Area members directly, e.g. Area.XYZ. Your external interfaces should convert input strings to Areas.
|
# ? Aug 21, 2022 03:26 |
|
QuarkJets posted:Your internal code should use Area members directly, e.g. Area.XYZ. Your external interfaces should convert input strings to Areas. Ninja edit: I got most of the way through writing a big explanation of my service but I think I just am agreeing with you. I think there's just a bunch of old code lying around that does some odd things, so I'm trying to prioritize what I can bother rewriting...especially in a codebase with like 30% test coverage, which makes refactors a little scary. (I'm working on that last part, but thanks to a bunch of module variables and singleton patterns it's not an easy thing to fix.)
|
# ? Aug 21, 2022 04:22 |
Falcon2001 posted:...especially in a codebase with like 30% test coverage, which makes refactors a little scary. Out of curiosity, what’s usually considered good coverage? We’re at 88% on our most recent release of a certain library and we’re trying to decide if we should formally set a minimum and, if so, what it should be. Assuming 100% is the dream, not the expectation.
|
|
# ? Aug 21, 2022 06:35 |
|
Goodhart's law applies here - the moment you make code coverage an actual target instead of just something that you look at to figure out what part of the codebase might need more testing, you're going to wind up with a whole bunch of pointless change-detector tests that exercise all the code paths without actually testing the behaviour you're interested in.
|
# ? Aug 21, 2022 08:17 |
|
Jabor posted:Goodhart's law applies here - the moment you make code coverage an actual target instead of just something that you look at to figure out what part of the codebase might need more testing, you're going to wind up with a whole bunch of pointless change-detector tests that exercise all the code paths without actually testing the behaviour you're interested in. Even so, it's important to set a threshold for low coverage because 1) There will also be developers who use the notification of low coverage to develop good new tests 2) Smoke testing is better than no testing, and for some lines it's actually all that's needed In a world where most codebases have no testing, the appropriate coverage is a decision to be agreed upon between the developers and the managers. If you're a person who can influence this, get it as high as possible; 80% would be a reasonable threshold. Setting it too high risks what Jabor is describing QuarkJets fucked around with this message at 18:18 on Aug 21, 2022 |
# ? Aug 21, 2022 18:14 |
Yeah, we got 88% without worrying about the number and just targeting good tests and discovered-in-practice edge cases and such for regression, and my gut tells me that’s a pretty good number to have hit with that approach. Of course it would also require, in the event of a low number, looking at WHAT code isn’t getting covered, and whether we actually care. Just curious what other people might use as a “sensible” jumping off point. I guess I could look at some other Big Kid libraries and see how they’re doing. The primary goal is to have very high confidence in regression testing. New feature testing second to that. Absolutely agree that just saying “95% no matter what” or similar is potentially very counterproductive. And maybe it’s best to just not set an actual number and instead focus almost exclusively on occasionally examining what, specifically, is being missed.
|
|
# ? Aug 21, 2022 18:26 |
|
Josh Lyman posted:This kinda makes sense to me. Stupid question, how do I run requests on a local server? The API call work like I have no idea what you mean by this localserver thing and Google isn't helping. I assumed from previous posts that you were using requests. If that's not the case, my specific advice is less relevant but probably the answer lies in this direction. Is it really running on localhost? Do you control the server? Where did the code for localserver.localpackage come from? This makes it more complicated because the state that's affecting the requests might be coming from your code but from the code you're importing. In which case there might not be much you can do about it. Whether its possible to use requests instead depends on how much info you can get about the actual HTTP API and the complexity of the code (you can see the code in Jupyterlab by typing the function/class/module with ?? after). Probably in the code they are using requests but not necessarily. I mean, with the info we've seen, maybe it's not even an HTTP API but a simulation of one, in which case all bets are off.
|
# ? Aug 21, 2022 19:08 |
|
Getting back into python after a few years, so I'm rusty. Doing a user input validation and its throwing up error, haven't run it yet though.code:
|
# ? Aug 22, 2022 12:09 |
|
Mycroft Holmes posted:Getting back into python after a few years, so I'm rusty. Doing a user input validation and its throwing up error, haven't run it yet though. input() will always return a string, you've gotta try and convert it yourself, like code:
|
# ? Aug 22, 2022 13:01 |
|
Mycroft Holmes posted:Getting back into python after a few years, so I'm rusty. Doing a user input validation and its throwing up error, haven't run it yet though. What gets returned if there’s a single invalid input? What happens if there’s an invalid input twice in a row? Without seeing more context, it’s hard to know what the right answers to these are (or whether they’re already answered somewhere outside that function). But probably you want a while loop.
|
# ? Aug 22, 2022 13:07 |
|
so, something like this is better?code:
|
# ? Aug 22, 2022 13:15 |
|
Mycroft Holmes posted:so, something like this is better? well, take a pass at that and just tell yourself what it does for two iterations in the loop - or hell, just run it. one thing that might not be immediately obvious is that it should be while not isinstance(labs, whatever) not labs is not whatever
|
# ? Aug 22, 2022 13:32 |
|
Mycroft Holmes posted:so, something like this is better? To expand on Phobeste's comment, the reason to not use "is" to check types is because it checks for identity and not class (i.e., type) membership. So your conditional is literally asking if labs is the same thing as the type int, not if it is of the type int. You want the latter, which is what isinstance does. Why is self.labs a string ("A"), when the lab method is getting a float? If you're converting a float to a string letter grade, that probably ought to be handled inside the lab method. Do you want the lab method return a value, or to set the value of an attribute? If you want the latter (which seems more likely), you'll need to use self.labs inside the lab method. If you want the former for some reason, you'll need to make sure to have a return statement somewhere inside the method. (Here's a related question: why is lab a method of the Main class and not a standalone function? Currently it doesn't create or modify any attributes of the Main class.) Less particular to your situation, but some of these questions would be easier to help with if you used a docstring for the lab method, so it was clearer what exactly it should do. In general, every function/method should have a docstring (though I'd usually consider it understandable to leave it out when asking questions somewhere like here).
|
# ? Aug 22, 2022 13:56 |
|
ok, getting a bunch of different errors. It eternally loops if a numerical value is put in. it throws an error if a letter is put in, despite the valueerror bit. code:
|
# ? Aug 22, 2022 14:25 |
|
Phone posting but The while loop checks labs but what you're converting to a float is grade1. So labs will only ever be a string as that's the input var And you're trying to convert the input to a float outside the try except so it doesn't have error handling on invalid inputs, that's where the error is coming from
|
# ? Aug 22, 2022 14:40 |
|
The line where you're trying to cast the input as a float outside of the try block is what's throwing the value error. Basically, you don't need the first instance of this line in the lab function code:
As for the infinite looping, your while function should only need the isinstance function since that will return a boolean and the "is" comparison isn't needed. Since the successfully casted float and the result of the isinstance function are different objects, the while loop condition will always resolve as true hence the infinite looping and is prevalent in all your grade functions. The function should look like this: code:
EDIT 2: Infinite loops may not be ideal but the following could work since a successful cast to float should mean the input was a number which the function will return and break out of the loop. code:
Edward IV fucked around with this message at 15:23 on Aug 22, 2022 |
# ? Aug 22, 2022 14:47 |
|
SurgicalOntologist posted:I have no idea what you mean by this localserver thing and Google isn't helping. I assumed from previous posts that you were using requests. If that's not the case, my specific advice is less relevant but probably the answer lies in this direction. Is it really running on localhost? Do you control the server? Where did the code for localserver.localpackage come from? As an unrelated question, np.argmin() isn't behaving the way I'm expecting. Say I have an array [200,500,1000]. np.argmin(myArray>=100) should return 1 right? >=500 should return 2, not sure what >=5000 should return. What am I missing? Isn't it the minimum index (starting at 1) that satisfies the inequality? edit: I think I have it figured out. np.argmin() returns the index of the lowest value, and the inequality return an array of True/False, so it's actually checking for the minimum index (starting at 0) that's False? Josh Lyman fucked around with this message at 18:03 on Aug 23, 2022 |
# ? Aug 23, 2022 17:34 |
|
that's correct. I think you're looking for np.where(myArray>=100)[0]
|
# ? Aug 23, 2022 18:16 |
|
Ok, I need to have a program exit if the user presses enter without inputting data. Is there a way to detect a blank field?
|
# ? Aug 24, 2022 13:23 |
|
Mycroft Holmes posted:Ok, I need to have a program exit if the user presses enter without inputting data. Is there a way to detect a blank field? code:
|
# ? Aug 24, 2022 13:54 |
|
Mycroft Holmes posted:Ok, I need to have a program exit if the user presses enter without inputting data. Is there a way to detect a blank field? Sure, and here's a path to figuring something like that out: code:
|
# ? Aug 24, 2022 13:56 |
|
can you put an if loop inside a try/except?
|
# ? Aug 24, 2022 14:25 |
|
Mycroft Holmes posted:can you put an if loop inside a try/except? You can put conditionals (if) and loops (for, while) inside try/except blocks.
|
# ? Aug 24, 2022 14:41 |
|
On a related note, I have a fairly long script with a number of generic try/except blocks inside of loops, many of which are except: pass. In JupyterLab, when I click the stop button, it continues onto the next loop iteration. Shouldn't the stop button actually stop the notebook? Do I need to specify the type of error in my try/except blocks? Unfortunately, one of them is meant to catch an error when I call an API and it returns an empty list, and when I tried to put the name of that error in the except, it wasn’t recognized. Should I just use except Exception: in that case?
Josh Lyman fucked around with this message at 07:51 on Aug 25, 2022 |
# ? Aug 25, 2022 07:20 |
|
Josh Lyman posted:On a related note, I have a fairly long script with a number of generic try/except blocks inside of loops, many of which are except: pass. In JupyterLab, when I click the stop button, it continues onto the next loop iteration. Shouldn't the stop button actually stop the notebook? Do I need to specify the type of error in my try/except blocks? Unfortunately, one of them is meant to catch an error when I call an API and it returns an empty list, and when I tried to put the name of that error in the except, it wasn’t recognized. Should I just use except Exception: in that case? You should avoid broad Exception catching, usually. Can you eliminate that try/except block by just checking the list length?
|
# ? Aug 25, 2022 09:15 |
|
QuarkJets posted:You should avoid broad Exception catching, usually. At the very least, this has gotten me to specify all my except statements (primarily IndexError).
|
# ? Aug 25, 2022 09:31 |
|
Does anyone use Folium? I am trying to build a map with multiple layers:Python code:
Big Dick Cheney fucked around with this message at 21:08 on Aug 26, 2022 |
# ? Aug 26, 2022 21:01 |
|
no idea what Folium is, but I'd guess you're running into a classic lambda variable binding gotcha:Python code:
one kludge is to bind the variable to an argument default value: Python code:
of course there's other, much more readable solutions, like: Python code:
|
# ? Aug 26, 2022 22:27 |
|
Is there a simpler way to handle this interaction? I'm finding I'm doing this a reasonable amount.Python code:
|
# ? Aug 31, 2022 19:04 |
Python code:
|
|
# ? Aug 31, 2022 19:06 |
|
Falcon2001 posted:Is there a simpler way to handle this interaction? I'm finding I'm doing this a reasonable amount. You can use the built in getattr, similar syntax to dict.get("key", default). Python code:
Armitag3 fucked around with this message at 19:14 on Aug 31, 2022 |
# ? Aug 31, 2022 19:09 |
|
Data Graham posted:
I didn't realize I could use Or like that, thanks! Armitag3 posted:You can use the built in getattr, similar syntax to dict.get("key", default). Yeah, for purposes of this, I mean nullable to be None, not nonexistent. Falsiness is the check I'm trying for, to be clearer. Falcon2001 fucked around with this message at 19:47 on Aug 31, 2022 |
# ? Aug 31, 2022 19:38 |
|
If you find that you end up sprinklingPython code:
|
# ? Aug 31, 2022 19:58 |
|
|
# ? May 25, 2024 13:16 |
|
12 rats tied together posted:If you find that you end up sprinkling Yeah, I know this is moving into antipattern territory. This portion is entirely internal, and none of these objects exit to my dependencies. In fact, a bit part of what I'm doing is trying to generate safe, fully generated objects to output by catching any places where things are null'd out during generation of those objects. I think the proper way to do this would be with more exceptions and error handling instead of 'Optional[outputObject]', but this isn't something I'm shoving outside of this module at least. Edit: To expand on this, I guess I can just lay out what I'm doing and if I'm being an idiot, tell me. Python code:
Falcon2001 fucked around with this message at 20:35 on Aug 31, 2022 |
# ? Aug 31, 2022 20:09 |