|
piratepilates posted:Sourcesafe has got to be one of the biggest coding horrors, no branching support which makes it real fun when two people have to work on the same thing at once, or when someone commits changes to VSS but the changes aren't approve to make it to production and whoever works on that thing next doesn't check the status before grabbing the latest version. You can branch in SourceSafe. I've never done it because it was very painful but it can be done. Also, you are criticizing software written over 20 years ago. Microsoft bought SourceSafe in 1994 and it was already a commercial product for a while (I couldn't find how long). It served a purpose back when most source control was still ZIP files or <project>_V## directories backed up on floppy disks. Yes in 2013 using SourceSafe is a Coding Horror. Funny enough we still have two VB6 projects in SourceSafe that we haven't bothered to move over to TFS. We hardly touch them so not a huge deal.
|
# ? Jan 16, 2014 02:51 |
|
|
# ? May 27, 2024 17:45 |
|
Suspicious Dish posted:I see this a lot. "An error came up, so we're just going to ignore it". I have to actually remove a lot of try/catch statements that should never happen in real life, but are only there to catch somebody else's bugs. This reminds me of a thing that I get really annoyed at in Python development; there's this idea that you can just use try/except blocks to get some behavior that you want when that behavior should be obtained in another way. Maybe it would be okay if you were writing your own special snowflake Exception and catching only it and nothing else, but it's still loving stupid to intentionally throw exceptions just to mimic better code I saw someone on stackoverflow suggesting that this: Python code:
Python code:
Python code:
|
# ? Jan 16, 2014 06:44 |
|
Catching all exceptions is wrong, butcode:
|
# ? Jan 16, 2014 07:54 |
|
evensevenone posted:Catching all exceptions is wrong, but Aren't exceptions much slower than just checking iirc?
|
# ? Jan 16, 2014 08:38 |
|
I don't think exceptions are particularly expensive. Certainly no style guide recommend against them. And if the key exists, it's actually going to be faster than the second example.
|
# ? Jan 16, 2014 09:21 |
|
dict.get exactly and explicitly matches the desired semantics of the operation. Anything else is less immediately obvious.
|
# ? Jan 16, 2014 09:24 |
|
Yeah, even if there is no performance impact, I think it's hard to defend using exceptions for anything other than exceptional circumstances. If you expect the key to sometimes not be present in the dictionary as part of normal operation, you should check for it, not use an exception (without an extremely compelling reason).
|
# ? Jan 16, 2014 10:02 |
|
evensevenone posted:I don't think exceptions are particularly expensive. Certainly no style guide recommend against them. E: sorry. Missed the context of "Python". Exceptions might not be much slower on python, but it is emphatically the wrong solution for performance in general to rely on exceptions for normal flow control. Doctor w-rw-rw- fucked around with this message at 10:25 on Jan 16, 2014 |
# ? Jan 16, 2014 10:23 |
|
Python's core exceptions are about two-fold slower than and equivalent if loop in the worst case (source). I've heard scuttlebutt that custom exceptions are slower, but couldn't find anything to quantify it. Best practice is to avoid using exceptions where the exception case is common. However, for rare or merely uncommon exceptions, try/except is considered more robust, and better semantics. It's less "You Should Always Ask For Forgiveness," and more "You Should Always Consider Asking For Forgiveness." Haystack fucked around with this message at 16:38 on Jan 16, 2014 |
# ? Jan 16, 2014 14:56 |
|
Huh. I just wrote almost the exact same thing last night and thought I was being a good Python programmer for asking for forgiveness, not permission, or whatever. I didn't use get because in my case the default value was complicated to figure out: Python code:
|
# ? Jan 16, 2014 15:23 |
Sounds like you should have used a defaultdict there.
|
|
# ? Jan 16, 2014 16:55 |
|
"Asking forgiveness instead of permission" is among the most terrible of all terrible nonsense "pythonic" rules. Exceptions are dynamic non-local gotos that obscure control-flow and spread the logic of your program across arbitrarily-distant functions. They should be used for exceptional circumstances and absolutely not as a matter of course. If you're forced to use exceptions for control-flow it's because Python is a bad language
|
# ? Jan 16, 2014 17:03 |
|
On the next exciting episode of programmersbeingdicks dot tumblr dot calm, "Python's 'Ask Forgiveness Instead of Permission' Policy and the perpetuation of Rape Culture among programmers"
|
# ? Jan 16, 2014 17:07 |
|
seiken posted:Exceptions are dynamic non-local gotos that obscure control-flow and spread the logic of your program across arbitrarily-distant functions. Perhaps even more stupid about this specific example is the fact that if an exception is encountered you go to literally the next line. Regardless of how stupid exception handling is in this case, if you're trying only one line of code that isn't even an explicit method, there's probably a better way to do it (like dict.get.)
|
# ? Jan 16, 2014 17:09 |
|
Well it's not like you're forced to use exceptions as a control flow mechanism in any common language facilities in Python... http://docs.python.org/2/library/exceptions.html#exceptions.StopIteration Oh.
|
# ? Jan 16, 2014 17:14 |
|
I've barely touched Python. Is that as much of a horror as it appears to be? Does Python really have that much of a different concept of exceptions than all the other languages I have used?
|
# ? Jan 16, 2014 17:19 |
|
nielsm posted:Sounds like you should have used a defaultdict there. I forgot to mention that when a new key is encountered, I reassign all the other keys as well. I guess I'll explain since there's a reasonable chance I'm the horror and I wouldn't mind learning. I'm interfacing with a bunch of wireless sensors that are numbered but otherwise identical. If the user writes an application using two sensors, they probably need to know which is which. And yet, they might use sensor 1 and sensor 2, but then the batteries run out and they switch to 3 and 4. And maybe the next day sensor 2 is broken and they use 1 and 3. I can't require the user to always use, e.g., sensors 1 and 2. I don't want the user to have to input the sensor numbers every time they start a new session because that will inevitably cause fuckups. But the sensors still need to be identifiable within each session. My solution is that every time data comes in from a new sensor, I resort the existing sensor numbers and "mydict" in the snippet above is a mapping from internal sensor numbers to external sensor numbers. For the user, their application can refer to sensor 0 and sensor 1 and all they have to worry about when using their application is the relative ordering of the actual sensor numbers. Data comes in at 200 Hz so getting the sensor numbers wrong for the first 1/200 s is not a big deal, and after that speed is important. SurgicalOntologist fucked around with this message at 17:35 on Jan 16, 2014 |
# ? Jan 16, 2014 17:32 |
So have one thing that generates a sensor_logical_physical_map from scratch, a flag that specifies that the current map is invalid for some reason, something that sets that flag as appropriate (startup, error condition detected), and check that flag once a cycle? Basically the straight forward way you'd have written it in C 30 years ago.
|
|
# ? Jan 16, 2014 17:45 |
|
..btt posted:I've barely touched Python. Is that as much of a horror as it appears to be? No quote:Does Python really have that much of a different concept of exceptions than all the other languages I have used? Yes(-ish), but that doesn't necessarily make it a horror. They should probably have a different name in Python so people don't freak out when they're used the way they are because they're used for control flow and that's Very Bad in every other language I know of that supports the concept. It freaked me out at first, but it works fine when not abused as shown above (not calling out SugicalOntologist - the stuff further up), so eh. In my fantasy Python 4M, they're called signals or interrupts - something like that.
|
# ? Jan 16, 2014 17:49 |
|
nielsm posted:So have one thing that generates a sensor_logical_physical_map from scratch, a flag that specifies that the current map is invalid for some reason, something that sets that flag as appropriate (startup, error condition detected), and check that flag once a cycle? Basically the straight forward way you'd have written it in C 30 years ago. So... pretty much the same except the Except clause sets a flag instead, and the map is fixed elsewhere? There's only one applicable condition, when I first encounter a sensor that hasn't been mapped. On startup I haven't yet encountered any sensors (each cycle I only get data from one sensor. With more sensors the cycles come faster).
|
# ? Jan 16, 2014 17:54 |
|
Munkeymon posted:No There's not really any reason it would be less of a horror in Python. If you don't abuse it and only catch the exception one level up as above of course that's not too bad, but when you start depending on control-flow like that it's inevitable the catches will start moving further and further away from the raises and the program will become harder to reason about locally. vvv that's ridiculous, naming has nothing to do with it. Control flow exceptions are poo poo no matter what the language is or what they're called seiken fucked around with this message at 18:52 on Jan 16, 2014 |
# ? Jan 16, 2014 18:03 |
|
seiken posted:There's not really any reason it would be less of a horror in Python. If you don't abuse it and only catch the exception one level up as above of course that's not too bad, but when you start depending on control-flow like that it's inevitable the catches will start moving further and further away from the raises and the program will become harder to reason about locally. Just having exceptions at all allows that to happen, though. I've seen C# that used exceptions to transition between UI states using exceptions like DownloadSuccessfulException, for example. Python is structured to lean on them more heavily than most languages, but that's intentional, so it's helpful to think of them as a misnamed feature instead of a misapplied tool. Basically, complaining that Python uses exceptions 'wrong' is, to some extent, about as useful as complaining that it treats types 'wrong' because it doesn't check them at the start of the function like some other languages.
|
# ? Jan 16, 2014 18:50 |
|
I just deal with a lot of programmers who are like pathologically terrified of exceptions and waste tons of time coding around corner cases that raise exceptions. I also come from the C world where the "pass a pointer to where you want the results of the function as a parameter, then check the return value of the function to see if it worked, and then check errno to see where it went wrong" style is prevalent and holy god does that get old.
|
# ? Jan 16, 2014 18:51 |
|
Munkeymon posted:Just having exceptions at all allows that to happen, though. I've seen C# that used exceptions to transition between UI states using exceptions like DownloadSuccessfulException, for example. I guess the difference is that in the .net world this is objectively stupid and wrong, since there is such a large overhead to throwing an exception, and convention dictates you do not use exceptions for flow control (except, of course, when dealing with exceptional circumstances such as unexpected errors). Like any rule, there are exceptions (), but in the vast majority of cases the above is true. A value not being in a dictionary in the detailed example above is likely to happen in normal operation, so in this instance an exception should not be used. I would expect the Dictionary.Get function to throw an exception if the value wasn't there - this is entirely appropriate, particularly when "null" or "-1" or whatever could be valid return values. I would not expect code calling the dictionary to throw an exception, but to preface the call with a .ContainsKey guard.
|
# ? Jan 16, 2014 19:06 |
|
Munkeymon posted:Just having exceptions at all allows that to happen, though. I've seen C# that used exceptions to transition between UI states using exceptions like DownloadSuccessfulException, for example. This is a true horror like God drat
|
# ? Jan 16, 2014 19:11 |
|
I usually hear those referred to as "Expections".
|
# ? Jan 16, 2014 19:20 |
|
SurgicalOntologist posted:Huh. I just wrote almost the exact same thing last night and thought I was being a good Python programmer for asking for forgiveness, not permission, or whatever. It's generally poor practice and isn't actually faster: Python code:
Python code:
Don't use exceptions for flow control, it's a stupid and expensive practice seiken posted:"Asking forgiveness instead of permission" is among the most terrible of all terrible nonsense "pythonic" rules. Exceptions are dynamic non-local gotos that obscure control-flow and spread the logic of your program across arbitrarily-distant functions. They should be used for exceptional circumstances and absolutely not as a matter of course. If you're forced to use exceptions for control-flow it's because Python is a bad language You are never forced to use Exceptions for flow control, even if some people think that exception-based flow control is cool for some reason. Python is a good language used by bad people who sometimes like to misuse useful tools QuarkJets fucked around with this message at 19:50 on Jan 16, 2014 |
# ? Jan 16, 2014 19:40 |
|
QuarkJets posted:It's generally poor practice and isn't actually faster: To be completely truthful, it's a little more complicated than this analysis. Whether or not using exceptions vs interrogating is faster depends on the rate of misses. code:
code:
code:
BigRedDot fucked around with this message at 21:33 on Jan 16, 2014 |
# ? Jan 16, 2014 21:26 |
|
Munkeymon posted:Python is structured to lean on them more heavily than most languages, but that's intentional, so it's helpful to think of them as a misnamed feature instead of a misapplied tool. Basically, complaining that Python uses exceptions 'wrong' is, to some extent, about as useful as complaining that it treats types 'wrong' because it doesn't check them at the start of the function like some other languages. I'd have to agree with seiken here, the naming isn't the problem. Python calls them exceptions because they behave like exceptions; i.e. they halt control flow, unwind the stack, and jump to the nearest handler. That is an expensive operation and it's the primary reason why exceptions are considered a horror for control flow. Calling it something else doesn't change the nature of the underlying mechanism nor the reasons why it's a bad idea.
|
# ? Jan 16, 2014 21:41 |
|
BigRedDot posted:To be completely truthful, it's a little more complicated than this analysis. Whether or not using exceptions vs interrogating is faster depends on the rate of misses. I'd assume QuarkJets meant using it in place of an if statement, not never using it. I'd surround attempts at reading files with an try/except but if I wanted to use a variable that may or may not be empty/null then I wouldn't do code:
Looking before you leap is best in most scenarios but as you say, if the failure case truly is exceptional then that's where a try/except comes into play.
|
# ? Jan 16, 2014 21:52 |
|
Tesseraction posted:I'd assume QuarkJets meant using it in place of an if statement, not never using it. BigRedDot fucked around with this message at 22:03 on Jan 16, 2014 |
# ? Jan 16, 2014 21:56 |
|
Okay, I'm sticking with try/except then, my miss rate is something like 1 in 1 million.
|
# ? Jan 16, 2014 22:05 |
|
Monkeyseesaw posted:I'd have to agree with seiken here, the naming isn't the problem. Python calls them exceptions because they behave like exceptions; i.e. they halt control flow, unwind the stack, and jump to the nearest handler. That is an expensive operation and it's the primary reason why exceptions are considered a horror for control flow. Calling it something else doesn't change the nature of the underlying mechanism nor the reasons why it's a bad idea. I get all of that and I've been on your side of this same argument - probably back a few years in this thread - but the people who maintain the language use them for flow control and I'm giving them the benefit of the doubt and trying not to worry about it.
|
# ? Jan 16, 2014 22:08 |
|
SurgicalOntologist posted:Okay, I'm sticking with try/except then, my miss rate is something like 1 in 1 million. In your circumstance, there is already a tool written into the language that does exactly what you want to do. You should either use dict.get() or a defaultdict for more complicated cases try/except with careful crafting (IE catching the exact exception that you want and having an extremely short try block) is not a horror, but it is a slippery slope to horrors that you should avoid when there's already a mechanism that does the same thing in a better way
|
# ? Jan 17, 2014 01:30 |
|
QuarkJets posted:In your circumstance, there is already a tool written into the language that does exactly what you want to do. You should either use dict.get() or a defaultdict for more complicated cases Maybe I'm missing something but I don't see how I could accomplish what I'm doing with a defaultdict. Every time I encounter a missing key I'm not only supplying the missing value but also changing the value of all the existing elements in the dict.
|
# ? Jan 17, 2014 01:36 |
|
Why do you want to modify an entire dict when a key is missing?
|
# ? Jan 17, 2014 01:49 |
|
SurgicalOntologist posted:Maybe I'm missing something but I don't see how I could accomplish what I'm doing with a defaultdict. Every time I encounter a missing key I'm not only supplying the missing value but also changing the value of all the existing elements in the dict. Hmm, I reread your later posts and that's true But I guess I don't understand why you're using a dict at all, in that case. If you're just using the keys "Sensor1", "Sensor2", ..., "SensorN" and then remapping other objects to these keys, why not just use a list of length N? Then the user just references an entry in the list rather than referencing the "SensorN" key in the dictionary. e: I guess I don't really understand your setup that well. Can you describe it again? Clearing and then re-instantiating the dict every time that you see a new sensor sounds like a lot of unnecessary work QuarkJets fucked around with this message at 01:58 on Jan 17, 2014 |
# ? Jan 17, 2014 01:51 |
|
The issue is how to allow the user to select any set of sensors while also making them predictably identifiable. Basically, I need to map physical sensors to logical sensors as someone said. For an example, maybe you're using these sensors to make a two-player game. One player controls a "goalie" (I'm visualizing a pong paddle) and the other player tosses projectiles toward the goal by making a flicking motion. I want the players to be able to pick any two physical sensors but still be able to predict which will control the goalie and which will control the shooter. The solution being that only the relative order of the sensor numbers matters: maybe whoever has the sensor with the lower number is the goalie. I want to end up with a dict that has physical sensor numbers as keys and logical sensor numbers as values. When raw data comes in, I clean it up, extract the sensor number, and use that to determine where to store the rest of the data: Python code:
1. A data packet comes in. Call this sensor 0. At this point we have no idea if we will encounter more sensors, and if so what physical numbers they will have. 2. Another data packet comes in. If it's from the same sensor, we're good for the rest of the session. If it's from a new sensor, reorder the sensors. Make the one with a lower physical number sensor 0. 3. Etc. until the first cycle has completed. 4. After 5 ms the sensor mapping should be stable for the rest of the session. The only downside is before 5 ms have passed the data will be misidentified. But I'm not too concerned about that. Anyways I think I have this figured out I only posted it because someone posted catching a KeyError for control flow as a horror within 8 hours of my having done exactly that. E: I suppose I could avoid the try-except by sending data to a 'set_up_sensors' procedure until the first cycle completes, at which point I switch the data stream to send to the normal handler. Only issue here is I'm not confident in the hardware - there's a chance I could get a second packet from one sensor before I get the first packet from another. I suppose I could transition after like 50 ms or something to be absolutely confident, but setting that up would be more effort than it's worth, I think. SurgicalOntologist fucked around with this message at 06:26 on Jan 17, 2014 |
# ? Jan 17, 2014 06:17 |
|
I think the person that was on my team before I got there had this whole Python exception handling thing down, found a bunch of code like this today:code:
|
# ? Jan 17, 2014 06:27 |
|
|
# ? May 27, 2024 17:45 |
|
SurgicalOntologist posted:The only downside is before 5 ms have passed the data will be misidentified. But I'm not too concerned about that. Most of what you're saying makes sense, but this specifically is really weird. You're being blasé about, basically, introducing an arbitrary and unnecessary source of data corruption to your clients, who may or may not care about the sensors having nice, small identifying numbers but definitely care a lot about reliably identifying a single stream of data. If the renumbering thing is really important for some reason you haven't explained, then yes, you almost certainly should just delay/suppress sending any data to the client for the first cycles until you've figured out how many sensors there are.
|
# ? Jan 17, 2014 07:30 |