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
theratking
Jan 18, 2012
It's a difference between Python 3 and 2.X I think.

Adbot
ADBOT LOVES YOU

Amarkov
Jun 21, 2010

theratking posted:

It's a difference between Python 3 and 2.X I think.

It is indeed.

(I'm half surprised 3.X didn't make it an optional flag because MY BACKWARDS COMPATIBILITY :qq:. I've learned to expect very little from language designers when it comes to random dumb things their language allows.)

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Amarkov posted:

(I'm half surprised 3.X didn't make it an optional flag because MY BACKWARDS COMPATIBILITY :qq:. I've learned to expect very little from language designers when it comes to random dumb things their language allows.)

3 was all about making changes that broke backwards compatibility so it's not that surprising really.

Civil Twilight
Apr 2, 2011


Python 3 ruined everything.

ed: oops, new page.

hobbesmaster
Jan 28, 2008

evensevenone posted:

in matlab
code:
>> i

ans =

        0 + 1.0000i

>> i=1

i =

     1

>> i

i =

     1

>> 
But if you really want to piss someone off, name a variable 'quit'.

Use j, never use more than one loop. Problem solved!

But what about unit vectors?

PROBLEM SOLVED

Modern Pragmatist
Aug 20, 2008

hobbesmaster posted:

Use j, never use more than one loop. Problem solved!

But what about unit vectors?

PROBLEM SOLVED

Both i and j map to sqrt(-1), so use either one.

Also, in regards to Matlab, never use a for loop.

qntm
Jun 17, 2009

Bunny Cuddlin posted:

I thought it was just a weird quirk because it appears across a lot of our files but i finally realized a few days ago that a former coworker did for (int ii = 0; ii < x; ii++) because he was prefixing the variable name 'i' with the hungarian prefix 'i' for integer.

I see people do this in Java. And string variable names prefixed with "str".

Bunny Cuddlin
Dec 12, 2004

qntm posted:

I see people do this in Java. And string variable names prefixed with "str".

oh yea he does comprehensive Hungarian: str for strings, ds for datasets, dt for datatables, b for booleans, etc

Arcteryx Anarchist
Sep 15, 2007

Fun Shoe
Javas own hungarian-notation-in-spirit 'pattern' thats always bugged me is prefixing all interface classes with 'I* and '*Impl' for 'implementors' of interfaces.

I had a discussion with a contractor the other day about some class he was working on and a bit confused about why it wasn't working as he expected. I looked over it and noticed he had copied a lot of another implementation that was kind of wacky due to some of the libraries it was interfacing with. The class he was working on had no need for any of this so I suggested that he could probably get away from a lot of the weird state issues he was having by removing a lot of that unnecessary strange instantiation bits needed by that other implementation. His response was 'OK I think I'll try that after I put some more time into this to see if I can make it work' :psyduck:

That could basically serve as the basic indicator story of the quality of this project.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

lancemantis posted:

Javas own hungarian-notation-in-spirit 'pattern' thats always bugged me is prefixing all interface classes with 'I*
I've never seen this in a Java library, but .NET loves it and I loving despise it.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

Some more SQL horror from this project I inherited. The table is meant to describe products, and each product has columns like Color1, Color2, Color3, etc. (which is a normalization horror in its own right). So the previous guy has a select to retrieve products by color, straightforward right? Except for this bizarre last where clause...
code:
SELECT * FROM Products
WHERE
 Color1 = @Color1
 AND (LEN(Color2)>0 OR Color2 IS NULL)
So he's returning results if Color2 is NULL or if it has anything in it, which seems bizarrely redundant. I thought at first it would at least exclude empty string, but nope, SELECT LEN('') returns zero too. So basically there's no circumstance where this WHERE clause would not fire. Is this just another AND 1=1?

Also, I don't know if people consider this a horror, but I've been transitioning to C#. I knew it was case sensitive but I never really stopped to think what that could mean in the wrong hands (same guy as above). I go in to make a simple change and get to see this in the Intellisense output:
code:
getthing(string)
Getthing(int)
GetThing(array)
getThing(datatable)
Is this 'a thing' in case sensitive languages? It's not even consistent because getthing2 takes an object, GetThing3 takes a string, etc. etc.

kitten smoothie
Dec 29, 2001

Scaramouche posted:


code:
getthing(string)
Getthing(int)
GetThing(array)
getThing(datatable)
Is this 'a thing' in case sensitive languages? It's not even consistent because getthing2 takes an object, GetThing3 takes a string, etc. etc.
The correct way is to take advantage of function overloading and define the method with the same name, case and all, but different types for the parameters.

Assuming of course that the purpose of the function is the same and it is just using different criteria to Get A Thing given the data type passed in.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

lancemantis posted:

Javas own hungarian-notation-in-spirit 'pattern' thats always bugged me is prefixing all interface classes with 'I* and '*Impl' for 'implementors' of interfaces.
This is frequently a sign of premature abstraction where the interface doesn't actually make any sense on its won.

ToxicFrog
Apr 26, 2008


Scaramouche posted:

Is this 'a thing' in case sensitive languages? It's not even consistent because getthing2 takes an object, GetThing3 takes a string, etc. etc.

No, it is not :gonk:

If they do the same thing and differ only in argument type, they should have the same name including case and use function overloading. If they do different things, they should have different names. This naming convention is a horror in either case.

Even if for some reason they can't use function overloading (say, they also have different return types and C# doesn't allow return type overloads), the answer is not to name all of the variants the same thing with different case. Goddamn.

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

Aleksei Vasiliev posted:

I've never seen this in a Java library, but .NET loves it and I loving despise it.

As I'm sure I've posted before in this thread, there's certain cases where "what makes good sense" for the situation and Hungarian notation overlap. Naming Windows Forms buttons "btCancel" isn't a horror, and neither is naming your interfaces I*, especially because it matches the standard .NET naming convention for interfaces:

quote:

*Name interfaces with nouns or noun phrases, or adjectives that describe behavior. For example, the interface name IComponent uses a descriptive noun. The interface name ICustomAttributeProvider uses a noun phrase. The name IPersistable uses an adjective.
*Use Pascal case.
*Use abbreviations sparingly.
*Prefix interface names with the letter I, to indicate that the type is an interface.
*Use similar names when you define a class/interface pair where the class is a standard implementation of the interface. The names should differ only by the letter I prefix on the interface name.
*Do not use the underscore character (_).

nielsm
Jun 1, 2009



Scaramouche posted:

So he's returning results if Color2 is NULL or if it has anything in it, which seems bizarrely redundant. I thought at first it would at least exclude empty string, but nope, SELECT LEN('') returns zero too. So basically there's no circumstance where this WHERE clause would not fire. Is this just another AND 1=1?

I'd say "Color1 is only valid if Color2 is properly defined or known to not exist", i.e. if Color2='' then Color1 is invalid. Whether Color2 ever ='' is another question. (Except if you're on Oracle where '' IS NULL is true. Then I can't think of an explanation.)

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

nielsm posted:

I'd say "Color1 is only valid if Color2 is properly defined or known to not exist", i.e. if Color2='' then Color1 is invalid. Whether Color2 ever ='' is another question. (Except if you're on Oracle where '' IS NULL is true. Then I can't think of an explanation.)

I don't think you got it; he's doing an OR comparison there, which means that it doesn't matter what is in Color2. Color2 could be 'red', could be NULL, could be '', Color1 will always be valid for any value found in Color2, so there's no reason to be checking it for anything. There is literally no value for Color2 that would cause rows to be filtered by that WHERE clause.

Freakus
Oct 21, 2000

Scaramouche posted:

I don't think you got it; he's doing an OR comparison there, which means that it doesn't matter what is in Color2. Color2 could be 'red', could be NULL, could be '', Color1 will always be valid for any value found in Color2, so there's no reason to be checking it for anything. There is literally no value for Color2 that would cause rows to be filtered by that WHERE clause.

I don't understand:

code:
mysql> select length('')>0 or '' is null;
+----------------------------+
| length('')>0 or '' is null |
+----------------------------+
|                          0 | 
+----------------------------+
1 row in set (0.04 sec)

mysql> select length(null)>0 or null is null;
+--------------------------------+
| length(null)>0 or null is null |
+--------------------------------+
|                              1 | 
+--------------------------------+
1 row in set (0.00 sec)

mysql> select length('fds')>0 or 'fds' is null;
+----------------------------------+
| length('fds')>0 or 'fds' is null |
+----------------------------------+
|                                1 | 
+----------------------------------+
1 row in set (0.00 sec)

Or was > a typo?

Freakus fucked around with this message at 22:54 on Mar 29, 2013

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Freakus posted:

I don't understand:

code:
mysql> select length('')>0 or '' is null;
+----------------------------+
| length('')>0 or '' is null |
+----------------------------+
|                          0 | 
+----------------------------+
1 row in set (0.04 sec)

mysql> select length(null)>0 or null is null;
+--------------------------------+
| length(null)>0 or null is null |
+--------------------------------+
|                              1 | 
+--------------------------------+
1 row in set (0.00 sec)

mysql> select length('fds')>0 or 'fds' is null;
+----------------------------------+
| length('fds')>0 or 'fds' is null |
+----------------------------------+
|                                1 | 
+----------------------------------+
1 row in set (0.00 sec)

Or was > a typo?

This. It sounds like a godawful way to filter out empty strings, likely copy/pasted from some forum.

Amarkov
Jun 21, 2010

nielsm posted:

(Except if you're on Oracle where '' IS NULL is true. Then I can't think of an explanation.)

Does nobody read things in parentheses?

Bunny Cuddlin
Dec 12, 2004

Factor Mystic posted:

As I'm sure I've posted before in this thread, there's certain cases where "what makes good sense" for the situation and Hungarian notation overlap. Naming Windows Forms buttons "btCancel" isn't a horror, and neither is naming your interfaces I*, especially because it matches the standard .NET naming convention for interfaces:

yeah, I name forms controls btnOK, ddlDropDown, tbInput, etc. This is especially helpful in an editor with proper Intellisense (which I guess is all of them these days).

God of Mischief
Oct 22, 2010

Aleksei Vasiliev posted:

I've never seen this in a Java library, but .NET loves it and I loving despise it.

Spring. Spring loves its goddamn interfaces and single-implementing classes named <Interface>Impl. Yes, I understand that it is apparently much easier to proxy interfaces than concrete classes. No, you are not "programming to interfaces" in the way that it was intended to mean. Now gently caress you let me just use my concrete class because I will never have a second implementation for it. I will beat you to death if you give me an interface with a matching *Impl for no reason.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

God of Mischief posted:

Spring. Spring loves its goddamn interfaces and single-implementing classes named <Interface>Impl. Yes, I understand that it is apparently much easier to proxy interfaces than concrete classes. No, you are not "programming to interfaces" in the way that it was intended to mean. Now gently caress you let me just use my concrete class because I will never have a second implementation for it. I will beat you to death if you give me an interface with a matching *Impl for no reason.

I don't mind it. I usually program in the large (multi million line projects) and sometimes you need to do something no one anticipated, and the original Impl is good enough for 80% of cases, and for the other 20% you just plug in your new class that handles the new feature. Having that simple layer of abstraction (Thing and ThingImpl) has saved me a bunch of headache a number of times.

Funking Giblet
Jun 28, 2004

Jiglightful!

trex eaterofcadrs posted:

I don't mind it. I usually program in the large (multi million line projects) and sometimes you need to do something no one anticipated, and the original Impl is good enough for 80% of cases, and for the other 20% you just plug in your new class that handles the new feature. Having that simple layer of abstraction (Thing and ThingImpl) has saved me a bunch of headache a number of times.

Subclass would probably be better here,unless the implementation is totally different.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

Funking Giblet posted:

Subclass would probably be better here,unless the implementation is totally different.

Maybe I'm cargo culting a bit here but I prefer to code to interfaces rather than subclasses.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Factor Mystic posted:

Naming Windows Forms buttons "btCancel" isn't a horror, and neither is naming your interfaces I*, especially because it matches the standard .NET naming convention for interfaces:
I know it's .NET convention to prefix interfaces with I, but it's terrible and misses the entire point of interfaces.

Sang-
Nov 2, 2007

Funking Giblet posted:

Subclass would probably be better here,unless the implementation is totally different.

Subclassing concrete classes isn't best practice really, it can lead (more easily) to annoying ArrayStoreExceptions for example.

God of Mischief
Oct 22, 2010

trex eaterofcadrs posted:

Maybe I'm cargo culting a bit here but I prefer to code to interfaces rather than subclasses.

You're coding to an interface (exposed method signatures) no matter what, you just aren't really coding towards interfaces (java style). I just think that if I can't decide what to name a class besides *Impl, it really has no place in having an interface created specifically for it. That is my main logic to decide when I need an interface vs concrete class: can I create something that implements the interface for a specific reason, or is the class there PURELY as a default interface implementation?

Funking Giblet
Jun 28, 2004

Jiglightful!

Sang- posted:

Subclassing concrete classes isn't best practice really, it can lead (more easily) to annoying ArrayStoreExceptions for example.

Well depends on context really, you can substitute between different implementations of an interface when the same interface is required, but using a subclass also allows polymorphic calls when the super class is a dependency, not an interface. Not to mention that the base class might do a lot of what you need already, you just need to adjust some behaviours.

For example, if you had a domain entity, which encapsulated logic for a specific domain (say E-Commerce basket). Would you rather subclass this for a specific purpose or write an interface to mirror the Basket class (not just behaviour, but stuff like properties).

Funking Giblet fucked around with this message at 22:47 on Mar 30, 2013

Rothon
Jan 4, 2012
The *Impl "pattern" is also used in Java to help out with unit testing. The *Impl class isn't actually the only implementation: tests define mock implementations and use those to avoid dependencies on other parts of the application. You need the interface because the mock libraries use java.lang.reflect.Proxy under the hood which can only implement interfaces, not extend classes.

Freakus
Oct 21, 2000

God of Mischief posted:

You're coding to an interface (exposed method signatures) no matter what, you just aren't really coding towards interfaces (java style).
I've noticed that people are more willing to poo poo up a concrete class' interface rather than an interface's interface. One of many reasons why we can't have nice things.

Sang-
Nov 2, 2007

Funking Giblet posted:

Well depends on context really, you can substitute between different implementations of an interface when the same interface is required, but using a subclass also allows polymorphic calls when the super class is a dependency, not an interface. Not to mention that the base class might do a lot of what you need already, you just need to adjust some behaviours.

For example, if you had a domain entity, which encapsulated logic for a specific domain (say E-Commerce basket). Would you rather subclass this for a specific purpose or write an interface to mirror the Basket class (not just behaviour, but stuff like properties).

In that case I'd be coding an abstract base class and have two concrete classes.

pigdog
Apr 23, 2004

by Smythe
That doesn't necessarily sound like the greatest idea, because interfaces can be implemented by all kinds of classes (eg Serializable) while inheritance requires a bigger architectural investment.

Anyway, I think the *Impl thing is from the early days of Java where there were no good IDEs and people had to keep track of what implements what by filenames, whereas these days finding implementation classes is a click away.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

pigdog posted:

That doesn't necessarily sound like the greatest idea, because interfaces can be implemented by all kinds of classes (eg Serializable) while inheritance requires a bigger architectural investment.

Anyway, I think the *Impl thing is from the early days of Java where there were no good IDEs and people had to keep track of what implements what by filenames, whereas these days finding implementation classes is a click away.

Yeah, interfaces are for creating a contract that defines a set of behaviors, regardless of how the behavior is ultimately implemented. I shoot for small interfaces that define a specific discrete behavior, then compose classes by implementing those interfaces.

God of Mischief
Oct 22, 2010

Rothon posted:

The *Impl "pattern" is also used in Java to help out with unit testing. The *Impl class isn't actually the only implementation: tests define mock implementations and use those to avoid dependencies on other parts of the application. You need the interface because the mock libraries use java.lang.reflect.Proxy under the hood which can only implement interfaces, not extend classes.

I find mocking nicer than creating test implementations, but that taste may differ between people and/or projects. But I did not know about java.lang.reflect.Proxy before, that actually explains a great many things about proxying in Java.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

Rothon posted:

The *Impl "pattern" is also used in Java to help out with unit testing. The *Impl class isn't actually the only implementation: tests define mock implementations and use those to avoid dependencies on other parts of the application. You need the interface because the mock libraries use java.lang.reflect.Proxy under the hood which can only implement interfaces, not extend classes.

It's the same with .NET. For instance, the popular mocking library Moq can only mock interfaces and virtual methods on non-sealed classes, because it uses the proxy library Castle DynamicProxy, which has that same limitation. I know that TypeMock's Isolator and Microsoft's own Fakes framework can mock almost anything, but they cost a lot of money. I hate making 1-to-1 class/interface pairs where the odds that I'll ever need to make a second implementation of the interface are basically zero, but the alternative is to make every public method on the class virtual, which is no better, and which is more likely to be forgotten if new methods are added, and also leads to more complexity in the mocking code. And of course every interface will be named stuff like IClassName, since that's exactly what they are. It's got nothing to do with "programming by interface", really; it's purely a technique for mocking. But it's very annoying to have to do it.

wwb
Aug 17, 2004

Having dived into a bit of objective-c development I really like the pattern -- using interfaces is alot like the C-style headers and then implementation, which I'm falling in love with.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

ToxicFrog posted:

No, it is not :gonk:

If they do the same thing and differ only in argument type, they should have the same name including case and use function overloading. If they do different things, they should have different names. This naming convention is a horror in either case.

Even if for some reason they can't use function overloading (say, they also have different return types and C# doesn't allow return type overloads), the answer is not to name all of the variants the same thing with different case. Goddamn.

