59

I was skimming the latest SO blog post, when I quickly noticed a rather obvious typo in the table of numeric built-ins:

enter image description here

comlex should be complex!

I wouldn't normally take much notice of a typo, but as this in a rather exalted position (and in large font)... ;)


The Car class example also has a lot of problems:

  • Uses Class instead of class
  • Has incorrect indentation
  • Uses invalid quotes and instead of '
  • Uses = for comparison instead of ==
  • Doesn't have colons at the end of if-statements or method headers

Compare the current, incorrect version—

Class Car:
    def __init__(self, year, make, model, color)
        self.year = year
        self.make = make
        self.model = model
        self.color = color

    def __bool__(self)
if self.color = ‘red’ or self.color = ‘black’ 
    return True
return False

with the corrected version—

class Car:
    def __init__(self, year, make, model, color):
        self.year = year
        self.make = make
        self.model = model
        self.color = color

    def __bool__(self):
        if self.color == 'red' or self.color == 'black': 
            return True
        return False
16
  • 6
    Also, the code seems to be missing colons and have incorrect indentation and syntax highlighting Commented Apr 27, 2022 at 16:01
  • 2
    The Car class example has a million problems. Look at the of this question
    – user17242583
    Commented Apr 27, 2022 at 16:06
  • 26
    I'm wondering if there is a community or website where they can ask for a bit of proof-reading before publishing. I guess they don't have a reddit account ...
    – rene
    Commented Apr 27, 2022 at 17:26
  • 15
    The title of this question doesn't do the blog post justice. The typo is the least of the problems. Commented Apr 27, 2022 at 17:32
  • 23
    @richardec - I'm afraid any suitable title would violate the Code of Conduct. Commented Apr 27, 2022 at 17:43
  • 2
    At the bottom of the blog pot, it says "[Note: code operation was verified using the ExtendsClass Python checker.]" -- ?
    – user17242583
    Commented Apr 27, 2022 at 19:15
  • 11
    After the ES6 blog post I decided I did not want to see information about the blog any more. I've blocked the top blog announcements from the side bar and I'm not at all tempted to unblock it given what I see here.
    – VLAZ
    Commented Apr 27, 2022 at 19:28
  • 9
    I thought all those examples using if condition: return True ... return False instead of return condition were ... unfortunate. But then I saw that for loop at the end, with the locals() stuff. Yikes!
    – PM 2Ring
    Commented Apr 27, 2022 at 22:19
  • 23
    feature-request: shut down the blog. They hardly do anything but spew out trash these days anyway Commented Apr 27, 2022 at 23:52
  • 15
    @ZoestandswithUkraine I've been calling the blog "the spamblog" for years, for obvious reasons. This also has an advert at the end. Ironically it's supposed to advertise that "code operation was verified" with it. Not the best marketing if you ask me. Commented Apr 28, 2022 at 10:49
  • 4
    The article is immortalised here: web.archive.org/web/20220427140829/https://stackoverflow.blog/…
    – Rob Grant
    Commented Apr 28, 2022 at 11:05
  • 3
    @AndrasDeak--СлаваУкраїні It seems like great advertising to me. Thanks to that fantastic ad, I now know what tool not to use Commented Apr 28, 2022 at 12:19
  • 8
    If the blog's editor had any integrity at all (assuming they aren't asleep) this post should have been withdrawn until corrected. It's so bad it could be used as an example of the kind of misinformation SO was formed to try and avoid.
    – holdenweb
    Commented Apr 28, 2022 at 13:03
  • 10
    Oh look, the author is the same as that of the ES6 post.
    – dumbass
    Commented Apr 28, 2022 at 13:24
  • 7
    Hey, at least the post doesn't recommend using numpy for functionality that can be implemented in two lines of pure python. But yeah, the blog is a collection of at best questionable articles - crap like this is practically expected at this point, I'd consider it more noteworthy if they somehow published a great article.
    – l4mpi
    Commented Apr 28, 2022 at 14:17

