Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Zombywuf posted:

Then all my unit test fail at the call site instead of at the location of the error.

Wait, why does that happen?

Adbot
ADBOT LOVES YOU

Zombywuf
Mar 29, 2008

Jonnty posted:

Wait, why does that happen?

code:
def foo(a, b, ):
    do_stuff

foo(x, y, z)

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Zombywuf posted:

code:
def foo(a, b, ):
    do_stuff

foo(x, y, z)

Oh, so what I said then. I still don't see why that's any more of a horror than any other valid-but-not-what-I-meant bit of code.

it is
Aug 19, 2011

by Smythe
code:
def can_do_x_to_y:
     @returns: a list of y's that can't have x done to them
Super job, guys.

Zombywuf
Mar 29, 2008

Jonnty posted:

Oh, so what I said then. I still don't see why that's any more of a horror than any other valid-but-not-what-I-meant bit of code.

Python seems to quite like letting you dump stray comma's around, sometimes they change the meaning of the code, sometimes they don't, why not just ban the commas? Then there's the fact that this code produces no errors:
code:
++x
Code that does nothing should be represented by empty space, when it's possible to represent code that does nothing with a non empty string it should at least produce some kind of warning.

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Zombywuf posted:

Python seems to quite like letting you dump stray comma's around, sometimes they change the meaning of the code, sometimes they don't, why not just ban the commas? Then there's the fact that this code produces no errors:
code:
++x
Code that does nothing should be represented by empty space, when it's possible to represent code that does nothing with a non empty string it should at least produce some kind of warning.

We've already been through why trailing commas are often very convenient; sorry that the python devs value that over compensating for your clumsy hands.

Zombywuf
Mar 29, 2008

Jonnty posted:

We've already been through why trailing commas are often very convenient; sorry that the python devs value that over compensating for your clumsy hands.

And I mentioned why down that route HTML lies.

xf86enodev
Mar 27, 2010

dis catte!

Zombywuf posted:

Le sigh.

Why don't you make a rage comic about it and post it to /r/python? Call it "le PEP" and the language will be fixed faster than you can say "significant whitespace".

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Zombywuf posted:

And I mentioned why down that route HTML lies.

No, it really doesn't. You've got unit tests - use them.

Zombywuf
Mar 29, 2008

Jonnty posted:

No, it really doesn't. You've got unit tests - use them.

Like how I can shove any old tag soup into a browser and so long as it looks right it's ok?

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

Zombywuf posted:

Working on it, but emacs's compile mode doesn't quite do what I want. It would still have the problem that the error would be reported at the call site, not at the line of code with the error.

Use shorter methods more conducive to unit testing, and test the poo poo out of them.

https://vimeo.com/1534976

Zombywuf
Mar 29, 2008

BonzoESC posted:

Use shorter methods more conducive to unit testing, and test the poo poo out of them.

I'm in the process of turning an untested and undocumented codebase with functions hundreds of lines long into a tested and documented codebase with functions less than 20 lines long, mostly shorter.

Tests caught the error, if it was a syntax error pylint+flymake would have caught it before I even hit save.

baquerd
Jul 2, 2007

by FactsAreUseless

Zombywuf posted:

I'm in the process of turning an untested and undocumented codebase with functions hundreds of lines long into a tested and documented codebase with functions less than 20 lines long, mostly shorter.

That honestly sounds to me like you've gone from too far on one side to too far on the modular side. How many functions do you call more than once? If unit testing is your group's thing, it will certainly make easier, but it's a lot of jumping around and likely often passing a lot of parameters. I'd much rather have a 100 line function that does one thing than 5 20 line functions that do one thing.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

baquerd posted:

That honestly sounds to me like you've gone from too far on one side to too far on the modular side. How many functions do you call more than once? If unit testing is your group's thing, it will certainly make easier, but it's a lot of jumping around and likely often passing a lot of parameters. I'd much rather have a 100 line function that does one thing than 5 20 line functions that do one thing.

You have to strike a balance. Some people say "if your method is more than X lines long, it's doing too much", where X is 5, or 10, or 20. I don't necessarily agree, but big methods are generally doing too much and are a nightmare to unit test and maintain.

