Tips to break bad coding habits?

Discussion in 'Mac Programming' started by MorphingDragon, Jul 9, 2010.

  1. MorphingDragon macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #1
    The title is self explanatory, but I don't notice what I'm doing until I get somebody else to point it out.

    My Biggies:

    Procedural C++/C# (Awesome use of the technology :rolleyes:)
    GOTO/Class() (Something I just can't shake form my Visual Basic 6 days)
     
  2. wjlafrance macrumors 6502

    Joined:
    Dec 23, 2009
    Location:
    Madison, WI
    #3
    Since I've started writing code in college, one instructor always reminds me that if I can't see the opening and closing of my function on my 13" MacBook, I'm not modularizing correctly. I guess this falls in with procedural Objective-C.

    EDIT -
    If you ever feel you're not progressing in your programming skills, look at the code you wrote two weeks ago. It'll crack you up.
     
  3. MorphingDragon thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #4
    Oh God, I haven't worked on that card game engine past text based games. Work's servers decided to catch fire, so i spent all my holidays implementing the new IT infrastructure 6 months early (RedHat style). Though now I can afford a new iMac and an iPhone 4. :D
     
  4. mdatwood macrumors 6502a

    Joined:
    Mar 14, 2010
    Location:
    Denver, CO
    #5
    Refactor.

    Maintenance is the largest part of software, so that means you'll be going back into the same code more often than when you first wrote it. Every time you dive back in take what you know now and improve the code.

    If you're writing procedural code instead of OO code when you want to be writing OO then by the time you are coding it already too late. You need to step back to the design stages and rework from there. You need to learn to think in an OO manner. Get the GofF book and refresh yourself on patterns and then start thinking of them on your own. Think re-usable parts and self contained functionality.

    Coding errors like GOTO, etc... are simply discipline. Unless you're writing vbs GOTO should not be part of your coding vocabulary. Of course there are special cases, but as a general rule you should ban the use of GOTO.
     
  5. cossie macrumors member

    Joined:
    Aug 8, 2006
    #6
    Where I work we use "test driven development" for our software projects. I'd never worked that way before going the company and it's made me a much better programmer already (I've been there 3 months).

    It has made me really think about all the things my code should be able to do and handle before I actually write a single line. Now I always make sure I have sanitation checking, really tight exception handling (I'll admit to lazily using catch(Exception e) when pressed for time in the past!) and things of that nature.

    Seeing those big red "Failed" messages appearing a few times from our build system after submitting new code certainly shames you into picking up your game!

    I've been trying to use it in my own personal projects too.
     
  6. macjunk(ie) macrumors 6502a

    Joined:
    Aug 12, 2009
    #7
    Read up on XP practices and pair program with someone better than you...
     
  7. aforty macrumors 65816

    aforty

    Joined:
    Nov 27, 2007
    Location:
    Brooklyn, NY
    #8
    Truth!

    I wrote the "BESTEST CODE EVAH" at work about a year ago and I mean I was so proud of it, I'd go around and show it to people and I'd talk about it and whatnot. It really was quite nice at the time. Now I revisited it yesterday because of some enhancements that had to be made and man... what a piece of crap! I see so many things I could have done differently, scratch that, better.

    Then again though, knowing what I quoted you above for as being absolute truth... You know how sometimes you write some code that just stands the test of time? You come back to it but it still shines and you still marvel at it. That's a great feeling right there. (or maybe I just haven't progressed enough to figure out what I did wrong ;))
     
  8. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #9
    Its the simple stuff. The non-fussy stuff. The stuff you are not proud of at the time that stands the test of time because it does something and does it well.

    It is quite common to see programmers get caught up in their egos or find a really 'elegant' approach to a problem, only to find out it was rubbish later on.

    As to the thread, a method or a function should do one thing only. Just remember that and your problems go away.

    C++ is hard enough to write good code in. Don't make it harder by getting caught up in the cleverness of the language. KISS: Keep It Simple Stupid.
     
  9. aforty macrumors 65816

    aforty

    Joined:
    Nov 27, 2007
    Location:
    Brooklyn, NY
    #10
    You nailed it. And it's usually not simple though hours of over-analyzing and contemplating but something you thought of but didn't really have the time to think through.

    Love those moments. Programming can be such a high... am I weird? :rolleyes: :D
     
  10. kernkraft macrumors 68020

    kernkraft

    Joined:
    Jun 25, 2009
    #11
    Here's my tip

    Every time you make a mistake, you should break a finger. Soon, you'll hardly be able to type, so whatever you put down as code will be certainly worthy and properly thought-through.

    There is nothing more motivational than physical pain (unless you are a masochist)!
     
  11. MorphingDragon thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #12
    I'm having trouble deciding if you're serious or being sarcastic.
     
  12. kernkraft macrumors 68020

    kernkraft

    Joined:
    Jun 25, 2009
    #13
    Please, don't break your fingers! I only tried to light up the discussion. But the point is that many people use some reward-system about their workflow. If notes help in front of you, use them! If you can have a sweet or a longer break, try to set targets about them...

    You can be your biggest slave-driver or your biggest de-motivational influence.
     
  13. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #14
    Don't try to be clever.
    Don't confuse cleverness with elegance.
    Don't optimize prematurely.
    Your code isn't cleaner without those pesky comments.
    Good comments are much better than none, none are better than comments that lie.
    Use revision control, and look at your diffs before you commit along with the comments. Did you update the comments when you changed related code? Is the change what you meant and what you say it is? Make sure you did these before committing.
    Don't use block comments to remove code. Just delete it, that's what revision control is for. Grepping for things is much harder if half the results are actually commented out.
    If you notice a flaw in your approach, don't be afraid to delete everything and start again.
    Do you have access to code written by better coders than you? If so, read it.
    Have you written the same or a very similar line of code before? If so, you should try to do this task in a function.
    Do not use goto. Discipline is important. If using a goto will save you 20 lines of code, don't do it. 200 lines? Don't do it. Typing is easy, thinking is hard. Saving LoC while sacrificing readability and understandability is not worth it.
    Spend more time thinking and with paper and pen than you do now, and less time in your code editor.
    You should be able to improve something you wrote a week ago, be a bit unhappy with something you wrote a few months ago, a bit embarassed by things you wrote 6+ months ago, and ashamed of things you wrote a year ago. That's just how it goes if you're getting better. Design your objects on paper before you start coding.
    Code your classes with a driver to test them. When they work, then start wiring them up to actually perform the task.
    If you're up against a hard problem, throwing more code at it won't help. You'll solve the hard problems in the shower, in the car, eating dinner, etc.
    Have others review your code. They will look at it differently than you do. Take their critiques in stride, they want you to get better.

    Otherwise, it's just time and practice. Books are nice, but you're not going to break habits reading a book, you have to do things right over and over.

    -Lee
     
  14. pilotError macrumors 68020

    pilotError

    Joined:
    Apr 12, 2006
    Location:
    Long Island
    #15
    I've seen this book recommended, but I haven't read it myself.

    Clean Code
     
  15. Luke Redpath macrumors 6502a

    Joined:
    Nov 9, 2007
    Location:
    Colchester, UK
    #16
    This. Read it. Then read it again.
     
  16. seepel macrumors 6502

    seepel

    Joined:
    Dec 22, 2009
    #17
    These re all the things I tell myself I should do, but don't because I get lazy and "want it done NOW". Then I regret it later.
     
  17. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #18
    I was reading a security article the other day about why the Linux kernel makes quite liberal use of goto and it made sense.

    Imagine a function that has to free resources before it can return an error code. If you have say 5 or 6 function calls within it, each needing to have the return value checked and dealt with that means you need 5 or 6 sections of code doing essentially the same thing (albeit with a different stderr error message), this can often lead to one forgetting to clean your code up.

    The solution that the Linux kernel uses is a goto to a clean up section which then cleans up after itself before returning the appropriate error code.

    I'm not sure how popular this approach is, but it made sense.
     
  18. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #19
    If someone is an experienced kernel hacker, they probably don't need my advice. I'd say, though, that you need to learn the rules before you decide when they must be broken. Even in the case you describe, a partner function that can be called inline seems like it would get you the same performance and be cleaner. But again, the folks writing that code are probably better programmers than I, that code's performance requirements might trump readability, and it sounds like with enough discipline the code you describe is probably still easy to follow. This sounds like an incredibly rare exception.

    http://xkcd.com/292/

    -Lee
     
  19. mdatwood macrumors 6502a

    Joined:
    Mar 14, 2010
    Location:
    Denver, CO
    #20
    Defensive programming, treat all warnings as errors, handle all exceptions are all great programming techniques. Automated testing is key. I don't always agree with the people who want to write all tests before writing any code because that can seem like overkill and it's hard to know what to test. What I do agree with though is if a bug is found finding it again should be automated. Bugs have a habit of resurfacing while making code changes and automated testing is a great way to catch these.

    Kernel hacking is basically it's own type of programming. There are so many other rules and gotchas that you have to deal with that never present themselves in the code that the majority of programmers write. Back in grad school I wrote some Linux kernel code for a class and it can be very messy because it's been optimized to hell and back for speed, deals with hardware interrupts, and has a lot of legacy code kicking around among other things. I wouldn't really use Linux kernel code (or any kernel code) as an example for code writing best practices. This goes doubly true when most people who are going to read and work with your code are not at the level of kernel hackers.

    Some good reading here and here.

    With that said, there are no fixed rules. A GOTO may be the perfect way to solve a particular problem, but *usually* it's not especially if you're writing code in a language that has proper exception handling unlike C.
     
  20. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #21
    Patience and discipline are two key habits. Without them, nothing else matters.

    We never have time to do it right, but we always have time to do it over.
     
  21. pilotError macrumors 68020

    pilotError

    Joined:
    Apr 12, 2006
    Location:
    Long Island
    #22
    A little off topic, but how many of you in heavy duty coding shops have ever had time to refactor something?

    In all my years, I've never had the opportunity to go back and fix something that wasn't broken and wasn't funded to be modified.

    In just about every shop I've ever been in, it's frowned upon to change anything other than the bug you need to fix. Mainly because it becomes a regression testing nightmare.

    I'm not sure if that's because most of my career was spent in high availability shops or because our coding practices just sucked.

    I love the books and techniques, and I completely agree that good coding comes from reading A LOT of others code (you may think your good, but keeping an open mind will make you better), and time on the job. You usually do something OK and it works, and you see some folks do it better and then you see it done differently, and ultimately, you gather ideas for the next project.

    I like some of the concepts of XP and Agile (Sometimes the same), but refactoring code because you feel like it seems like a sinkhole. In practice, I've seen some refactor code because they didn't understand it (over their ability).

    I'd like to hear some of your experiences on the subject. I could also start a new thread if this is too off topic.
     
  22. mdatwood macrumors 6502a

    Joined:
    Mar 14, 2010
    Location:
    Denver, CO
    #23
    I refactor all the time, but usually by very small amounts and only code that needs it. First, you need to have some sort of automated testing. This will help with the regression problem. Second, I only refactor code while I'm already in fixing another problem. My rationale is that the code was written in such a way the first time to introduce a bug, so if I take the time to understand the code in order to fix the bug I should also refactor the code to protect against any future bugs.

    It also takes discipline to know when and what to refactor. You don't need to do it just because you learned some new technique, but only if it will actually make the code better in some way.
     
  23. pilotError macrumors 68020

    pilotError

    Joined:
    Apr 12, 2006
    Location:
    Long Island
    #24
    We have a ton of automation testing, but it can never possibly catch everything.

    I do need to get better acquainted with test-driven software development though. As much of a PITA as it sounds, I think in the long run, its a good thing.

    In terms of refactoring, we produce code diff's for our QA teams. It gives them an idea of testing coverage per lines of change. The real issue is not so much testing within the system itself, but all the external systems we connect with.
     
  24. jpyc7 macrumors 6502

    Joined:
    Mar 8, 2009
    Location:
    Denver, CO
    #25
    I'm refactoring some code right now, about 2500 lines of Python with a co-worker. We have not deployed the software yet, but I am not convinced that the new re-factored code is that much better than the old code. I wrote/designed the majority of code and the new code has better abstraction to hide database code. It might pay off in the long-run, but I really doubt we are going to change our SQL server vendor. Basically, I think my original code was either already pretty good or I didn't think enough to come up with better refactoring/design.

    I've been reading up on agile programming after interviewing with a company using that process. I like the concepts (and feel like I do many of the same things currently). My main weakness is testing (or at least automated testing). I am probably over-estimating the effort required to write more automated tests, so I only do it for subsets of functionality.
     

Share This Page