3 Answers 3

30

Editor of the blog here. I appreciate the corrections and feedback, and I've tried to fix the article where I can in order to remove the inaccuracies. If you have other specific feedback on it, including edits to make to the code, I'd appreciate those as well. I rely on my writers to produce good code examples, so when bad code goes out I try to fix it as soon as possible.

As some have pointed out, this isn't the first article from this writer that has had problems. As such, I'm no longer publishing his work, as these sorts of consistent errors are not acceptable to me.

For much of the blog's articles, I'm dependent on outside contributors pitching articles that may be interesting to the Stack Overflow community. If you are unhappy with the quality of work on the blog, I encourage you to send me pitches for articles (pitches at stackoverflow dot com). Guidelines are here: https://stackoverflow.blog/2020/01/27/blog-contributor-guidelines/

10
  • 15
    Thank you for the reply and consideration! Naturally, we cannot blame the editor for mistakes made by the original author (except in the case of a technical article, where there is a formal, technical peer-review process). Being responsive to fixing things like typos is, of course, appreciated, as is your decision not to publish future submissions from the author. I would, however, like to suggest that you add some sort of disclaimer to the article that connects it to the community criticism. I tried to add a comment along those lines, but it either hasn't been reviewed yet or was rejected.
    – Cody Gray Mod
    Commented Apr 28, 2022 at 20:07
  • 8
    Thanks for posting this, and for taking our technical feedback at face value. It's much appreciated. Do you think there could be some mechanism in the future for unfeaturing such posts with questionable quality? Commented Apr 28, 2022 at 20:07
  • 2
    @CodyGray Someone posted a link to this meta discussion in the comments of the blog post. I try to approve comments that are offering constructive criticisms (and I just approved yours). If you want additional caveats or criticisms in the comments, feel free to post them, but keep it civil.
    – Ryan Donovan Staff
    Commented Apr 28, 2022 at 20:55
  • 3
    @AndrasDeak--СлаваУкраїні I don't plan on un-featuring or deleting these posts; while I try to ensure that posts have good and accurate content, I don't think removing the post is the right call. Many of the posts that get called out for technical inaccuracies draw a good amount of attention, so I'd rather update those posts to make them more accurate instead.
    – Ryan Donovan Staff
    Commented Apr 28, 2022 at 20:55
  • 11
    That's fair, but there is also the responsibility of the blog not to disseminate anti-patterns and falsehoods. I wouldn't want the post to be deleted, but I would consider toning down its visibility for the insane amount of traffic that goes through Stack Overflow. The amount of mistakes in the post, many of them fundamental to the post itself (e.g. variable variables at the end), put the post on par with sites like geeksforgeeks which are an endless source of crap code. This is bad for Stack Overflow (the Q&A platform) and bad for people trying to learn to program in general. Commented Apr 28, 2022 at 20:59
  • 1
    A good portion of the issues have been fixed, yet some still remain (eg. variable-variables, improper usage of __bool__, invalid syntax in sequence examples). Commented Apr 29, 2022 at 5:10
  • 3
    Also, it looks like a paid article, there are at least two dubious links that are part of phrases that don't fit very well within their context.
    – Cristik
    Commented Apr 29, 2022 at 6:25
  • 1
    If you find further inaccuracies or syntactical mistakes, can you send them to [email protected]? The more specific the change you suggest, the better.
    – Ryan Donovan Staff
    Commented Apr 29, 2022 at 17:07
  • @SuperStormer see above comment ^ by Ryan. Commented Apr 30, 2022 at 9:28
  • 1
    @RyanDonovan there are also some concerns with the most recent blogpost: Almost none of the JSON in the blog about JSON is JSON
    – Luuklag
    Commented Jun 2, 2022 at 17:31
45

This article has a host of other issues aside from these two. Here's a list of some that I wanted to point out. Bold is mine for emphasis.