Good god it just gets worse with this guy and case sensitivity. A pretty important calculation was going wrong, and it turns out that Diameter1 is imperial units and diameter1 is metric units. Guess the result always being out by a factor of *25.4 might be related! It's not even consistent because Diameter2 and diameter2 is the reverse.

It's like there are things I can troubleshoot for and figure out, and then there's things that are intrinsically wrong and should be read as basic assumptions. I'm wondering what other basic infrastructural decisions I'm going to have to investigate.

HORATIO HORNBLOWER
Sep 21, 2002

no ambition,
no talent,
no chance
Due to downsizing at my work, I have two peoples' jobs now. Half my time is spent on new development and half my time is spent on supporting a horrendous beast of a legacy web application that is considered mission critical for a whole bunch of external customers. This app is huge and an entire book could be written about the horrors that lay within.

One of the things the app does is maintain records about a thing, let's call it a System. Each System has a list of Widgets that are associated with it. Each Widget has a cost, and so the cost of the System is equal to the sum of the costs of the Widgets associated with the system. Pretty straightforward, right? (Calculating the cost of each Widget is fairly complicated but not directly relevant here.)

So, for "performance" the cost of the System isn't directly calculated on demand; when you update a System record, the total cost is calculated and stored in a summary row. Notice I said "when you update a System record." You can update a Widget record associated with a System and change it in such a way that the Widget's cost changes. When you save that Widget record, the JavaScript on the "Edit System" page will recalculate the System cost and display it correctly; but the summary row for the System doesn't get updated. Users for the most part didn't care since they saw the correct total on the page. But when a System Report is generated, it uses the values that are stored in the summary row, so it comes out all wrong.

