Hello! I hope you are doing good today! Understanding good programming styles and practices is very important to any serious programmer. Most people have arguments for and against certain ways of programming – let us look at a few and then give you an opportunity to share your own views.
Common Questions :
- Should you comment your code or not?
- Curly braces on separate lines or not ?
- Camel case or not camel case?
- Should you use underscores in function names?
- To put or not to put author’s name in the file?
Once again, we could debate for centuries on these questions but I believe there are several rules of thumb that most of us can agree that they could apply to most programming languages.
1)Avoid shelling out to commands
Not only is this not cross-platform but also very expensive in terms of processing. Let us consider an example here:
import os import subprocess def f(): x = "" x = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE).communicate() def f2(): os.listdir('.') for i in range(0, 500): f()
*Note: ls is a fairly lightweight command. But let’s say you were to SSH, FTP, etc
- f() takes approximately 3.39 seconds to run
- f2() takes about 0.05 seconds to run
The time is not that much of a difference, however, analyzing more important information :
- Minor (reclaiming a frame) : 353959
- Voluntary context switches : 2501
- Involuntary context switches : 1610
- Minor (reclaiming a frame) : 1036
- Voluntary context switches : 1
- Involuntary context switches : 7
That is really bad. No really, it is horrible. Context switching is one of the most computationally intensive operations there is. If you are interested in reading more about it, please click here
2)Generally, functions or methods should do a single task
Of course this rule isn’t set in stone, but it is a good rule of thumb to try to program by. It does make your code easier to read to an extent and much easier to maintain. If you have a function that performs multiple tasks – it’s almost a guarantee at some point in your development that you will want to do 1-2 of the tasks out of 3 so this would spawn a function with duplicated functionality. If you are copying code it’s a good indication you are doing something wrong.
Consider this python example
class Employee: checkingptr = 0 def calculate_hours_and_pay(self, hours): pay = hours * 25 self.checkingptr += pay
Simple right? While you are watching cat videos after completing your code, your not-so-cool boss drops in and says “we need a way to pay bonus” and you are like, no problem. You go ahead and do this:
class Employee: checkingptr = 0 def calculate_hours_and_pay(self, hours): pay = hours * 25 self.checkingptr += pay def pay_bonus(self, cash): self.checkingptr += cash
Now your boss comes in again and says, hey, we need a way to pay certain employees based on how much they sold. So you jump onto the code and add methods like this:
class Employee: checkingptr = 0 def calculate_hours_and_pay(self, hours): pay = hours * 25 self.checkingptr += pay def pay_bonus(self, cash): self.checkingptr += cash def sale_bonus(self, nitems): self.checkingptr += (.25 * nitems)
Great right? Not so fast Mr. Grasshopper, we need to pay taxes too. So you whip up your ninja skills and do this:
class Employee: checkingptr = 0 def calculate_hours_and_pay(self, hours): pay = hours * 25 self.checkingptr += pay - (pay * 0.1) def pay_bonus(self, cash): self.checkingptr += cash - (cash * 0.1) def sale_bonus(self, nitems): self.checkingptr += (.25 * nitems) - ((0.25 * nitems) * 0.1)
A better way of solving this problem
class Employee: checkingptr = 0 def deposit_money(self, deposit): checkingptr += deposit - (deposit * 0.1) def calculate_hours_and_pay(self, hours): pay = hours * 25 deposit_money(pay) def pay_bonus(self, cash): deposit_money(self, cash) def sale_bonus(self, nitems): deposit_money(0.25*nitems)
If you are interested in reading more about this, please click here.
3)Try to program as efficiently as possible
I think that in today’s day and age people fall into a trap of thinking that modern computers have tons of RAM and plenty of CPU power and it causes them to subconsciously waste those resources. I think certain languages enable this behavior over others – especially those that perform automatic garbage collection.
Consider this example
# postdata = copy.deepcopy(request.POST) #
Arguably this is completely unnecessary and a waste of memory and CPU time. That, is not good programming style and practice. Assuming you are going to modify the value of the submitted data – just make a copy of that specific value such as:
# postdata = copy.copy(request.POST['name']) #
Now POST data is, usually, just a single level dictionary and doesn’t have much effect. But what if in Django, you did something like this:
# blogposts = copy.deepcopy(Blog.objects.all().values()) #
Always pretend that RAM and CPU are a limited resource. In the long run not only will your application run faster but your customers/clients will be happy with fast software. Which actually brings me to a specific example. How would you store hierarchical data in a database? Such as species of animals or classes of food.
Click here to read a more in-depth article on how to store the said data. Ultimately you should use an algorithm like Modified Pre-order Tree Traversal. It does require some up front processing costs but it will make querying data much more efficient.
Thank you for reading this post. Please share it with your friends online using the buttons below and leave some comments. If you have any questions, please do not hesitate to ask and remember to subscribe for updates. Thanks again and see you soon.