baquerd
Jul 2, 2007

by FactsAreUseless

Ithaqua posted:

You have to strike a balance. Some people say "if your method is more than X lines long, it's doing too much", where X is 5, or 10, or 20. I don't necessarily agree, but big methods are generally doing too much and are a nightmare to unit test and maintain.

I completely hear you on unit testing. As far as being able to maintain, it really depends a lot on how your methods are going to be used.

Suppose you need to implement code that joins together two tables from different databases with some data manipulation. You could write one method to do this, or perhaps 6 or more (1 each to retrieve tables, 1 each to manipulate data on returned tables, 1 to join the data, 1 to manipulate joined data).

If this method is meant to be used once internally inside a class and it is not foreseen as likely to need to change the basic idea behind the method, I would tend towards using a single method, which can be trivially refactored in the future without impact. There is a vague conceptual limit on the number of lines before a method becomes "too large", but this would tend more towards 50 to 100 lines in this case. The more public the methods, the better it tends to be to make them compartmentalized and specific in purpose.

My group doesn't do unit testing as the development time cost is considered too high to achieve good coverage and black box testing combined with good general practices with exception handling serves us well. I tend to agree with this practice, as our applications tend towards internally isolated components on an architectural level with libraries and utility classes drawn in, so compartmentalization on a code level tends to only increase overhead in both development and execution without adding significant value.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

baquerd posted:

My group doesn't do unit testing as the development time cost is considered too high to achieve good coverage and black box testing combined with good general practices with exception handling serves us well.

That sounds insane. You're testing your code at some point (even if it's by writing status text to the console or stepping through with a debugger), so why not capture those tests in a repeatable fashion? I'd rather spend an hour or two writing test cases now and save myself from pain 6 months down the line when I have to refactor to add a new feature.

The team I recently joined has a similar "boo hoo it takes extra time to write tests" attitude, and I'm trying really hard to change it. I'm leading by example, adding tests whenever I can, even if it's only for a couple of simple methods. I've found and corrected a few ticking timebombs by doing so, too. Someone even brought up the "exception handling" point, which just seems like a crutch to me. You shouldn't have exceptions in the first place. That means your code is hosed up, which is why you should unit test.

BAD ANALOGY TIME: It's like not bothering to check if you have faulty wiring because you have a really good sprinkler system and plenty of fire extinguishers. It's good to have, but you should still fix the wires before you need the fire extinguishers.

New Yorp New Yorp fucked around with this message at 04:15 on Oct 19, 2011

Opinion Haver
Apr 9, 2007

You know what I think this needs? More nested classes.

baquerd
Jul 2, 2007

by FactsAreUseless

Ithaqua posted:

That sounds insane. You're testing your code at some point (even if it's by writing status text to the console or stepping through with a debugger), so why not capture those tests in a repeatable fashion? I'd rather spend an hour or two writing test cases now and save myself from pain 6 months down the line when I have to refactor to add a new feature.

I understand the case for unit testing, and in a way our code structure merges the unit tests into the code in that if there's something wrong, an exception should be thrown and logged. If the code executes under various input without exceptions during testing, it has "passed".

If code slips under the radar that should have thrown an exception, how is this any different than not considering/writing the test for that possibility? A truly thorough unit test will be longer than the code itself in many cases, and that is where the cost of development time comes in. Writing thorough unit tests in a couple of hours seems optimistic.

The logical structure of our codebase does not lend itself to complex interactions between objects that should be more thoroughly tested during changes, rather each object/application is internally contained and testing can be done in-line. Doing real-time validation via exceptions during operation is efficient and catches many errors due to changes in external resources before optimistic code that has thorough unit tests would, simply due to the unit tests not being run constantly.

I have the ability look at the logs of any user's usage and write changes that are pushed out to production usage the same day. Most critical issues tend to deal with unforeseen changes in input parameters, and unit testing will not catch these during testing. The applications I write depend on business input to determine their function, and writing extremely robust applications (as opposed to what you might call "fail-fast") would involve asking users about increasingly arcane situations and delay releases significantly.

