There was a time in my life when I first started this whole programming thing when I thought, “Programming is easy… why do you need to go to school for this stuff?”, but with experience and education I have learned that programming is hard.
Self evaluation has always been important to me, because at the end of the day it doesn’t matter what anybody else thinks, it matters to what you think. During this evaluation I thought about strengths, weaknesses, education, training, and personal growth. This process allowed me to reflect, learn, and think about what it means to be a programmer.
My first job in the tech industry I focused on HTML, CSS, and JavaScript for the purpose of making elements do things or creating some visual intrigue. In this time, I never really thought of myself as a programmer and at that point I never really wanted to be one. It was slightly after when I figured out how to do more things in NodeJS, PHP, and MySQL that I started to think of myself in this light. Compounding my thoughts of grandeur as a programmer, I got my first job with a programmer like title “software engineer” where I was actively programming solutions daily.
“Experience has taught me that I was slashing, hacking, and pounding keys with vigor, but I wasn’t programming. ”
Programming requires thought and understanding of various data types, structures, and understanding the technology that programming languages were built to serve. The difference is mainly in the process used when working on getting certain tasks completed. The focus was not on data types, design patters, algorithm types, performance, or anything related to the quality of code and application. Instead it was being put into the actual working mechanic and the aesthetics of the mechanic, this often ended in a lot of time into a large un-maintainable beast. All the while running output to various places and feverishly testing that output until it closely resembled a feature. If anything this gave me the feeling that I was programming, but I wasn’t being pragmatic or thoughtful in my approach.
Data structures is an area that I’ve gotten the feelings of inadequate education. The idea behind data structures is that you have different ways of storing, recalling, sorting, and searching data. When I first started programming I never thought about various data tasks and the performance with the datatypes. Often times defaulting to using arrays (including hashes, json, dictionaries, and other terminology for key-value data sets) for anything that needed to be stored, sorted, or iterated over.
Sets, stacks, and queues are intriguing to me from a computer science standpoint, but less intriguing to me after actually seeing some in action within the ruby programming language. In my mind stacks and queues are the same thing, they allow you to get information from the ends of the data, the exception with queues is that you can only get the items in the order that they joined. When I imagined this at first I thought of putting things in a list to await processing and reduce over-head on tasks that can be run in the background. Actually putting it into practice in a high level programming language like Ruby doesn’t make much sense since it is basically just pushing or unshifting elements into an array.
For example, a stack in Ruby could be as simple as the code below.
class Stack
def initialize@set = Array.new()end
def push(x)@set.push xend
def grab@set.popend
def empty?@set.empty?endend
# implemented stack
s = Stack.news.push 'a's.push 'b's.push 'c's.inspect #<Stack:0x48b66454 @set=["a", "b", "c"]>puts s.grab # "c"puts s.grab # "b"puts s.grab # "a"s.grab.inspect # nil
Queues are relatively the same on the type of data that is created, plus Ruby has a class for that already.
# ruby Queue Class
q = Queue.newq << 'a'q << 'b'
# Tests Examples using Queue
puts q.length # prints 2puts q.pop # prints aputs q.length # prints 1puts q.pop # prints bputs q.length #prints 0
While simple, it is basically a very simple array. That itself may be the beauty of it. I see myself potentially using stacks or queues in command line scripts, but I’m not sure where else I would use them off the top of my head.
Binary Search Tree is something that intrigues me because of the search times and speed in retrieving data. I’ve often found it really easy to get data from an array, but as the array gets large searching it takes time. That is where binary search trees come into play, and I really enjoy this video produced by Harvard. While I haven’t done anything to use one of these, I really would like to implement something using this and then compare it to the native ruby methods with arrays to see how much faster Binary Trees are than simple arrays or hashes. In my research about binary trees and trying to find actual implementations and use cases I found these interesting articles.
My first web application was ridiculously bad for maintainability. I used no code conventions, no design pattern, no order to where methods were being defined, no namespaces, and no objects or models. If I had to go back to fix bugs (which I’m sure it has), it would probably be faster to re-write than figure out where the method causing the bug actually exists.
Poor design leads to spaghetti code.
One problem I had difficulty overcoming was nested conditionals and loops. These loops would often have tons of if statements and validations, but this problem was systemic of another problem. Not understanding how to properly organize and separate various parts of the program. I was trying to do everything in large methods and not focusing on where pieces could be re-used or created as a module that extends functionality to all objects and methods. The code below is an actual snippet truncated and modified slightly to conserve length.
print " <h3> Display Weekdays: </h3> ";
// Looping in a view ... should have been factored diffforeach($imageRecords["display"] as $ => $displayRecords) {// WTF is this a nested foreachforeach($displayRecords as $value => $dispRecord){$tempWeekdayValuesArray = array();if($value === "weekdays" && !isnull($dispRecord)) {// 3rd nested foreach WTF!foreach($dispRecord as $weekday => $weekbool) {// :( condition foreach day ::SHAME::if($weekday == "monday" && $weekbool == 1) {// logic removed}}
}
}
}
I am not going to deflect the blame on anybody else, this code was my bad code and I will own up to that, however some of this could have been mitigated by a code mentor, or via code reviews and pull-requests. Looking back at this code I feel ashamed, but that is a good thing because it shows how much I’ve grown as a developer. Freedom is a problem that we had in some senses, but not in others. For example for this project I was hemmed into using a LAMP stack, that was non-negotiable, but at the same time that was really the only limitation. I didn’t have to use design patterns, follow any style guides, use code linters, or follow any policies about code convention. This creates a system where you are free to your own devices and if you haven’t learned about longevity of applications and bug fixes it compounds to harm your end results.
I’ve grown to really appreciate the text editor and how much it can save you by linting (pointing out potential errors)your code as you write, but I’ve also grown to really appreciate the finer smaller details associated with programming. A well written code base that follows documentation standards, clear conventions, and a style guide is as fluent to read as an email, or internet article. (Granted sometimes the programming language used lends itself to that much better) Generally I also found that I enjoy many of the principles in the book, Clean Code A Handbook of Agile Software Craftsmanship By: Robert C. Martin and various other authors.
The benefits of test driven development are enough to prove its merits, in my opinion, but I understand that not everyone agrees that testing provides any value to a codebase. I’m not going to argue the validity of testing, but I do want to share how it has helped me. Writing integration and unit tests for code prior to actually creating the code has helped in many ways. It has helped me write cleaner code, efficiently write code, and has helped me to solve problems that I’m having trouble wrapping my mind around.
Writing cleaner and more efficient code has a crossover with many things in programming. Readability, performance, and time to write are the main areas that TDD has helped me. I found that I am able to write code that I don’t have to refactor (multiple times) before it can go to production or into version control. It has helped me not only bug reduction, but the amount of time I spend tracing down a bug and fixing it. When fixing a bug I found I can take that expected input or output, write a test that matches it, and then work towards making that test and all other tests pass. This eliminates the bug and keeps the code doing its intended purpose.
TDD has helped me to organize my thoughts before I start writing the actual methods or objects. In more complex features it helps me to break down the feature to very minimal set of items that the feature needs to work properly. Often times it reminds me of writing false or pseudo code because your tests are going to fail and ultimately will have to be changed as your code evolves. That being said, edge cases are edge cases and they are often more difficult to think of when initially creating the code. Ultimately I feel that Test Driven Development helps to make me a better programmer.