Apparently this is a long-standing issue, and the official workaround from the previous support team had always been: "Make sure you always update the System record after you update a Widget record, and if you see a total that looks wrong, just go in to the System record and hit Update."

Today, though, this irritated the right person just enough to get me assigned to the ticket. My coworker (the only holdover from the old team) continues to insist the old workaround is the best solution; I'm not buying it. I find the method that gets called when a Widget is updated and it looks roughly like this:

Java code:
System system = SystemManager.getSystem(systemId);
Widget widget = processWidgetDataFromUserInput(...);

WidgetManager.updateWidget(widget);

SystemSummaryManager.updateSummary(systemId, system);
So, all along, this code has been doing exactly what it needs to do, just in the wrong freaking order. SystemManager.getSystem(), of course, retrieves the System record(s) from the database, including the summary data and a list of all the Widgets associated with the System. The summary data was getting updated, alright; with stale data. The fix was to literally move the getSystem() call two lines down. Problem solved forever.

Biggest horror?
  • Allowing the problem to even be possible by storing denormalized data
  • Calculating the summary independently in the UI, leading most users to think everything is correct
  • Dumbass developer who hosed up the code in the first place
  • Mentally retarded support staff who couldn't figure out the world's simplest fix
  • Me, for still working here

Adbot
ADBOT LOVES YOU

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