All data in Python resides in objects. And all Python objects have a type with associated attributes and methods. But because Python uses dynamic typing to allow flexibility, it doesn’t always know the type of a given object. So functions you think should exist as members of an object when you instantiate may very well not.

Python always knows the type of a given object - method calls work by looking up the function on the class.

Fortunately, you can ensure that you have the right functions for your classes and objects when you define them using something known as dunder methods or magic methods. You can quickly recognize these operations by the double underscore or “dunder” format: __methodname__().

Dunders are used to implement special functionality for a class (eg. constructors, operator overloading, etc), completely unrelated to ensuring that an object has a method that you're attempting to call.

Python object types have several characteristics. First, they may be single value object types (e.g., numbers or characters) or container/collection object types (e.g., lists and arrays).

Assuming they're referring to built-in types, in which case they omitted functions, classes and iterators. Characters and arrays are also not builtin types.

Type Description Example Constructor
List The broadest category of sequence data types includes several subtypes:Lists are mutable (i.e. modifiable) sequences, normally of similar or homogeneous items Tuples are immutable (i.e. they cannot change state or content) sequences, particularly useful for different or heterogeneous items Ranges are immutable sequences of numbers, most often used for managing loops List: a, b, c, d, e Tuple: 3, red, [corvettes, porsches] Range: 0 (start value), 100 (stop value), 10 (iterative step) list() tuple() range()
Text A text-specific sequence type, this type encompasses sequences of Unicode characters. Hello world str()
Binary Python has three different binary-specific sequence data types:Bytes are immutable sequences of single bytes.Byte arrays are the mutable version of bytes.memoryview objects allow Python to access and manipulate the content of a byte-type object without first copying it. These types allow the manipulation of binary objects and the conversion of string data to binary for machine storage. Byte: 244 Bytearray: [2, 4, 6, 8] Memoryview: 64 or [10, 20, 30] b’123’b’abc’b’\x20\xC2\xA9’ byte() bytearray() memoryview()

None of these examples are valid syntax. Especially egregious are byte, bytearray and memoryview - the provided examples are integers and lists.

One of the more widely used functions for sequence data is len(), which returns the length of an item. Attempting to use the built-in len() function on a custom class returns an attribute error. However, by implementing the __len__ dunder in your class, you can replicate built-in functionality. The same is true for other common, useful sequence functions like get_item(), set_item(), and more. You can then use these objects anywhere you would a native sequence type without changing code.

len() returns the length of the entire sequence. get_item() and set_item() don't exist.

Let’s look at a very simplified example of using __bool__. Say you have a class for cars that contains certain attributes like the year, make, model, and color. You know that while you are going to store data about a wide range of cars, most of your operations will involve only red or black cars. You can use __bool__ in defining the class to return true only for red or blue cars:

Redefining __bool_ for a one-off usecase doesn't make sense. The code also doesn't match the bolded description.

Examples of sets include [5, 10, 15, 20] and [5, 10, “Hello”, “World”].

Those are lists.

Frozen sets, on the other hand, are useful as dictionary keys. Frozen sets can only have a single value, but that value can be almost anything, including a list or a set.

Frozen sets are just sets, but immutable. I can't see how that can be described as "only have a single value".

There are many more advanced data types in Python, including classes, instances, and exceptions. But as we will see, classes and instances do not necessarily come along with the same dunder methods as other data types.

"instances" are not a data type. This paragraph is also duplicated (and this is also a strange spot in the article to put it).

The most well-known dunder methods in Python are __new__() and __init__(), which create a class instance and initialize its state, respectively. Most python programmers focus overrides on __init__ so that changes take place on instantiation of a new object, while __new__ typically only creates subclasses of immutable data types. The syntax for the init method is __init__(self, char1, char 2,...).

__new__ is definitely not well-known, as it is rarely needed. The __init__ example syntax is also invalid.

Python does not know what type the object btc_wallet is. So many standard operations are not available to use with it, and if we try to do so, we will get an error message. But now, let’s look at how we would use dunder methods to add functionality to our btc_wallet object type.

Presumably that should be btcwallet1. In any case, "Python always knows the type of a given object".

If you want to determine how much total bitcoin you have in your first two wallets it would be tempting to write:

total_btc = btcwallet1.amount + btcwallet2.amount

This code works - not sure why the article is implying that it doesn't.

But if you use the dir() function on btc_wallet, you would see that __add__ is not present. So we need to modify the class definition with a dunder method:

But you're not adding 2 btc_wallets, you're adding 2 integers (that are attributes of btc_wallet).

def __add__(self, other):
   return self.amount + other.amount

If you wanted to add the balances of the 2 wallets, it's better to spell it out explicitly instead of using __add__.

Now, what if we want to total only our wallets that have three or more BTC? We could use a standard if loop, checking the amount for each wallet and including only the ones where btcwallet.amount > 3. But we could also return to our discussion about Booleans above. You can define btcwallet so that it is only true if the amount is greater than three by adding the following to the class definition:

"if loops" don't exist. Also, "redefining __bool__ for a one-off usecase makes no sense".

Now you can set up the loop to calculate the total of your wallets:

total_btc = 0

for x in range (0,3):
loopname = locals()['btcwallet' + (str(x+1))]
if bool(loopname):
          total_btc = total_btc + loopname.amount

Using locals() for variable-variables is very bad practice. Indentation is also invalid.

Half the single quotes in the article are also smart quotes (including within code blocks), and sevaral of the code snippets could be written in much more idiomatic Python (after the syntax errors are fixed, of course).

Even ignoring the factual, stylistic and syntax errors, the article honestly doesn't seem particularly well-written in the first place (as is usual for the blog).

4
  • 14
    Thanks, I was considering writing a similar post, good to see it's already here. Commented Apr 28, 2022 at 10:48
  • 20
    Some additional things: 1. indentation is all over the place (even if mostly technically correct): 4 spaces, 8 spaces, in one place 16 spaces, 2. if bool(whatever): is always redundantly wrong, 3. posting crap like that on something officially "stackoverflow" won't help one bit in teaching people how to write good, nay, decent code. It's just a mess. Commented Apr 28, 2022 at 10:54
  • "Fortunately, you can ensure that you have the right functions for your classes and objects when you define them using something known as dunder methods or magic methods." For example def __getitem__(self, i): in class MyClass, so that MyClass()[5] is defined. That's what I understand, at least. And thanks for your post. I LOLed while reading the original article, with a car being truthy if it's red or black. Commented Apr 30, 2022 at 9:06
  • 1
    Good god. The errata is almost as long as the article itself...
    – Gimby
    Commented May 4, 2022 at 13:41
10

Other than the things that already have been mentioned, I suppose it cannot be called an ‘error’ as such, but I find the choice of example to demonstrate the discussed language feature rather distasteful.

total_btc = 0
    
for x in range (0,3):
    loopname = locals()['btcwallet' + (str(x+1))]
    if bool(loopname):
          total_btc = total_btc + loopname.amount

The output will now be “I have a total of 30 BTC in my wallets (lucky me!)”. And you are indeed lucky as this is approximately $1.2 million.

The criticisms of cryptocurrencies are rather well-known: environmental impact of mining, by-design deflationary economy turning them into speculative vehicles, lack of tangible practical applications, rampant scams and pump-and-dump schemes, and I am not even getting into the explicitly political criticisms. To blithely peddle them in passing here as something positive I find rather tone-deaf at best.

But this is unfortunately not the first time where The Overflow shills for cryptocurrency, so I don’t expect much to be done about it.

1
  • 8
    But, you see, they're trendy!
    – Cody Gray Mod
    Commented Apr 29, 2022 at 10:08

You must log in to answer this question.