If I had to deal with greater separation between myself and the users, or more complex architecture, I'd be more receptive to taking the time to separate and formalize the testing.

tef
May 30, 2004

-> some l-system crap ->

Ithaqua posted:

BAD ANALOGY TIME

The idea that you shouldn't have exceptions is a bit silly. Software errors in third party libraries, hardware faults, interrupts, often throw exceptions. Or even have failures. Robust software actually comes from writing things to handle failures rather than eliminating failure cases.

Joe Armstrong wrote a whole bunch of words about it in his thesis on erlang. It is quite light reading by comparison with a lot of theory laden thesis.

tef fucked around with this message at 05:21 on Oct 19, 2011

TasteMyHouse
Dec 21, 2006

yaoi prophet posted:

You know what I think this needs? More nested classes.

nested classes that CONTAIN NOTHING EXCEPT FURTHER NESTED CLASSES

Presto
Nov 22, 2002

Keep calm and Harry on.

SlightlyMadman posted:

I can't remember for the life of me, but I was working with some horrible scripting language not long ago that would actually throw AN ERROR if you tried to do that CORRECTLY. Declaring "int i" a second time would tell you that i was already defined. I ended up having to declare all of my iterators at the top of the function.
I know Adobe Flexbuilder bitches if you do 'for (int i; ...' more than once. I think it's just a warning though.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Zombywuf posted:

Sooooo
code:
def foo(a, ):
doesn't appear to be an error in Python.

Damnit Guido.

I love how Python ignores an extra trailing comma in lists and tuples, but it doesn't seem useful in parameter lists. Why is it allowed here too?

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Presto posted:

I know Adobe Flexbuilder bitches if you do 'for (int i; ...' more than once. I think it's just a warning though.

Because actionscrpt is function scoped, not block scoped, so you are duplicating the creation of i.

xf86enodev
Mar 27, 2010

dis catte!

pokeyman posted:

I love how Python ignores an extra trailing comma in lists and tuples, but it doesn't seem useful in parameter lists. Why is it allowed here too?

Consistency. Why should parameter lists be different when working with them in your editor is very similar to working with lists, tuples and dictionaries?

Zombywuf
Mar 29, 2008

baquerd posted:

That honestly sounds to me like you've gone from too far on one side to too far on the modular side. How many functions do you call more than once? If unit testing is your group's thing, it will certainly make easier, but it's a lot of jumping around and likely often passing a lot of parameters. I'd much rather have a 100 line function that does one thing than 5 20 line functions that do one thing.

Then I say you're a fool. Functions are for giving names to distinct actions, another way of looking at is they are a way of limiting the scope of groups of variables; so in answer to your question, most of them. If you're writing lots of single use functions that take more than 4 (number pulled from arse) paramaters you are doing it wrong though, functions should occur where there are choke points in the dataflow of your program.

I don't unit test functions intended for internal use, all that does is make certain design choices brittle.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

xf86enodev posted:

Consistency. Why should parameter lists be different when working with them in your editor is very similar to working with lists, tuples and dictionaries?

Well I was thinking of something like
code:
>>> def butts(*args,): pass
SyntaxError: invalid syntax
which mostly points out that it's inconsistent in the language but that could also happen with a naive editor (e.g. you remove the **kwargs parameter with an editor action that assumes a trailing comma is always fine to leave in). And I feel like once you're handling that special case in your editor then why not treat parameter lists like the separate construct they are.

Comrade Gritty
Sep 19, 2011

This Machine Kills Fascists
Contrived Example!

code:
def my_function(a, b, c, d):
    pass
changing to

code:
def my_function(a, b, c, d, e):
    pass
produces this diff:

code:
- def my_function(a, b, c, d):
+ def my_function(a, b, c, d, e):
while

code:
def my_function(
    a,
    b,
    c,
    d,
)
going to

code:
def my_function(
    a,
    b,
    c,
    d,
    e,
)
produces this diff:

code:
+ e,
This is basically why it's allowed for lists, tupes, dictionaries, and the args to a function is just a tuple.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Steampunk Hitler posted:

the args to a function is just a tuple.