HORATIO HORNBLOWER posted:

Due to downsizing at my work, I have two peoples' jobs now. Half my time is spent on new development and half my time is spent on supporting a horrendous beast of a legacy web application that is considered mission critical for a whole bunch of external customers. This app is huge and an entire book could be written about the horrors that lay within.

One of the things the app does is maintain records about a thing, let's call it a System. Each System has a list of Widgets that are associated with it. Each Widget has a cost, and so the cost of the System is equal to the sum of the costs of the Widgets associated with the system. Pretty straightforward, right? (Calculating the cost of each Widget is fairly complicated but not directly relevant here.)

So, for "performance" the cost of the System isn't directly calculated on demand; when you update a System record, the total cost is calculated and stored in a summary row. Notice I said "when you update a System record." You can update a Widget record associated with a System and change it in such a way that the Widget's cost changes. When you save that Widget record, the JavaScript on the "Edit System" page will recalculate the System cost and display it correctly; but the summary row for the System doesn't get updated. Users for the most part didn't care since they saw the correct total on the page. But when a System Report is generated, it uses the values that are stored in the summary row, so it comes out all wrong.

Apparently this is a long-standing issue, and the official workaround from the previous support team had always been: "Make sure you always update the System record after you update a Widget record, and if you see a total that looks wrong, just go in to the System record and hit Update."

Today, though, this irritated the right person just enough to get me assigned to the ticket. My coworker (the only holdover from the old team) continues to insist the old workaround is the best solution; I'm not buying it. I find the method that gets called when a Widget is updated and it looks roughly like this:

Java code:
System system = SystemManager.getSystem(systemId);
Widget widget = processWidgetDataFromUserInput(...);

WidgetManager.updateWidget(widget);

SystemSummaryManager.updateSummary(systemId, system);
So, all along, this code has been doing exactly what it needs to do, just in the wrong freaking order. SystemManager.getSystem(), of course, retrieves the System record(s) from the database, including the summary data and a list of all the Widgets associated with the System. The summary data was getting updated, alright; with stale data. The fix was to literally move the getSystem() call two lines down. Problem solved forever.

Biggest horror?
  • Allowing the problem to even be possible by storing denormalized data
  • Calculating the summary independently in the UI, leading most users to think everything is correct
  • Dumbass developer who hosed up the code in the first place
  • Mentally retarded support staff who couldn't figure out the world's simplest fix
  • Me, for still working here

Spend two days "fixing" it that you actually spend on making other things with less visibility better.

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