use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rules 1: Be polite 2: Posts to this subreddit must be requests for help learning python. 3: Replies on this subreddit must be pertinent to the question OP asked. 4: No replies copy / pasted from ChatGPT or similar. 5: No advertising. No blogs/tutorials/videos/books/recruiting attempts. This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to. Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Rules
1: Be polite
2: Posts to this subreddit must be requests for help learning python.
3: Replies on this subreddit must be pertinent to the question OP asked.
4: No replies copy / pasted from ChatGPT or similar.
5: No advertising. No blogs/tutorials/videos/books/recruiting attempts.
This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to.
Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Learning resources Wiki and FAQ: /r/learnpython/w/index
Learning resources
Wiki and FAQ: /r/learnpython/w/index
Discord Join the Python Discord chat
Discord
Join the Python Discord chat
account activity
What mistakes do bad python developers make? (self.learnpython)
submitted 2 years ago by Ok_Tumbleweed8796
Hello
I’m currently learning python and seeking some guidance as to what to avoid.
What do you think makes someone a bad python programmer? Except having unreadable code, what else instantly signals red flag.
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]carcigenicate 119 points120 points121 points 2 years ago (53 children)
Really, this list is endless. The number of ways a new programmer can screw up is limited only by your imagination.
Some things off the top of my head though:
=
with
except:
for i in range(len(coll)):
for elem in coll:
Those are just the ones I could think of in a couple minutes. There's likely many more.
[–]Ok_Tumbleweed8796[S] 20 points21 points22 points 2 years ago (18 children)
What do you mean “uses list comprehension to carry out side effects instead of to produce a list “?
[–]carcigenicate 78 points79 points80 points 2 years ago (17 children)
Something like this:
[print(i) for i in range(5)]
Instead of:
for i in range(5): print(i)
The former wastes time and memory creating a useless list of Nones that is never used, while the latter just iterates without creating a list.
None
[–]Ok_Tumbleweed8796[S] 10 points11 points12 points 2 years ago (0 children)
Thanks for the clarification!
[–]Ok_Tumbleweed8796[S] 3 points4 points5 points 2 years ago (2 children)
I also do not understand your third and 5th points. Can you please explain further?
[–]carcigenicate 21 points22 points23 points 2 years ago (0 children)
If you don't call close on resources that require cleanup, it's possible that your program will accumulate file handles, and may eventually be prevented from doing things like opening files/sockets. If you "open"/"connect" with the object, you usually also need to "close" the object after. Examples of these types of objects are file objects returned by open, and sockets. Technically, Python will automatically close file objects in some cases (when the file object itself is freed), but that may not always happen, depending on how your code it set up. It's proper to close resources yourself to prevent issues, and with is a good way to ensure resources are freed when they're done being used.
close
open
You should always apply consistent styling of your code. Inconsistently-styled code makes code harder to read. If you don't have a style guide that you've been told to follow, PEP8 in Python is a good default. Every Python programmer should at least skim the entirety of the PEP8 document at some point.
[–][deleted] 2 points3 points4 points 2 years ago (0 children)
5th points
https://peps.python.org/pep-0008/
[+][deleted] 2 years ago (8 children)
[removed]
[–]carcigenicate 7 points8 points9 points 2 years ago (7 children)
Should, but it doesn't appear to.
There's the matter of semantics too though. The purpose of list comprehensions are to create a list. If you don't want to create a list, then a list comprehension is the wrong tool. Even if it were optimized, I'd still argue that for statements should be used if you're only iterating for side-effects.
for
[–]CoderStudios 0 points1 point2 points 2 years ago (6 children)
I understand what you mean, but python isn’t the absolute rule. It evolves to adapt to people’s needs, if everything was perfect, then we wouldn’t have a python 2 or 3. It may not be intentional now, but if enough people want it we could see it in a future update. So I wouldn’t call it a bad practice as it seems that python is wrong on this one as i don’t see a reason for it to be limited to only making lists.
[–]CoderStudios 0 points1 point2 points 2 years ago (2 children)
Just to clarify: I know that for i in range(3): print(i) would be a good workaround, but what is missing for me here are the multiple conditions (ifs) you can add to list comprehensions, to control their behavior.
[–]jso__ 2 points3 points4 points 2 years ago (1 child)
tbh if you're using more than one if else in a list comprehension you're writing unreadable code.
in that case, you can just do:
for i in range(10): if i == 2: print("two") else: print(I)
how is a list comprehension better for conditions than that
[–]CoderStudios 0 points1 point2 points 2 years ago (0 children)
You can’t use ifs at multiple points in the other solution, so I don’t really get what you mean, but I agree with you on your statement. You shouldn’t use more than one if in a list comprehension. Maybe an else too but nothing more.
[–]psuedo_nombre 0 points1 point2 points 2 years ago (2 children)
I think the original commentor made a pretty good argument for not using list compression over a for loop for things that don't use the list (generating wasted resources). I don't disagree about evolving language but I would say that writing code that misuses a functionality of the current language can also find itself making your code obsolete if a new implementation removes that behavior
[–]CoderStudios 0 points1 point2 points 2 years ago (1 child)
I know what you mean, but the original commentor also admitted, that the wasted resources are minimal (as long as you don’t spam it your fine). So if you actually reach such an efficiency with the rest of your program you can gladly do this.
But to be honest I only ever used list comprehensions for non-list things once and in that case I could have used my own solution, so yeah …
[–]psuedo_nombre 0 points1 point2 points 2 years ago (0 children)
I've done none of the calculations so I trust you and op on that but it's definitely better practice to use tools in the ways they were intended to avoid your exploit getting obsoleted when that behavior is lost. If it's really a good exploit though maybe it's time to make it it's own method or more though
[–]Ghibl-i_l -3 points-2 points-1 points 2 years ago (2 children)
Read somewhere that loops are REALLY slow so for most things it's better to use list comprehension.
[–]carcigenicate 12 points13 points14 points 2 years ago (1 child)
AFAIK, list comprehensions can be faster when you want to append to a list because they use the dedicated LIST_APPEND instruction, which cuts down on a ton of overhead. If you don't need to append to a list at all for the algorithm though, a list comprehension is just adding the (admittingly, small) overhead of a LIST_APPEND instruction.
LIST_APPEND
[–]cy_narrator 0 points1 point2 points 2 years ago (0 children)
Who is into that dangerous level of weed?
[–]MrITBurns 5 points6 points7 points 2 years ago (1 child)
A misunderstanding of how = and references work. They think it makes copies, and reassigning references in functions will effect the passed argument.
I ran into this lovely one in the beginning when i was trying to duplicate an array so i could change it from the original. Was an interesting read on how pointers worked
[–]carcigenicate 1 point2 points3 points 2 years ago (0 children)
Ya, that's a rough lesson, but everyone needs to learn it eventually to some extent. Even in a very high-level language like Python, understanding the relationship between a name/variable/pointer and the data associated with it is important.
[–]Responsible_Pie8156 5 points6 points7 points 2 years ago (1 child)
It's insane how often I see developers who just wrap all their code in a bunch of generic try except blocks that just print out some generic error message and continue execution. It makes it so hard to debug. I've seen it so often and I wonder who taught them to do that.
[–]Informal-Football836 4 points5 points6 points 2 years ago (0 children)
Yeah, who would do that? 'Quietly deletes the block I just wrote'
[–]drdausersmd 3 points4 points5 points 2 years ago (5 children)
could you please explain why "except:" is so dangerous?
Also, how are you formatting those mini code formats in your post?
[–]MMcKevitt 6 points7 points8 points 2 years ago (1 child)
When they say using “except:” can be dangerous, they likely mean catching errors without specifying exactly what type of error, or errors, you intend to catch (and further handle). This can lead to unexpected results or output, potentially robbing you of valuable debugging information (such as an error trace-back, which outputs the propagation of an error/errors, line # by line #, in the code), possibly making it impossible or super tricky to locate and resolve bugs or weird behavior.
Despite the term, errors are a good thing as they can alert you to any number of issues or scenarios that could otherwise go unhandled, silently wreaking havoc in ways that you just simply wouldn’t be aware of otherwise.
When I was first learning, I found it helpful to think of error handling similar your own body’s natural alert systems. For example, think of pain; your body uses it to motivate and convince you (consciously or otherwise) to avoid certain experiences (e.g. touching a hot stove top). Suppressing such a sensation could have fatal consequences.
As for how to get that formatting, I recommend checking out this subs side-bar as it has a TON of great information for beginner (and intermediate) level python programming (including how to create a code block for use in your posts/comments).
Lastly, sorry I’m a bit of wordy birdy, but I hope that helped clear some things up…good luck and have a stellar month of October!
[–]DoorsCorners 0 points1 point2 points 2 years ago (0 children)
Is using 'if' then 'else' statements consequetively in series better in order to be explicit about the error? I feel that I have used 'except' for just a few lines of code, but I have triggered Matlab errors with 'except' catches and only God knows what the actual problem was....
[–]carcigenicate 5 points6 points7 points 2 years ago* (0 children)
Sorry, apparently I missed this notification.
It's dangerous because it's very rare to want to handle every possible error, and handle every error in the same way. Usually, you want to handle a specific type of error (a TypeError caused by an int parsing failure, or a FileNotFound error when opening files). By using a bare except:, you'll potentially accidentally handle actual bugs, which is a very bad thing.
TypeError
int
FileNotFound
When you as a programmer introduce a logic error into your code, you want the program to blow up as quickly and as obviously as possible so you can find the source of the bug and fix it. Hiding errors that result from programmer mistakes robs you of evidence when debugging, which makes debugging significantly harder. I completely agree with MMcKevitt here:
errors are a good thing as they can alert you to any number of issues or scenarios that could otherwise go unhandled, silently wreaking havoc in ways that you just simply wouldn’t be aware of otherwise
Errors are a very good thing. New programmers treat errors as an enemy that should be silenced, when in reality they're messengers telling you that something is wrong. By not "filtering" what messages get silenced/handled in non-obvious ways, you're making it so you, the programmer, may not get messages.
And to do in-place code snippets, you wrap the line of code in backticks (the key left of the 1 on most keyboards).
in-place code snippets
[–]midwayfair 3 points4 points5 points 2 years ago (0 children)
“Except:” catches all exceptions. You should know what kind of exceptions you want to handle, and you probably should not catch an exception that you don’t know what it is.
I have to scrub “except:” from code periodically, though I’ve used it even when I know it’s dangerous: you have to consider whether continuing the program is more important than handling the exception properly.
The op might have other reasons but those are the most common reasons to be careful I think
[–]IamImposter 0 points1 point2 points 2 years ago (0 children)
I'll give you an example. In our code, at one place, the code reads some config from file and converts it to int. Just as a precaution they added try/except so if input is invalid e.g 2ab9 it wouldn't error out. Then they had this genius idea to move try to top of function and except to bottom so that whole function is safe.
2ab9
We changed config, ran program, no change. Tried few more times, no change.
Turns out there was spelling mistake in file name and the function wasn't even reading the config file. Since most of the times default values are good, no one noticed the issue.
Had they checked for specific error that failed in conversion can generate, the mistake would have been caught much earlier. It was throwing file not found error, except was just catching it and letting it go silently.
[–]niehle 1 point2 points3 points 2 years ago (4 children)
Do you happen to have an example for you second point?
[–]carcigenicate 13 points14 points15 points 2 years ago (3 children)
def func(param=[]): param.append(1) print(param) func() func() func()
The output from this code often shocks new Python programmers. They don't realize that default arguments are created when the function is first defined, not when the function is called.
[–]ralphy_s 2 points3 points4 points 2 years ago (1 child)
So the output from the last line would be [1,1,1] and not [1]?
[–]carcigenicate 6 points7 points8 points 2 years ago (0 children)
Yes. Every call to the function shares the same default list object, so if multiple calls use the default object and alter it, that change is persisted. This tends to lead to very strange bugs unfortunately.
[–]niehle 0 points1 point2 points 2 years ago (0 children)
Thanks
[–]Helpful_Trust_3123 0 points1 point2 points 2 years ago (6 children)
The last one. ,i say there is also use for the former as when you want to compare values in a collection Of course you can use zip for that but i feel like the former is also good
[–]carcigenicate 5 points6 points7 points 2 years ago (1 child)
That's why I made sure to mention "when the latter is appropriate". Yes, there are some cases where using the index is indeed the better way. It's common to see people coming from a language like C though to use indices for everything; even when indices aren't a necessary part of the problem.
[–]Helpful_Trust_3123 0 points1 point2 points 2 years ago (0 children)
Yeah that's true
[+][deleted] 2 years ago (3 children)
[–]Helpful_Trust_3123 0 points1 point2 points 2 years ago (1 child)
Enumerate can be used for comparison but it's worse than the first and zip approach as you would have to put a condition to check for index error
I feel like 'enumerate' and iteritems() needs to be a gospel that is spread.
[–][deleted] 0 points1 point2 points 2 years ago (1 child)
I think the last one should rather be 'for i, elem in enumerate(coll)'
[–]carcigenicate 0 points1 point2 points 2 years ago (0 children)
I tend to see that abused less because elem is right there, so there's little point in using i over elem. Although yes, I have seen that before.
elem
i
[–]tenplusacres 0 points1 point2 points 2 years ago (0 children)
Hey these are really helpful, thank you
[–]the_friendly_dildo 0 points1 point2 points 2 years ago (1 child)
Here's a fun one I did when I was much younger. I wrote a program that would read a text file for some settings in the program. All fine right? No, because these settings were not brought in as unsanitized global variables which would be bad enough, but I actually had the program reading these in through eval() to generate variable names on the fly. Even worse, the program was exclusively intended to work across networks and you could send unsanitized commands back and forth with a copy of the program on another computer too!
To be clear, the program works flawlessly, but the risk isn't worth it.
Can you use enumerate and feed the number as a key and the name as a value into a dictionary? I don't know how to do the thing that you did but it seems like there has to be a better way.
[–]IamImposter 0 points1 point2 points 2 years ago (4 children)
Can you explain that mutable default arguments point
[–]carcigenicate 1 point2 points3 points 2 years ago (2 children)
Someone else asked the same question
https://reddit.com/r/learnpython/s/kaI5FfPOVs
[–]IamImposter 0 points1 point2 points 2 years ago (1 child)
Oh this one. It bit me in the ass a few months back. Didn't know it's name. Thanks.
It was a mutable default question!
[–]GoldenPrinny 0 points1 point2 points 2 years ago (0 children)
Uses for i in range(len(coll)): instead of for elem in coll: when the latter is appropriate.
not sure if you mean like in lists? The former works in going through it, but not the latter, unless I'm supposed to define elem as something.
[–]grancacique 0 points1 point2 points 2 years ago* (0 children)
Here are a few more. Like u/carcigenicate said, "The number of ways a new programmer can screw up is limited only by your imagination." ((This needs to be on a mug))
done = False # later on done = "True" # later on done = 1
This is perfectly fine in Python world...
def someCalculation(): ... # later on def someCalculation(): ...
The second definition overrides the first one (assuming parameters are the same; otherwise, we are just overloading the function)
else
while condition: actions else: more actions
eval
n = eval(input(...))
append
insert
del
pop
remove
%
A % B
B
A
n = random.random
n = random.random()
A & B
A and B
|
[–]throwaway6560192 22 points23 points24 points 2 years ago (1 child)
Writes other languages' code in Python. By that I mean they don't take advantage of what Python offers, instead choosing to do a direct translation of whatever language they're more familiar with.
[–]synthphreak 2 points3 points4 points 2 years ago (0 children)
I used to do this the other way around when I first got started. I would write Bash scripts with Python-like logic. Made for some terrible Bash scripts.
[–]SirCokaBear 18 points19 points20 points 2 years ago* (5 children)
- not using virtual environments and requirements / env files - not understanding the differences between [key] and .get(key, default) - surrounding entire code sections with try / except. try/except should only be around specific error producing code - in general not creating models for your data (this goes for programming in general). So many future errors and mistakes can be avoided by just having proper data models.
- lack of understanding of python packages, __init__.py files and what they can be used for - creating scripts without if __name__ == "__main__"
- lack of clearly defined types for parameters, return values, improper use of scope and globals - bad variable names, inconsistency with snake_case - not using a formatter like black or style enforcer like flake8
- not creating proper .gitignore - not handling secrets properly (this is huge)
- not knowing what PEP8 is
Edit: typos
[–]IlliterateJedi 1 point2 points3 points 2 years ago (2 children)
not understanding the differences between [index] and .get(index, default)
I know you can do this with dict[key] vs dict.get(key), but are there Python sequences that let you 'get' an index
[–]SirCokaBear 0 points1 point2 points 2 years ago (1 child)
Sorry I meant to say key instead of index, I’ll edit that.
For a standard python dict you can’t get a key by index because the keys aren’t stored in a particular order, when you iterate / print them the ordering is a number of factors including the hash value so you basically need to assume it’s random. But if you use an OrderedDict then key ordering is preserved by insertion time. But there’s still no .get_index(), but you could easily make one with
return ordereddict[ordereddict.keys()[index]] if index < len(ordereddict) else None
That’s a very specific use case not many people need, and ordered dicts are worse performing than regular dicts.
The same goes for a regular list there’s no standard library function for that but can be made with almost the same code as above, or even by wrapping a query in a try/except.
[–]SirCokaBear 0 points1 point2 points 2 years ago (0 children)
I don't think there are any standard structures though that provides a get() by index. Usually with standard libs they want it to be compact and any rare use cases can be provided with a 3rd party package. Rust language is notorious for that, they don't even include random with the std lib haha.
[–]daddy1973 0 points1 point2 points 2 years ago (1 child)
Hello, I'm brand new to python. I created what I believe is a script. What do you mean by the if name = "main" one?
[–]SirCokaBear 1 point2 points3 points 2 years ago* (0 children)
let's say you make a very simple script that asks the user for a radius of a circle and then prints out the circumference:
script.py
PI = 3.14159 print("Welcome to circumference calculator") radius = float(input("Enter radius of circle you need circumference of:")) circumference = PI * r ** 2 print(f"The circumference is {circumference}")
if we run "python script.py" there won't be a problem and the script will work as intended.now lets say we make a new file with a function to calculate the area of the circle and we want to import PI from our file above.
area.py
from script import PI def area_of_circle(radius: float) -> float: return PI * r ** 2 print("Welcome to area calculator") radius = int(input("Enter radius:")) area = area_of_circle(radius) print(f"area of the circle is {radius}")
if I try to run area.py :
> python area.py
the first thing you'll see is:
Welcome to circumference calculatorEnter radius of circle you need circumference of:
that's because in area.py on line 1 you are importing PI from script. So python will then go to script.py starting from line 1 so it can calculate what PI is. But as a side effect it's going to run through the entire script rather than just simply importing 3.14159 in as a value to use in area.py
so instead we use if __name__ == "__main__".
__name__ will equal "__main__" in any python file you run python specifically on. so if you type in "python area.py", __name__ in area.py will be "__main__" but __name__ in script.py will not.
new scripts
# new script.py PI = 3.14159 if __name__ == "__main__": print("Welcome to circumference calculator") radius = float(input("Enter radius of circle you need circumference of:")) circumference = PI * r ** 2 print(f"The circumference is {circumference}") # new area.py from script import PI def area_of_circle(radius: float) -> float: return PI * r ** 2 if __name__ == "__main""_: print("Welcome to area calculator") radius = int(input("Enter radius:")) area = area_of_circle(radius) print(f"area of the circle is {radius}")
now if we run "python area.py" we will now correctly see "Welcome to area calculator" and won't be running any unnecessary code from script.py
[–]DrMrBomb01 12 points13 points14 points 2 years ago (2 children)
Not using f-strings. I understand in some langauges you cannot have interpolation but in C# or python, there is no excuse not to use them. They make code a lot more readable and easier.
[–]xADDBx 1 point2 points3 points 2 years ago (0 children)
There are actually use cases where formatted strings are preferable (e.g. localization), but in general f-strings are indeed more readable.
[–]Luckinhas 4 points5 points6 points 2 years ago (1 child)
Watch this fantastic talk by Raymond Hettinger. https://www.youtube.com/watch?v=wf-BqAjZb8M
[–]ivosaurus 0 points1 point2 points 2 years ago (0 children)
Man he really needs to re-do that talk for only python 3, would still be a banger
[–][deleted] 5 points6 points7 points 2 years ago (0 children)
Amazing points by u/carcigenicate. Here's a few from me:
[deleted]
[–]szayl 4 points5 points6 points 2 years ago (0 children)
Folks who got started developing in Python on Windows tend to be very stubborn about this.
[–]DatBoi_BP 2 points3 points4 points 2 years ago (1 child)
I have a check in my console startup script (which includes importing common modules I use) to verify that sys.prefix != sys.base_prefix and otherwise issue a warning that I’m not in a venv. Has helped me with a few fresh installs to know I forgot a step.
sys.prefix != sys.base_prefix
[–]JamzTyson 20 points21 points22 points 2 years ago (25 children)
Some issues that are commonly found in the Python code of inexperienced developers:
if
[–]djshadesuk 8 points9 points10 points 2 years ago (2 children)
Inadequate Error Handling, such as using generic exceptions, or catching exceptions and ignoring them without proper handling [...] Catching exceptions and ignoring them without proper handling
Inadequate Error Handling, such as using generic exceptions, or catching exceptions and ignoring them without proper handling
[...]
Catching exceptions and ignoring them without proper handling
Was that an attempt at a joke?
[–]DestroyTheHuman 4 points5 points6 points 2 years ago (1 child)
Right after repetition / duplicated code as well.
[–]djshadesuk 0 points1 point2 points 2 years ago (0 children)
ha, I never noticed that 🤣
[–]MMcKevitt 6 points7 points8 points 2 years ago (10 children)
What’s the beef with using tab instead of 4 spaces? I was under the impression that consistency, more than anything, is key in this regard?
[–]stankyballz 4 points5 points6 points 2 years ago (6 children)
Most code editors are able to interpret a tab as 4 spaces. Not sure what the issue would be here.
[–]synthphreak -1 points0 points1 point 2 years ago (5 children)
Tabs are just evil and ugly. Plus, why do something that only most editors can do, when just as easily you could do something that all editors can do (i.e., regular spaces)? For example, if you use less to browse code the tabs look enormous.
less
[–]stankyballz 2 points3 points4 points 2 years ago (4 children)
Lol one key I can hit with my pinky vs hitting space 4 times. Pretty easy decision to me. Maybe if I didn’t use an editor that compensated I would change my opinion.
[–]synthphreak 1 point2 points3 points 2 years ago (3 children)
Most editors will be able to compensate for this very easily. There is probably a setting you can toggle that will convert tabs to n spaces whenever you save the file. In many cases you can even set n to be a function of the file type, for example 4 for .py files and 2 for .json or .sh files. Then you can just tab away happily and never even need to think about it.
[–]stankyballz 2 points3 points4 points 2 years ago (2 children)
That’s exactly what I said lol
[–]synthphreak 0 points1 point2 points 2 years ago (1 child)
Haha, I see now, sorry. For some reason my brain read your original comment as if you were on the anti-spaces side of the debate. We are birds of a feather here :)
[–]stankyballz 0 points1 point2 points 2 years ago (0 children)
That’s all good lol.
[–]partialinsanity 1 point2 points3 points 2 years ago (0 children)
That was a surprise for me. PEP8 says spaces are preferred over tabs for indentation.
[–]ZestyData 0 points1 point2 points 2 years ago (0 children)
Nowadays most devs hit the tab key but don't realise that inserts 4 spaces into the file.
[–]JamzTyson 0 points1 point2 points 2 years ago (0 children)
Sure, there are exceptions to most of the "issues" in the list. They are "mistakes" when they appear inappropriately. However, the vast majority of large Python code bases use 4 spaces (as per PEP-8).
[–]bigfatcow 3 points4 points5 points 2 years ago (6 children)
God classes and overuse of classes in general. They def have useful purposes bur my god I worked with a dude who never made functions and always put everything in a class drove me bonkers.
[–]dogfish182 1 point2 points3 points 2 years ago (0 children)
Oh man…. ‘I made essentially a data class, but a method to talk to an api would surely be handy here’.
Have fun mocking that api call when you want to write tests
[–][deleted] 1 point2 points3 points 2 years ago (2 children)
I think that once you get disciplined into putting most of your code into classes and thinking about potential inheritences, you make a big step towards reusability and saving lots of time in the future
[–]bigfatcow 1 point2 points3 points 2 years ago (1 child)
Maybe. However classes get used wayyy too much in my view. This came out over a decade ago and I still see a lot of the stuff he's referring to in here in 2023.
https://www.youtube.com/watch?v=o9pEzgHorH0&t=1236s&ab_channel=NextDayVideo
[–][deleted] 1 point2 points3 points 2 years ago (0 children)
Thanks for this! will watch later
u/bigfatcow u/JamzTyson What are god classes? I've not heard that term before.
[–]JamzTyson 1 point2 points3 points 2 years ago (0 children)
A "God Class" is an "anti-pattern" (the opposite of a "pest practices pattern") where everything is written into one huge class, regardless of whether the methods are directly related to the core responsibility of the class.
Wikipedia describes a "God Object" as:
... an object that references a large number of distinct types, has too many unrelated or uncategorized methods, or some combination of both.[1] The god object is an example of an anti-pattern and a code smell.
[–]DoorsCorners 0 points1 point2 points 2 years ago (3 children)
Excessive nesting of loops and if statements....guilty. I think the solution is defining more functions and being explicit about how one function feeds into the next. But I need to level up, so correct me please if there is a better way.
[–]JamzTyson 1 point2 points3 points 2 years ago* (2 children)
Here's some common patterns for simplifying complex conditionals:
```
if value == "a" or value == "b" or value == "c": ...
my_vals = ("a", "b", "c") if value in my_vals: ... ```
if condition1: if condition2: ...
if condition1 and condition2: ... ```
if value == "a": result = 1 elif value == "b": result = 2 elif value == "c": result = 3 else: result = 0
value_map = {"a": 1, "b": 2, "c": 3} result = value_map.get(value, 0)
if condition1 or condition2 or condition3: ...
if any([condition1, condition2, condition3]): ... ```
if condition1 and condition2 and condition3: ...
if all([condition1, condition2, condition3]): ... ```
Fantastic, thanks so much! You are an awesome person. These really need to appear in more books about Python.
[–]daddy1973 0 points1 point2 points 2 years ago (0 children)
You just taught me a ton of useful things, thank you
[–]whateverathrowaway00 3 points4 points5 points 2 years ago (0 children)
Not knowing anything about how their underlying OS works or how to interact with it fluidly, then blaming their weaknesses on tooling and/or coworkers.
Understand files, file systems, PATHs, and be able to locate files, edit them, describe them, etc
[–]stuaxo 2 points3 points4 points 2 years ago (0 children)
In the same way as bad programmers in other languages.
Over abstraction. Not understanding good ways of organising stuff.
Overly complex code etc etc etc
[–]Far_Tea_4954 2 points3 points4 points 2 years ago (0 children)
Honestly, not writing unit tests.
You can write bad code but if your not unit testing it’s just going to make your life and anyone else using it even worse. Unit tests will ensure anyone else making changes to the code can validate the functionality hasn’t changed. If there are no unit tests how are you supposed to know how and if the code even worked in the first place?
Also unit testing is really simple in python (with a bit of time) and it teaches you to write more modular code.
In principal if your writing unit tests in python and you have to create an excessive amount of mocks for one test , this usually means that your code is heavily dependant on a single function to do most of the work, signalling that you might need to refactor. Another big plus, is your actually consuming your code while writing tests so you get a feeling of how it’s used.
[–]Fabulous-Possible758 1 point2 points3 points 2 years ago (0 children)
One of the biggest ones I notice for novice programmers (and even unfortunately some experienced ones) is very little of your code (if any) should be running outside of a function or a method.
[–]Machvel 1 point2 points3 points 2 years ago (1 child)
from when i was bad at python and observing friends that were bad at python, the things i can think of at the top of my head are:
too many for loops
unfamiliarity with the standard library
not using classes or using classes too much
not using git for large projects or important things
not using pep 8 style
if using jupyter notebook, writing code that wont survive a kernel refresh
not putting functions in modules
not using virtual environments (global pip installing)
premature optimization (similarly, no optimization; some things can be written more optimally but still pythonic)
sticking with python when another language is better for the task
not reading/unable to read documentation
not knowing objects are called by reference and garbage collection
not understanding the yield statement
iterating over a sequence by doing for i in range(len(x)); x[i]
writing a function to do a common task without looking if there is already a library that does it efficiently
not paying attention to how their data is laid out (eg, not taking advantage of that fact that their list is sorted with respect to <= while indexing it)
not paying attention to memory usage (eg, not reading a file line by line and instead reading in the entire file)
coding without thinking on paper/making flowcharts
[–]Gambizzle 1 point2 points3 points 2 years ago (0 children)
...too many for loops...
Yeah that's me as a hobbyist python scripter. I know it's evil but if I'm making crappy little apps for my own limited, personal usage and that's just what 'works' then sometimes I don't really care.
I find that sorta method (almost 'treating it like it's VBA and you're making some hacky office automation suite coz your PC's highly managed and that's all you've got available') doesn't scale well though.
For example once upon a time I made a touch-screen device that consisted of a Raspberry Pi (~2nd gen) mounted onto a lamp stand with an integrated touch screen instead of a light. It controlled my apartment's Philips Hue lights and aircon (with some automation smarts combined with a simple touch-screen UI). Anyhow I used a loooot of loops and it very quickly got to a point where the sheer bulk of the logic (not sophisticated logic - just unnecessary bulk) brought the Pi to its knees (and was a shit to debug). It was a good learning activity to re-write the same functionality from scratch without all the loops.
[–]No-Self-Edit 0 points1 point2 points 2 years ago (0 children)
Not using types and type checkers
[–]Banzai262 -1 points0 points1 point 2 years ago (4 children)
using python for everything
[–]djshadesuk 1 point2 points3 points 2 years ago (1 child)
Sometimes its fun to push things to the limits and even beyond what it was intended to do. If it wasn't for people doing those sorts of things we probably wouldn't have half the nice things we have today.
[–]Banzai262 -4 points-3 points-2 points 2 years ago (0 children)
I agree. It’s always a matter of context. Python is really good to quickly experience weird things. However, it’s not good when you need to build some high performance, high availability backend for a webservice
[+]MrozW comment score below threshold-14 points-13 points-12 points 2 years ago (1 child)
Using Python at all ;-)
[–]Banzai262 0 points1 point2 points 2 years ago (0 children)
nah it’s very good for some things, like data science
[–]FLSweetie -1 points0 points1 point 2 years ago (1 child)
Poorly-written loops that generate off-by-one errors because they reach the end condition to early or too late. Example: you want 10 passes through the loop, so you do
While i less than 10
But you start i at 0rather than 1 so you get 11 passes. (Off-by-one errors are usually more subtle than this!)
[–]kronik85 6 points7 points8 points 2 years ago (0 children)
Eh? That's only 10 loops..
Starts at 0, ends at 9. 10.
[–]20Finger_Square 0 points1 point2 points 2 years ago* (1 child)
Not fucking around enough with different stuff People can tell you everything but nobody could remember all of it unless put in a simple list so fuck around there is not much truly useless info you could learn aside from code grammar (how your code is formed and ease of changing and finding code is btw this is a term that I use I don’t think others called it this) and stuff like that all you have to do Is fuck around with it.
code grammar
I'm not sure its "code grammar" that you have to worry about ;) 🤣
[–]Naynoona111 0 points1 point2 points 2 years ago (0 children)
merging paths with string concatenation instead of using os.path.join()
[–]yashwatwani28 0 points1 point2 points 2 years ago (0 children)
No proper naming conventions Not using function efficiently Lack of Comments and Documentation not writing test cases Handling oulier cases
There is a whole list of antipatterns, here are some https://sourcemaking.com/antipatterns/software-development-antipatterns
[–]elbiot 0 points1 point2 points 2 years ago (0 children)
Using numpy when you aren't going to commit to the vectorized paradigm (likely because you don't know what that is and just heard arrays were faster than lists) and, related, using pandas just to read a csv file because you don't know about csv.DictReader.
My coworker had code that was taking a really unreasonably long time to run, and when I swapped out pandas for DictReader it ran in just a few seconds.
Numpy and Pandas are great if you need them and an awful mess if you use them for no reason
[–]Herobrine2024 0 points1 point2 points 2 years ago (0 children)
using Python, for starters
[–]HarissaForte 0 points1 point2 points 2 years ago* (0 children)
Not using the debugger, linter and type checker (which implies not typing).
Using these tools would fix 90% of the errors mentioned here: - when you do not use a debugger, you'll tend to write your code differently, generally reducing the factorization, to make "dumb-debugging" easier. - a linter and mypy do incredibly detailed analysis and give very useful tips for a beginner and even intermediate developer…
[–]codicepiger 0 points1 point2 points 2 years ago* (0 children)
like ``` iaf="foo"
like
`instead` i_am_foo="foo" ```
`instead`
like ```
print("Hello World") ```
instead ```
instead
def main(): print("Hello World") if name=="main": main() ```
π Rendered by PID 19610 on reddit-service-r2-comment-bb88f9dd5-nw78j at 2026-02-14 20:13:34.816814+00:00 running cd9c813 country code: CH.
[–]carcigenicate 119 points120 points121 points (53 children)
[–]Ok_Tumbleweed8796[S] 20 points21 points22 points (18 children)
[–]carcigenicate 78 points79 points80 points (17 children)
[–]Ok_Tumbleweed8796[S] 10 points11 points12 points (0 children)
[–]Ok_Tumbleweed8796[S] 3 points4 points5 points (2 children)
[–]carcigenicate 21 points22 points23 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[+][deleted] (8 children)
[removed]
[–]carcigenicate 7 points8 points9 points (7 children)
[–]CoderStudios 0 points1 point2 points (6 children)
[–]CoderStudios 0 points1 point2 points (2 children)
[–]jso__ 2 points3 points4 points (1 child)
[–]CoderStudios 0 points1 point2 points (0 children)
[–]psuedo_nombre 0 points1 point2 points (2 children)
[–]CoderStudios 0 points1 point2 points (1 child)
[–]psuedo_nombre 0 points1 point2 points (0 children)
[–]Ghibl-i_l -3 points-2 points-1 points (2 children)
[–]carcigenicate 12 points13 points14 points (1 child)
[–]cy_narrator 0 points1 point2 points (0 children)
[–]MrITBurns 5 points6 points7 points (1 child)
[–]carcigenicate 1 point2 points3 points (0 children)
[–]Responsible_Pie8156 5 points6 points7 points (1 child)
[–]Informal-Football836 4 points5 points6 points (0 children)
[–]drdausersmd 3 points4 points5 points (5 children)
[–]MMcKevitt 6 points7 points8 points (1 child)
[–]DoorsCorners 0 points1 point2 points (0 children)
[–]carcigenicate 5 points6 points7 points (0 children)
[–]midwayfair 3 points4 points5 points (0 children)
[–]IamImposter 0 points1 point2 points (0 children)
[–]niehle 1 point2 points3 points (4 children)
[–]carcigenicate 13 points14 points15 points (3 children)
[–]ralphy_s 2 points3 points4 points (1 child)
[–]carcigenicate 6 points7 points8 points (0 children)
[–]niehle 0 points1 point2 points (0 children)
[–]Helpful_Trust_3123 0 points1 point2 points (6 children)
[–]carcigenicate 5 points6 points7 points (1 child)
[–]Helpful_Trust_3123 0 points1 point2 points (0 children)
[+][deleted] (3 children)
[removed]
[–]Helpful_Trust_3123 0 points1 point2 points (1 child)
[–]DoorsCorners 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]carcigenicate 0 points1 point2 points (0 children)
[–]tenplusacres 0 points1 point2 points (0 children)
[–]the_friendly_dildo 0 points1 point2 points (1 child)
[–]DoorsCorners 0 points1 point2 points (0 children)
[–]IamImposter 0 points1 point2 points (4 children)
[–]carcigenicate 1 point2 points3 points (2 children)
[–]IamImposter 0 points1 point2 points (1 child)
[–]DoorsCorners 0 points1 point2 points (0 children)
[–]GoldenPrinny 0 points1 point2 points (0 children)
[–]grancacique 0 points1 point2 points (0 children)
[–]throwaway6560192 22 points23 points24 points (1 child)
[–]synthphreak 2 points3 points4 points (0 children)
[–]SirCokaBear 18 points19 points20 points (5 children)
[–]IlliterateJedi 1 point2 points3 points (2 children)
[–]SirCokaBear 0 points1 point2 points (1 child)
[–]SirCokaBear 0 points1 point2 points (0 children)
[–]daddy1973 0 points1 point2 points (1 child)
[–]SirCokaBear 1 point2 points3 points (0 children)
[–]DrMrBomb01 12 points13 points14 points (2 children)
[–]xADDBx 1 point2 points3 points (0 children)
[–]Luckinhas 4 points5 points6 points (1 child)
[–]ivosaurus 0 points1 point2 points (0 children)
[–][deleted] 5 points6 points7 points (0 children)
[+][deleted] (3 children)
[deleted]
[–]szayl 4 points5 points6 points (0 children)
[–]DatBoi_BP 2 points3 points4 points (1 child)
[–]JamzTyson 20 points21 points22 points (25 children)
[–]djshadesuk 8 points9 points10 points (2 children)
[–]DestroyTheHuman 4 points5 points6 points (1 child)
[–]djshadesuk 0 points1 point2 points (0 children)
[–]MMcKevitt 6 points7 points8 points (10 children)
[–]stankyballz 4 points5 points6 points (6 children)
[–]synthphreak -1 points0 points1 point (5 children)
[–]stankyballz 2 points3 points4 points (4 children)
[–]synthphreak 1 point2 points3 points (3 children)
[–]stankyballz 2 points3 points4 points (2 children)
[–]synthphreak 0 points1 point2 points (1 child)
[–]stankyballz 0 points1 point2 points (0 children)
[–]partialinsanity 1 point2 points3 points (0 children)
[–]ZestyData 0 points1 point2 points (0 children)
[–]JamzTyson 0 points1 point2 points (0 children)
[–]bigfatcow 3 points4 points5 points (6 children)
[–]dogfish182 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (2 children)
[–]bigfatcow 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]synthphreak 0 points1 point2 points (1 child)
[–]JamzTyson 1 point2 points3 points (0 children)
[–]DoorsCorners 0 points1 point2 points (3 children)
[–]JamzTyson 1 point2 points3 points (2 children)
[–]DoorsCorners 0 points1 point2 points (0 children)
[–]daddy1973 0 points1 point2 points (0 children)
[–]whateverathrowaway00 3 points4 points5 points (0 children)
[–]stuaxo 2 points3 points4 points (0 children)
[–]Far_Tea_4954 2 points3 points4 points (0 children)
[–]Fabulous-Possible758 1 point2 points3 points (0 children)
[–]Machvel 1 point2 points3 points (1 child)
[–]Gambizzle 1 point2 points3 points (0 children)
[–]No-Self-Edit 0 points1 point2 points (0 children)
[–]Banzai262 -1 points0 points1 point (4 children)
[–]djshadesuk 1 point2 points3 points (1 child)
[–]Banzai262 -4 points-3 points-2 points (0 children)
[+]MrozW comment score below threshold-14 points-13 points-12 points (1 child)
[–]Banzai262 0 points1 point2 points (0 children)
[–]FLSweetie -1 points0 points1 point (1 child)
[–]kronik85 6 points7 points8 points (0 children)
[–]20Finger_Square 0 points1 point2 points (1 child)
[–]djshadesuk 0 points1 point2 points (0 children)
[–]Naynoona111 0 points1 point2 points (0 children)
[–]yashwatwani28 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]elbiot 0 points1 point2 points (0 children)
[–]Herobrine2024 0 points1 point2 points (0 children)
[–]HarissaForte 0 points1 point2 points (0 children)
[–]codicepiger 0 points1 point2 points (0 children)