Is it, though? I can't put *args or key=value pairs in a tuple, so function args seem to have special powers to me.

Cheesus
Oct 17, 2002

Let us retract the foreskin of ignorance and apply the wirebrush of enlightenment.
Yam Slacker
Ah, a "classic"...

We allow customers to purchase warranties on our hardware products, but only if the unit is under 4 years old. While it makes sense to have some limit, 4 years seems pretty arbitrary. Maybe 4 for this platform and 5 for another? Whatever, it would be pretty easy to extend it if you needed to if the function was named isEligibleForWarranty() instead of deviceIsFourYearsOld().

SlightlyMadman
Jan 14, 2005

Cheesus posted:

Ah, a "classic"...

We allow customers to purchase warranties on our hardware products, but only if the unit is under 4 years old. While it makes sense to have some limit, 4 years seems pretty arbitrary. Maybe 4 for this platform and 5 for another? Whatever, it would be pretty easy to extend it if you needed to if the function was named isEligibleForWarranty() instead of deviceIsFourYearsOld().

To make this better, be sure you call that function in other parts of the code to determine the units age for completely unrelated reasons, and then later end up changing the warranty eligibility to be based on something completely different, but retain the original function name.

TasteMyHouse
Dec 21, 2006
One from me, causing a bug I just found in my own code.

System.Diagnostics.StopWatch.ElapsedMilliseconds is VERY different from System.Diagnostics.StopWatch.Elapsed.Milliseconds

xf86enodev
Mar 27, 2010

dis catte!

pokeyman posted:

Is it, though? I can't put *args or key=value pairs in a tuple, so function args seem to have special powers to me.

Of course, the parameter list is special but the devs seem to have tried to make it work like other lists. And in most cases this works and is consistent.
As you have noticed, you can't put *args or **kwargs in a list or tuple, so maybe when you put them in your function definition you should expect a different behaviour? Defining functions with *args or **kwargs is tricky enough that you should pay extra attention when you're "refactoring" those, in my opinion.

I really don't see the horror, yes there is some inconsistency, but at least it's well defined :)

Vanadium
Jan 8, 2005

yaoi prophet posted:

Better to just have iterators.h that you #include at the top of every file:
code:
int i;
int j;
int k;

You should call it dijkstra.h

Impotence
Nov 8, 2010
Lipstick Apathy
I've seen some assholes in unicode-aware languages use мноıǐi for nested ++

Seems like a good idea.

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

TasteMyHouse posted:

One from me, causing a bug I just found in my own code.

System.Diagnostics.StopWatch.ElapsedMilliseconds is VERY different from System.Diagnostics.StopWatch.Elapsed.Milliseconds

When I get curious as to how well some similar set of operations perform in a tight loop I'll whip up a really quick console app to give some rough metrics. Usually it's a single function that runs two or three loops, depending on how many operations I'm testing, and I always always forget to call StopWatch.Reset() between loops. I then waste my time trying to figure out why the hell operation2 is consistently twice as slow as operation1.

w00tz0r
Aug 10, 2006

I'm just so god damn happy.
"Forward compatibility is easy, all Microsoft products are completely forward compatible. I can write a program on Windows Vista and have it run on Windows 95. The only thing that broke forwards compatibility is UAC."

TasteMyHouse
Dec 21, 2006

w00tz0r posted:

"Forward compatibility is easy, all Microsoft products are completely forward compatible. I can write a program on Windows Vista and have it run on Windows 95. The only thing that broke forwards compatibility is UAC."

:staredog:

SlightlyMadman
Jan 14, 2005

Tell me whoever said that got fired on the spot, because they were clearly high as a kite.

w00tz0r
Aug 10, 2006

I'm just so god damn happy.
That was my lead. I had a shouting match with him that lasted at least half an hour.

edit: basically, if anyone's leaving the company over that, it's me.

w00tz0r fucked around with this message at 21:04 on Oct 19, 2011

Adbot
ADBOT LOVES YOU

Dicky B
Mar 23, 2004

w00tz0r posted:

That was my lead. I had a shouting match with him that lasted at least half an hour.
Who won?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply