Better Software Engineer Archives - Simple Programmer https://simpleprogrammer.com/category/better-software-engineer/ Wed, 15 Feb 2023 05:12:00 +0000 en-US hourly 1 https://wordpress.org/?v=7.0 11 Tips to Be a Better Software Engineer https://simpleprogrammer.com/better-software-engineer-tips/ Tue, 14 Feb 2023 13:57:27 +0000 https://simpleprogrammer.com/?p=45018 1. Get a Programming Mentor If you want to accelerate your programming career, there’s few things more effective than having someone mentor you on this path of professional growth. For one, you’ll be more motivated to go after your goals with a mentor watching over you. They’ll also be able to point you towards the...

The post 11 Tips to Be a Better Software Engineer appeared first on Simple Programmer.

]]>
1. Get a Programming Mentor

If you want to accelerate your programming career, there’s few things more effective than having someone mentor you on this path of professional growth. For one, you’ll be more motivated to go after your goals with a mentor watching over you.

They’ll also be able to point you towards the best resources for your current stage of learning. And finally, your Software Engineering mentor can give you valuable industry insights and connections that you never would’ve had access to on your own. 

2. Think like a Computer Scientist

A programmer is somebody coding different functionality into a program.

A Computer Scientist, on the other hand, is someone who figures out solutions to problems from a high-level view – and will also likely use code to implement a lot of those solutions.

This kind of work is more all-encompassing and demanding, allows for more growth, and is more well-paid. Which is why I encourage you to think like a computer scientist, not a programmer.

Don’t limit yourself to being someone who codes program features. Also be the one who’s creating the high-level solutions.

3. Know how to approach your development tasks

Start any project by listing the work items you’ll need to complete, and put them into the most efficient order.

Then it’s not just about coding each item – you should use the principles of Test-Driven Development (TDD): If you want to approach your development tasks optimally, you’ll create unit tests for each piece of the software as a form of quality assurance.

In the end you want to have achieved code coverage – you have tests for all bits of your code. Now, write code that’s only as complex as it needs to be.

Finally, refactor your code to make it even better.

4. Stay clear of code katas

Yes, you need to do a lot of coding practice if you want to be a better Software Engineer. But – you need to be smart about how you practice. It’s not about mindless repetition, which in the long won’t help you improve your skills at all.

Most people’s version of doing so-called ‘Code Katas’ is a waste of time.

Here’s what to do instead: Constantly give yourself new challenges. Try to solve new problems, or old problems in a new way. Up the difficulty of your practice, and soon you’ll find your level of skill has increased along with it.

5. Practice deliberately

Don’t just ‘practice programming’. Practice it in a way that’s challenging, purposeful and measured. You can apply the principles of deliberate practice to improving your coding.

It starts with setting goals that aren’t mushy, but can be exactly measured. Clear, focused, and with a deadline. Then break it down into skills you need to improve so you can achieve these goals. Set up a practice plan for yourself, and execute it using Ericksson’s laws of deliberate practice.

At last it’s time to review your efforts, ask for feedback, and reiterate your process if necessary.

6. Re-think code comments

Are code comments as much of a great idea as people make them out to be? What if they’re a crutch for code that’s too complicated and not optimally named?

In fact, if we can rewrite a piece of code with clear naming, delete comments, and it comes out more readable than before, then that proves code comments are mostly a bad idea

7. Respect levels of abstraction

A great way to make sure you’re implementing best practices is to respect the levels of abstraction in your code.

This means you’re focusing each piece of code on either a low-level task (say, computing a necessary math operation) or a higher-level one (like evaluating a portfolio). The levels of abstraction build on each other, but you never mix them in a single piece of code. You respect them as a separate entity.

To do this correctly, you’ll have to pay special attention to good naming, class cohesion, readability and more – forcing you to write better code.

8. Obey the KISS principle

Keeping It Simple, Stupid isn’t easy to do in practice. You need to be a great abstract thinker and a competent Software Engineer to carry out the KISS principle correctly in your code.

Your goal should be to create software with as few statements as possible. Your program will be more readable to others, have less potential for bugs, and be easier to refactor.

But achieving these things requires much forethought and skill of execution. 

9. Understand the two purposes of code

Algorithms and coordinators are the two roles our code has. We should divide these roles into distinct classes. That way, none of your algorithmic code has dependencies on other code – making for code that’s less complex as well as easier to test and reuse.

Strive to not use mocks. Create separate classes for algorithms and coordinators. You’ll improve your code design and make something that’s easy to understand and work on.

10. Protect your passwords

Beyond the obvious tips like not storing passwords you need in your Software Engineering job (or your private use) in cleartext or showing them to other people, there’s advanced methods for programmers to protect their passwords.

Once you understand how the common attacks – dictionary attack, brute force attack, rainbow table attack, offline cracking attack, collision-based attack – work, you’ll be able to take proper steps to prevent them.

Namely you do this by choosing strong passwords, and also by maintaining a cryptographic storage with the correct hashing algorithms.

11. Read Fiction to Become a Better Programmer

Wait, how could reading seemingly unrelated books (fiction even!) ever make you better at computer programming?

For one, these creative books help you with outside-the-box thinking. New connections are sparked – and some of them can lead to a brilliant idea for your work projects you wouldn’t have gotten otherwise.

Reading fiction can also help you recharge and recover from your programming work.

As if that wasn’t enough, engaging with high-quality prose can improve your own sense for words. It’s easy to imagine how that would help with any writing tasks on the job.

The post 11 Tips to Be a Better Software Engineer appeared first on Simple Programmer.

]]>
Why You Should Think Like a Computer Scientist and Not a Programmer https://simpleprogrammer.com/think-computer-scientist-not-programmer/ Wed, 21 Nov 2018 15:00:27 +0000 https://simpleprogrammer.com/?p=30435 According to the United States Bureau of Labor Statistics, there were 8.6 million science, technology, engineering, and math (STEM) jobs in May 2015, which made up 6.2 percent of the country’s employment. Forty-five percent of these jobs revolved around computer science. The research sheds light on the importance and growth of computer science. We observe...

The post Why You Should Think Like a Computer Scientist and Not a Programmer appeared first on Simple Programmer.

]]>
According to the United States Bureau of Labor Statistics, there were 8.6 million science, technology, engineering, and math (STEM) jobs in May 2015, which made up 6.2 percent of the country’s employment. Forty-five percent of these jobs revolved around computer science.

The research sheds light on the importance and growth of computer science. We observe immense potential in it to exponentially grow in the coming years. Does this mean it’s essential for developers who want to keep refining themselves to have an additional understanding of computer science besides their particular technical knowledge?

This article explores the differences between a programmer and a computer scientist and rationalizes the significance of thinking like a computer scientist.

The Difference Between a Programmer and a Computer Scientist

Let us try to understand the difference between the terms “programming” and “computer science.” “Programming” is the generic term used for a person who works with software, applications, and other technological solutions.

For example, if someone in your office develops websites, you call them a programmer. If someone helps in solving functionality issues in an application, you call them a programmer or a coder. A programmer or a coder solves specific problems or adds features to a technological solution by developing and implementing codes.

Let’s think of your website experience. You open a website and, in a few seconds, a chat box added by a programmer working on the backend pops in. Now the question is, why isn’t a programmer a computer scientist?

“Computer science” is a broader term and includes many different dimensions, one of which is programming. Programming is a specific and concrete tool to perform a function, while computer science is an approach to solving problems efficiently and avoiding them in the future.

Computer science allows people to think differently by encouraging them to find opportunities in the problems they face.

Let’s go back to the time when we learned the basic structure of an eye. We know there is a retina, pupil, iris, and cornea; however, we don’t know how exactly the eye operates. Similarly, the knowledge of computer science helps you understand things in general, like the structure of an eye, while programming is a specific tool, like addressing a certain problem in the eye.

Why Should You Think Like a Computer Scientist?

A programmer will only develop code to solve a problem or create desired features, either of which has a limited scope. For example, a programmer will be responsible for developing software efficiently and incorporating all the requirements of the client.

On the other hand, a computer scientist will explore the possibilities and analyze ways to make the software better than what the client expects. Computer science gives you the ability to think critically and do better than is expected of you. It develops a drive for improving your skills. Do you not want to be more than ordinary?

Being a programmer means that you are focused on specific tasks such as developing an add-on feature for the website. The goal is to get the work finished. However, being a computer scientist means that your focus is on resolving the problem by understanding its causes, impact, and chances of occurrence in the future.

Thinking like a computer scientist will widen your horizons, help you develop a proactive approach, and enhance your efficiency.

How Can You Think Like a Computer Scientist?

Now that we understand the differences between a programmer and a computer scientist, let’s help you become a computer scientist!

Start by Understanding the Causes of a Problem

Programmers are often in a hurry to resolve the problem by developing the appropriate code. Consider a website that is no longer able to record the email addresses of its visitors. Now, a programmer would immediately think of solving the problem, but a computer scientist would dig deep into why the previous code failed and how to avoid failure in the future.

Remember that the goal is not merely to solve an issue immediately but to develop sustainable solutions that do not hinder any business operation. Take your time to think and do research before attempting to solve it. You may want to make notes or write it down, like a mind map.

Develop a Solution Plan

Think of one of the greatest companies in the world: Apple, Inc. Do you think one day the company decided to launch an iPhone-like mobile device and the next day started making it? No. When we ask you to think like a computer scientist, we are asking you to plan your work.

Once you have identified the possible causes of a problem, start working on the possible answers. Your knowledge, experience, research, and discussions will help you in shortlisting the alternatives. You must then write down the plan to implement the ideas, with various contingency plans.

What if the code doesn’t work? Will you start the research all over again or try an alternative code immediately? A computer scientist will look at things from a broader perspective, first analyzing the reasons that led to the failure of the code and then developing several solutions that are likely to get the job done. Instead of instantly trying different code, a computer scientist will run a thorough check to not repeat the mistakes.

Keep Looking for New Ways to Solve Problems

Computer science improves the way things are done. If you want to think like a computer scientist, you must be on a quest to learn.

A programmer may rest once a problem is solved, but a computer scientist will keep looking for new ways to improve the quality of products and services. Their goal is to develop methods to resolve issues before they arise and work to make things better.

According to Sebastian Thrun, “To me, mathematics, computer science, and the arts are insanely related. They are all creative expressions.”

Switch to the Scientist Mode

Computer science is an approach and a mechanism for addressing problems and developing effective solutions to ensure sustainability and reliability. Unlike programming, it isn’t about performing a specific task, but about doing things the right way.

Thinking like a computer scientist allows you to identify problems and explore different methods and solutions. It aims to eliminate errors in the future as well, therefore developing highly sustainable and widely applicable solutions.

Being a programmer does not mean you have to drown yourself in code and have a monotonous work life. Remember, you are a computer scientist who knows more than just coding!

The post Why You Should Think Like a Computer Scientist and Not a Programmer appeared first on Simple Programmer.

]]>
Protect Your Passwords https://simpleprogrammer.com/protect-your-passwords/ https://simpleprogrammer.com/protect-your-passwords/#comments Fri, 10 Mar 2017 15:00:33 +0000 https://simpleprogrammer.com/?p=22176 Recently, I created an account with a site (which shall remain nameless). Everything seemed cool at first. Then I submitted my application and was instantly greeted with a message: “Thanks for signing up. Your username is XXXX and your password is XXXX”. Yes, the site showed my password in cleartext right on the screen.\n\nThat is...

The post Protect Your Passwords appeared first on Simple Programmer.

]]>
Recently, I created an account with a site (which shall remain nameless). Everything seemed cool at first. Then I submitted my application and was instantly greeted with a message: “Thanks for signing up. Your username is XXXX and your password is XXXX”. Yes, the site showed my password in cleartext right on the screen.\n\nThat is pretty bad, right? Well, then something worse happened: I received an email. Can you guess what was in the email? That’s right: “Thanks for signing up. Your username is XXXX and your password is XXXX”. The password was sent to me in an email, again in cleartext.\n\npasswords\n\nI agree, Captain Picard.\n\nIf this story doesn’t make you facepalm, it should. Now, let’s talk about why careless password security is really bad, what policies and procedures you should have when storing passwords, and tips for a serious programmer to protect his passwords properly.\n\n

How Not to Protect Your Passwords

\n\nStoring passwords in cleartext. The number one practice that is completely wrong and indefensible is storing passwords in cleartext, as illustrated in the above example. This means whatever the user enters as their password will be directly stored in the database without any scrambling to prevent someone from seeing what they are. If you enter “p@ssw0rd!” as your password, then “p@ssw0rd!” is what is stored in the database. If someone gets into your database, they will be able to steal anyone’s credentials and impersonate them. Here’s a hint: if a website can send you your password, that means it is storing them in cleartext.\n\nAllow any humans to see passwords. Here is a quiz question: who should be allowed to see users’ passwords? The answer: NO ONE. Don’t fool yourself into thinking that system administrators or help desk personnel need to see passwords in order to do their jobs. This is a very bad practice that leaves you open to social engineering attacks.\n\nEncrypting passwords instead of hashing them. While there are times that an application may need to encrypt passwords, this should never be done with a user account’s password. The main reason for this is that if something is encrypted, it can be decrypted. You want to use hashes, or one-way functions that make it infeasible to get the input back out given the output. That brings us to our next point.\n\nUsing weak hashing algorithms or techniques. Just because you hash a password doesn’t mean it is safe. Which hashing algorithm did you use? Did you hash it only once and expect it to be okay? There are some subtleties to password hashing that can cause weaknesses and lead to compromise.\n\nDo not despair. Let’s take a look at how developers can do it right.\n\n

How to Properly Protect Your Passwords

\n\n\n\nThe first step to figuring out how to properly protect your passwords is understanding what kind of attacks the bad guys will use to try to get or guess those passwords. In this vein, let’s take a quick look at some of the top ways passwords are cracked today (a more complete list can be found here).\n\n

    \n

  • Dictionary attack – This attack is, as it sounds, when a dictionary of words is used to try to guess a user’s password.
  • \n

\n\n

    \n

  • Brute force attack – This is just a computer guessing every possible combination of alphanumeric characters until it finds the right password.
  • \n

\n\n

    \n

  • Rainbow table attack – A rainbow table is a table of precomputed hashes of passwords. If password hashes are stolen from a database (for example, from an SQL injection attack), the attacker can simply search for the stolen hashes in the table to figure out the correct password. These nasty things are why just hashing your password is not enough.
  • \n

\n\n

    \n

  • Offline cracking attack – Another side-effect of stolen hashes is that they are often published and made available. Once they are out, someone can just sit and use the above techniques until he/she finds some good passwords to steal.
  • \n

\n\n

    \n

  • Collision-based attack – This is rarer and more difficult, but it is possible and thus you should be aware of it. A collision-based attack involves trying to find a set of characters that, when hashed, will produce the same output as your password. That way, the attacker does not have to have your actual password since, if the hashes match, the system will let you in. This is a big reason why you need to choose a good algorithm to ensure that the chances of collision are sufficiently low.
  • \n

\n\nThese attacks can be mitigated by two things: long, random passwords and secure cryptographic storage. It’s up to your users to provide good passwords (and you can help with policies), but it’s up to you to provide the secure storage.\n\nThe best way to provide that secure storage is by handling hashing correctly.\n\n

Strong hashes

\n\nThe first step in effective hashing is choosing the best hashing algorithm. This is the foundation of your password storage architecture and is arguably the most important decision. Some hash algorithms have been shown to be weak. MD5 is one such algorithm. It has been shown to produce collisions—a big red flag when it comes to security. Another argument against it is the fact that it is a fast and memory-efficient hashing algorithm. To critique this may seem strange at first but consider this: the more efficient the algorithm, the faster you can make guesses. This means that MD5 is much easier to crack using brute force than other hashing algorithms.\n\nThe secure hash (SHA) family of hashes was developed by the NSA and published as the FIPS 180 series of standards published by NIST. This family consists of SHA-1, SHA-2, and SHA-3. SHA-1 has recently been shown to have collision problems and has been deprecated by NIST since 2011. SHA-3 is still very new and isn’t in wide use yet. SHA-2 is your best bet for an algorithm that has withstood scrutiny and has shown itself to be unpredictable and collision-free. It comes in two flavors: SHA-256 and SHA-512, named after the amount of bits output by the algorithms.\n\n

Salted hashes

\n\nWe spoke earlier of rainbow table attacks. These are the reason that just hashing your passwords before storing them is not enough. Salted hashes are the prescribed way of defeating rainbow tables.\n\nA salt is a random value that is generated and added to the password provided by the user before hashing the value and storing the hash in the database. This bit of randomness ensures that an attacker would have to precompute all hashes for all possible combinations of salt and password value, which is quite difficult.\n\nSalts should be generated by using a cryptographically secure random number generator. This ensures that even if two users provide the same password, their hashes will be different. See how this works in the example below:\n\npasswords\n\nThat bit of randomness added to the password will further protect all of your users in the case of a data breach.\n\n

Password-based key derivation functions

\n\nAnother great tool developers can use to protect their passwords is a password-based key derivation function, or PBKDF. PBKDFs are great tools for two reasons:\n\n

    \n

  1. They make it practically impossible to figure out passwords using rainbow tables.
  2. \n

  3. They make it really hard to brute force passwords because they deliberately slow down the hash calculation.
  4. \n

\n\nPBKDFs take three inputs: the password you want to hash, the salt, and a number of iterations to perform on the password to get the final hash.\n\n\n\nA huge advantage of PBKDFs is that they are configurable by nature. As processors get faster and better at cracking passwords, you can simply increase the number of iterations in order to stay ahead of the bad guys.\n\nKeep in mind that there are tradeoffs associated with this method. Increasing the number of iterations will also increase processing time. This is a great defense against brute force attacks, but will mean longer processing times for users if you are using PBKDFs for the user authentication process.\n\nYou should find a balance between security and usability, as is often the case. I suggest 50,000 iterations as a baseline, increasing as you can tolerate the performance impact.\n\n

How to Use .NET to Protect Your Passwords

\n\nNow that you understand the high-level concepts that can be used with any technology, let’s take a look at how .NET enables developers to protect passwords within their systems.\n\nIf you want good cryptography using the .NET framework, then you should get familiar with the System.Security.Cryptography namespace. Many of the tools we will discuss here are in that namespace. Let’s begin.\n\n

RNGCryptoServiceProvider

\n\nThe first order of business when you are implementing cryptography is choosing the correct random number generator. Random number generators will be the source of entropy for your keys in encryption and salts for hashes. We’ll concentrate on how to create a salt with a random number generator, but the same technique would work for creating a key as well.\n\nFor secure random numbers in .NET, use the RNGCryptoServiceProvider to generate a random set of bytes that you can then use as your salt. Do not use System.Random to generate secure random numbers. System.Random was not created with security in mind, and thus has a repeatable and guessable pattern in its generation of random numbers. RNGCryptoServiceProvider will give you the entropy you need for a secure salt (or key).\n\nYou use RNGCryptoServiceProvider by creating an instance and using the GetBytes method to generate the random set of bytes. RNGCryptoServiceProvider implements IDisposable, so make sure you wrap it in a using statement to make sure the object is properly disposed of when you are done with it.\n\nBelow is an example of using the RNGCryptoServiceProvider to securely generate a salt:\n\n\n\nIt’s only a few lines of code, but it can make a world of difference in the strength of your encryption and hashes. Wrap up the RNGCryptoServiceProvider in a library so that all of your developers can use it for all applications.\n\n

Hashing passwords with .NET

\n\nThe System.Security.Cryptography has many classes that implement common encryption and hashing algorithms. It would be wise to become familiar with them. The classes available to you are simply named after the algorithm you want to use. There is the MD5 class, the SHA1, SHA256, and SHA512 classes, and so on.\n\nSHA256 and SHA512 are your best bets for secure hashing (along with a random salt). Using them is actually refreshingly simple. You instantiate an object by calling the static Create() method on the class you want to use and then call ComputeHash() method to get the hash. It looks like this:\n\n\n\nIf you wish to use a PBKDF for storage of passwords, the .NET framework provides a class called rfc2898DeriveBytes (named after the RFC of the specific PBKDF used). It’s kind of a strange name, but the usage is still pretty simple:\n\n\n\n

SecureString

\n\nAn often overlooked security feature available in .NET is the SecureString class in the System.Security namespace. The SecureString class provides a secure alternative to the base String class when dealing with sensitive data such as passwords or credit card numbers. Let’s take a look at what the differences are between these two classes.\n\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

\n

String SecureString
Multiple copies in memory One copy in memory
In memory unencrypted Encrypted in memory
No easy way to zero out Implements IDisposable and a Clear() method
Immutable, so extra are created and kept in memory when changed MakeReadOnly() method to prevent any changes to the string

\n\n\nThe SecureString should not be used everywhere, but its use should be considered when dealing with any sensitive data in memory.\n\n

CryptSharp

\n\nI stumbled upon an interesting library called CryptSharp. It offers many great tools and cryptographic functions that could definitely come in handy if you don’t want to roll your own tools such as salt generators. It also provides you with the ability to use any hash algorithm with a PBKDF, as the native .NET implementation only supports SHA-1. It’s definitely worth a look if you are serious about securing your passwords.\n\n

ASP.NET Identity

\n\nThe last .NET framework piece I’ll mention is ASP.NET Identity. This library is included in the project templates for ASP.NET applications in Visual Studio, and is meant to provide a clean interface for developers to manage identities without rolling their own identity management solutions.\n\nThe secure storage of passwords is abstracted away, which can be good or bad depending on your opinion of such things. The full scope of functionality could be a post unto itself. The best place to get started would be on the official docs site.\n\n

The Final Dos and Don’ts of Password Storage

\n\nI know all this information is undoubtedly a lot to take in. But here are the things I want you to remember:\n\n

    \n

  1. Never store passwords in cleartext, anywhere.
  2. \n

  3. Just hashing is not enough, as rainbow tables can easily break through them.
  4. \n

  5. Salt your passwords with random data before hashing them to strengthen the hashes.
  6. \n

  7. The best protection against password attacks is to use a PBKDF, but remember that there is a performance cost.
  8. \n

  9. The System.Security.Cryptography namespace holds hash implementations and a PBDKF implementation for your use.
  10. \n

  11. Don’t use System.Random for random numbers. Instead, use RNGCryptoServiceProvider.
  12. \n

\n\nThe thought of storing passwords doesn’t have to be scary. Understanding best practices is the first step. From there, you can use good judgement, always keeping your users’ best interests at heart. Armed with both knowledge and empathy, you can keep your users safe and your passwords secure.

The post Protect Your Passwords appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/protect-your-passwords/feed/ 6
Respecting Levels of Abstraction https://simpleprogrammer.com/respecting-abstraction/ https://simpleprogrammer.com/respecting-abstraction/#comments Fri, 27 Jan 2017 15:00:49 +0000 https://simpleprogrammer.com/?p=21899 As software developers, we get to improve by learning many good practices which we strive to apply in our code.\n\nFor instance, we learn the importance of good naming of variables and functions, encapsulation, class cohesion, the usage of polymorphism, concision, readability, code clarity, expressiveness, and many other principles.\n\nIf you consistently deploy all of these practices,...

The post Respecting Levels of Abstraction appeared first on Simple Programmer.

]]>
As software developers, we get to improve by learning many good practices which we strive to apply in our code.\n\nFor instance, we learn the importance of good naming of variables and functions, encapsulation, class cohesion, the usage of polymorphism, concision, readability, code clarity, expressiveness, and many other principles.\n\nIf you consistently deploy all of these practices, you’re in fact doing one thing: respecting levels of abstraction. As we’ll see in greater detail in this article, an abstraction is characterized by what a particular piece of code intends to do as opposed to how it is implemented.\n\nThis is the one principle to rule them all because it automatically applies all the best practices mentioned above and more besides. When you follow it, you’ll find yourself naturally writing code with a high-quality design.\n\nA good design of code pays off in the long run because well-designed and expressive code is manageable. It is vital for long-term projects, and for projects with a team of several developers as well as for big-sized industrial ones.\n\nThis overarching principle is based on simple notions, but it took me years of practice and study to realize how this is the most central notion of all.\n\nTo prove this principle’s key importance, I will define levels of abstraction, show how a lot of best practices of code are equivalent to respecting them, and finally derive a technique for improving the expressiveness of a given piece of code.\n\n

The What and the How

\n\nWhat are “levels of abstraction” in the first place ? This notion is easy to grasp when you look at a call stack. Let’s take the example of a piece of software dealing with financial products. The user has a portfolio of assets that he wants to evaluate; the value of a portfolio is the sum of the values of all the assets it contains.\n\nabstraction\n\nThis call stack can be read from the bottom up in the following way:\n\n

    \n

  • To evaluate a portfolio, every asset has to be evaluated.
  • \n

  • To evaluate a particular asset, say that some type of probability has to be computed.
  • \n

  • To compute a probability, there is a model that does mathematical operations like +, -, etc.
  • \n

  • And these elementary mathematical operations are ultimately binary operations sent to the CPU’s arithmetic and logic unit.
  • \n

\n\nIt is natural to think that the code at the top of this stack is low-level code, and the code towards the bottom is high-level code. But level of what? They are levels of abstraction.\n\nRespecting levels of abstraction means that all the code in a given piece of code (a given function, an interface, an object, or an implementation) is at the same abstraction level. Said differently, abstraction levels are respected if, at a given level, there isn’t any code coming from another level of abstraction.\n\nA given level of abstraction is characterized by what is done in it. For example, at the bottom level of the stack, a portfolio is evaluated. On the next level, assets are evaluated, and so on.\n\nWhen we move from a higher level of abstraction to a lower one, the execution of the tasks in the less abstract level is how we implement the more abstract level. In our example, evaluating an asset is accomplished by computing a probability. We compute a probability (higher abstraction) with elementary mathematical operations (lower abstraction), and so on.\n\nabstraction\n\nSo the crucial question to constantly ask yourself when you design or write code is: “In terms of what am I coding here ?”\n\n

One principle to rule them all

\n\nI deem respecting the levels of abstraction to be the most important principle in programming, because it automatically implies many other best practices, like keeping it simple (KISS). Let’s see how several well-known best practices are just various forms of respecting levels of abstractions.\n\n

Polymorphism

\n\nMaybe the first thing you thought of when reading about abstraction is polymorphism. Indeed, polymorphism involves providing interfaces or abstract classes to manipulate decoupled implementations of a single concept.\n\nPolymorphism consists of segregating levels of abstraction.\n\nIndeed, for a given interface (or abstract class) and concrete implementation, the base class is abstract and the implementation is less abstract, because the base class describes what it does as an interface, while the implementation code describes how it does it.\n\nNote that the derived class is still somewhat abstract since it is not expressed in terms of 0 and 1, but it is at an inferior level of abstraction compared to the base class. The base class represents what the interface offers, and the derived class represents how it is implemented:\n\nabstraction\n\n

Good naming, encapsulation, cohesion

\n\nLet’s take the example of a class in charge of maintaining a caching of values. This class lets you add or retrieve values of type V with keys of type K.\n\nIt is implemented with a map<K,V>:\n\nabstraction\n\nImagine now that we want the interface to be able to provide the whole set of results at once. Then we add a method to the interface. How do we name this method ? A first try may be “getMap” because it effectively provides the map that associates all the keys to the values in the cache.\n\nBut as you might notice, “getMap” is not a good name. It isn’t a good name because — at the abstraction level of the caching interface — “Map” is a term of how (observe that it appears in the bottom part of the diagram), and not what, so “Map” is not at the same abstraction level as the thing it names. Calling it “getMap” would mix several abstraction levels together.\n\nA simple fix would be to call it “getAllValues” for instance. “Values” is a consistent term with the level of abstraction of the caching interface and is therefore a name that is more adaptable than “Map”.\n\nYou can accomplish good naming by giving names that are consistent with the abstraction level they are used in. This works for variable names, too. Because naming defines levels of abstraction and is therefore such an important topic, we will have a dedicated post about it at a later stage.\n\nBut isn’t it a violation of encapsulation to provide the map of results to the outside of the class in the first place? Indeed, encapsulation is the restriction of access to implementation data inside an object.\n\nActually, the answer depends on whether the very concept of a results container is logically part of the abstraction of the class. If this concept of container is seen as implementation, details then exposing it breaks encapsulation. And if in your design the caching has the responsibility of providing all results at the same time, exposing the concept of container (potentially with read-only attributes) does not break encapsulation.\n\nTherefore, breaking encapsulation means providing information that goes beyond the abstraction level of the interface.\n\nNow imagine that we added a new method in the caching class to do some formatting on values:\n\n\n\nThis is obviously a bad idea because this class is about caching values, not about formatting them.\n\nDoing this would break the cohesion of the class. In terms of abstraction, even though caching and formatting don’t have a what-how relationship, they are two different abstractions because they are in terms of different things.\n\nSo cohesion consists of having only one abstraction at a given place.\n\n

Concision, readability, expressiveness

\n\nLet’s go down to the function (or method) level.\n\nTo continue on the financial example, let’s consider financial indices such as the Dow Jones or the S&P that contain a collection of equities like Apple, Boeing, or Caterpillar.\n\nSay that we want to write a function that triggers saving an index in a database after having done some checks on it. Specifically, we want to save an index only if it is valid, which means, say, having an ID, being quoted on a market, and being liquid.\n\nA first try for the function implementation could be the following:\n\n\n\nWe could object to this implementation on the grounds that it has a complex Boolean condition that could be grouped and taken out of the function for code concision and readability:\n\n\n\nWhen we think about this fix, it is in fact pushing out the implementation of how an index is considered valid (having an ID, quoted, liquid) and replacing it with what the save depends on (being valid), which is consistent with the level of abstraction of the save function.\n\nAn interesting thing to note at this point is that respecting levels of abstraction goes beyond the simple concision of code. Indeed, we would still have done this fix even if being valid only meant having an ID.\n\nThis wouldn’t have reduced the number of characters typed in the code (it would even have slightly increased it), but this would have improved code clarity by respecting levels of abstraction.\n\nLast but not least, there’s expressiveness, which is the focus of my site Fluent C++.\n\nSay that we want to remove some components from the index if they are not valid.\n\nA first trial might write a for-loop to do this, but the best solution here in C++ is to use the remove_if algorithm of the C++ Standard Template Library (STL). STL algorithms say what they do, as opposed to hand-made for-loops that show how they are implemented. By doing this, STL algorithms are a way to raise the level of abstraction of the code to match the one of your calling site.\n\nI think expressiveness is the primary characteristic to strive for in code. This is particularly true for long-term or industrial-strength projects because expressive code is manageable in that it tells what it means to do.\n\nIn expressive code, bugs can be spotted and fixed, new features can be added, and performance can be tuned. By using expressive code, new developers in a project can come up to speed fairly quickly, move forward at a fast pace, and draw satisfaction out of their efforts.\n\n

Transforming obscure code to expressive code: Raising levels of abstraction

\n\n\n\nUnfortunately, all the code out there is not expressive. For instance, you might have legacy code in your system (as many companies do), which is obscure and wastes developers’  energy and motivation.\n\nA technique can be derived from respecting the levels of abstraction that allows you to transform an obscure piece of code into an elegant and expressive one.\n\nIn many cases of obscure code, lower-level code is in the middle of a higher-level layer of the stack — levels of abstraction have been disrespected.\n\nThe problem is code that describes how it performs an action rather than what action it performs. To improve such a piece of code, you need to raise its level of abstraction.\n\nAnd to do so you can apply the following technique:\n\nIdentify what things the code does, and put a label on each one of them.\n\nThis has the effect of dramatically improving the expressiveness of the code. Let’s illustrate with an example. The following case is written in C++, but the technique is not specific to a language, which is what makes it so powerful.\n\nLet’s consider an application where the user can plan a trip across several cities in the country. He would drive straight through from one city to the next if they are close enough (under 100 kilometers, say); otherwise, he would take a break on the road between two cities. The user doesn’t take more than one break between two cities.\n\nWe have the planned route in the form of a collection of cities.\n\nYou need to write a piece of code that works out how many breaks the driver has to take in order to budget his time effectively.\n\nThe existing class, City, represents a city on the route. It can provide its geographical attributes, amongst which are its location, which is represented by a class, Location. And a Location can itself compute the driving distance to any other location on the map:\n\n\n\nHere is a possible implementation of a function to determine how many breaks the driver has to take:\n\n\n\nThis code hasn’t been taken from one codebase in particular, but I have synthesized different techniques I’ve seen in production code or from being advised on the Internet in order to make a realistic example.\n\nThe problem with this code is that it doesn’t say what it intends to do; rather, it invites the reader to work out what is happening in it—this code is not expressive. Let’s use the previous guideline to improve expressiveness: that is to say, let’s identify what things the code does, and replace each one with a label.\n\nLet’s start with the iteration logic:\n\n\n\nMaybe you have seen this technique applied before. This is a trick to manipulate adjacent elements in a collection. it1 starts at the beginning, and it2 points to the element right before it1 all along the traversal. To initialize it2 with something, we start by setting it at the end of the collection and check that it2 is no longer at the end within the body of the loop to actually start the work.\n\nNeedless to say, this code is not exactly expressive. But now we have determined what it means to do: it aims to manipulate consecutive elements together.\n\nLet’s tackle the next piece of the code, in the condition:\n\n\n\nTaken on its own, it’s easier to understand what the code means to do. It determines whether two cities are farther away than MaxDistance.\n\nLet’s finish the analysis with the variable nbBreaks:\n\n\n\nHere, the code increments the variable depending on a condition. It means to count the number of times a condition is satisfied.\n\nIn summary, function:\n\n

    \n

  • Manipulates consecutive elements together.
  • \n

  • Determines if cities are farther away than MaxDistance.
  • \n

  • Counts the number of times a condition is satisfied.
  • \n

\n\nOnce this analysis is done, we are really close to turning this obscure code into a meaningful one.\n\nThe guideline was to put a label over each of the three things the code does, in order to hide the implementation code. Here, we are going to do the following:\n\n

    \n

  • For manipulating consecutive elements, we can create a component that we would call “consecutive,” and that would transform a collection of elements into a collection of element pairs, each pair having an element of the initial collection and the one next to it. For instance, if route contains {A, B, C, D, E}, consecutive (routes) would contain {(A,B), (B,C), (C, D), (D, E)}. In C++ this is called a range adaptor. You can see my implementation here. One such adaptor that creates a pair of adjacent elements has recently been added to the popular range-v3 library under the name of sliding.
  • \n

  • For determining whether two consecutive cities are farther away from each other than MaxDistance, we can simply use a function object that we would call FartherThan. I recognize that C++11 functors have mostly been replaced by lambdas, but this functor here has the slight advantage over a named lambda because it can completely hide the implementation code from the computeNumberOfBreaks function. This can also be achieved with a lambda, but it involves a bit more work (as shown in this post about making code expressive with lambdas). So here let’s just stick with a functor to get the point across:
  • \n

\n\n\n\n

    \n

  • For counting the number of times a condition is satisfied, we can just use the STL algorithm, count_if.
  • \n

\n\nHere is the final result, obtained by replacing the code with the corresponding labels:\n\n\n\n(Note: the native count_if C++ function takes two iterators to a begin and end of a collection. The one used here simply calls the native one, with the begin and end of the passed range.)\n\nThis code shows what it does and is much more expressive than the initial one. The initial one only told how it did the work, leaving its reader to do the rest of the job.\n\nThe above technique can be applied to many unclear pieces of code to turn them into very expressive ones. So next time you stumble upon obscure code that you want to refactor, think about identifying what things the code does and replacing each one with a label.\n\nYou’ll be surprised with the results.\n\nLabeling focuses on the code itself, though. If you want to learn an interesting methodology to writing clean code, you should definitely check out John’s post about how to write clean code.\n\n

Code for the Long Term

\n\n\n\nFollowing the principle of respecting the levels of abstraction will help you make good choices when designing code. This leads to greater expressiveness and robustness in your code, making it an asset for the future of your codeline and your company, rather than a liability.\n\nIf you think about this principle when designing your code and constantly ask yourself the question, “In terms of what am I coding here?”, your code will flow naturally, perform its function well, and be a pleasure to use for the other programmers and developers who have to work with it.\n\nAs developers, expressive code is generally what we call “beautiful” code. And having code that developers find beautiful is something a software company should look for. By identifying what things the code does and replacing each one with a label, we know how to raise levels of abstraction in order to make code more expressive.\n\nAs I indicated throughout the post, many best practices depend on respecting levels of abstraction.

The post Respecting Levels of Abstraction appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/respecting-abstraction/feed/ 1
9 Steps To Approach A Development Task https://simpleprogrammer.com/9-steps-to-approach-development-task/ https://simpleprogrammer.com/9-steps-to-approach-development-task/#comments Fri, 16 Dec 2016 15:00:25 +0000 https://simpleprogrammer.com/?p=18832 As a new developer, I’m trying to focus on producing the best work the least amount of time. This is obviously going to take me longer than a person who has worked for a number of years in development and gained lots of experience. But I believe that establishing the right process now may save...

The post 9 Steps To Approach A Development Task appeared first on Simple Programmer.

]]>
As a new developer, I’m trying to focus on producing the best work the least amount of time. This is obviously going to take me longer than a person who has worked for a number of years in development and gained lots of experience. But I believe that establishing the right process now may save me a lot of time in the future.\n\nNow, I want to recommend a good development method, especially for beginners. I also want to introduce you to steps you should work through before you even start writing any code.\n\n

The Basics of Scrum

\n\n\n\nIn my team, we work using the Agile methodology Scrum. For those that aren’t familiar with the process, here’s a brief explanation.\n\nScrum is a process of working to create a product that is iteratively developed by breaking down all new requests for big features (known as Epics) into bite-sized chunks called Work Items.\n\nEach project usually has a team of five to nine people (the optimum being seven), who work on an agreed set of items for a set length of time known as a sprint.\n\nOur team sprints usually last two weeks, so every two weeks we have a new set of items divided up between the team.\n\n

You Have Your Item, Now Where Do You Begin?

\n\nWhat I found difficult to know when I first began was where to begin my work item, or in other words, what to work on first. Once I’d worked out the most time efficient order in which to complete the tasks, I went about tackling number one on the list.\n\nMoving from testing to development, I didn’t have much experience with unit tests or Test Driven Development (TDD). While I knew it was a good idea to use TDD and write unit tests, it wasn’t imparted upon me to put this knowledge into practice.  So, given the option as a beginner, I generally made the mistake of jumping into writing the code first.\n\n

The Basics of Unit Testing and TDD

\n\nAlthough it’s not expected, our team does try to use TDD. In this system, you write out unit tests to see whether your code produces the correct result for the business logic you’re trying to match.\n\nAfter you have finished development, this yields a quick way to check and see if any issues have arisen within your code, even years later when new functionality is added.\n\nNew functionality means new tests should be written. Eventually, you build up a solid set of tests to fully cover the code you have written, which is known as code coverage.\n\nThe tests that you write are usually located in a separate test project alongside your project within your solution, but this is all dependent upon how your team structures your code base.\n\n

Managing Time Constraints Using TDD

\n\nWhen I’ve used TDD, I’ve found that coding using this method is great for someone new to development. It forces you to break your code down into small, testable chunks to achieve one purpose. This makes you think more about how you are going to structure your code before you write it.\n\nHowever, TDD is very hard to stick to when you’re under time constraints (which is almost always). I did want to try and stick to this technique, but I kept coming up against this issue of time.\n\nI think using TDD was a good step in the right direction for learning how to approach a development task, but I felt some bits were missing. It already assumes you have total knowledge with what you’re doing, and that might not be case. You may even find that once you sit down and read the item yourself, you have deeper questions that weren’t covered before. Because of this, I decided to seek advice from someone older and wiser.\n\nEarly on into my transition from a tester to a developer, I asked my manager the best way to approach a development task. At the time, he’d been developing for about ten years across different technologies and software, so he’s a pretty good source of information.\n\nHere’s the advice I got in 9 simple steps.\n\n

1. What’s your goal?

\n\nTo establish your goal, you need to do three things:\n\n

    \n

  • Clearly understand your work item
  • \n

  • Figure out what the business requires from this change
  • \n

  • Grasp the business value of this change
  • \n

\n\nIf you’re not sure about any of these things, talk to the appropriate people to gain this knowledge before attempting any coding.\n\n

2. Discuss the best way to accomplish your goal with others

\n\nConsult with experienced mentor types on your development team to help you get to your solution quickly. Again, the aim here is to use your time efficiently.\n\nBy all means, try and overcome challenges yourself, but be mindful of the time you spend on it. You should not and do not need to shoulder all the work yourself. No matter what level of experience you have, don’t be afraid to ask for help or turn to the all-knowing Google.\n\n

3. Break down your goal into tasks and objectives

\n\nSmaller chunks are easier to digest; it’s just logical. Before you begin, think about your goal like a computer scientist, what you need to do, and then tackle each task one step at a time.\n\nMaking lists or simply brainstorming what you think is involved is a good way to clearly see the steps you need to take. If you order these steps, it will also help you identify a logical order to proceed. Hopefully, this will ensure less jumping back and forth within code.\n\n

4. Look for similar existing unit tests and run them

\n\nThink about the current functionality that exists in the product you’re enhancing.\n\nIs there anything similar that you can step through and debug to help you make your task easier? If you find any methods like this, try and find tests that execute these methods to check if you can extend them to fulfill your new task.\n\n

5. Write your new test

\n\nIf all else fails, write a brand new test from scratch, but start by writing a test and not by writing the code for your solution. You start by writing the test because you know the outcome you want to achieve. You want to do X to achieve Y.\n\nYou will also have some idea of where your new code will sit within the project. Writing an empty method here for your test to run over will provide you something to build upon and expand in order to make your test pass. Lastly, writing your test now will save you time later.\n\n

6. Solve the task with the minimum amount of code

\n\n\n\nTry and use the least amount of code to write a solution for your task in order to fulfill it. Don’t worry about efficiency yet –– just get it done.\n\nYou will be tempted to try and write code perfectly to ensure the least amount of bugs, the greatest performance gains, and to show off your awesome coding skills. However, you need to keep in mind that doing all this may take you longer to do than solving the initial problem, especially if the task is small. You need to keep in mind that you may be over-engineering a solution or trying to future-proof against scenarios that may never happen. Be efficient with the time you have now.\n\n

7. Make your test pass…

\n\nRun the test over your small chunk of new code. If it passes, great. If it doesn’t pass and the reason isn’t obvious—for example, the condition of the assert wasn’t met—you need to debug the code.\n\nGo through each line, inspecting the value of each variable, property, and return statement.\n\nOnce you’ve found the culprit causing the issue, fix it and ensure that your test passes and fulfills its task.\n\n

8. …Then refactor your code

\n\nNow that your test has passed, you can extend your solution to become more efficient.\n\nDon’t forget that for every new method you may need a new test or two or more. This will depend on the number of ways that block of code can be exited. For example, you could go through the block of code where everything functions as normal and you get the result you expect, like a list of objects. But, there may also be a case where you could go through the same block of code and an error occurs which gives you a list of the same objects but they’re empty. Other ways to leave the code could be a number of different types of exceptions.\n\nThese all would need different tests.\n\n

9. Work back through step 7 – 9

\n\nRepeat steps 7 through 9 to ensure that the changes you’ve made in your code don’t make the test fail. If it does fail, debug the test to find out why.\n\nFeel free to add in as many assertions to verify the outcome of your tests are correct and reliable at any stage.\n\n

And That’s It!  Easy, Right?

\n\nWell, no. Actually, it takes quite a lot of discipline to avoid jumping straight into coding the solution, especially when you’re a junior developer.\n\nHowever, if you want to try and take small steps towards using TDD, you could try an alternative approach. If you write tests as you go along, i.e. after every method you create, you will save yourself time after the development of your features.

The post 9 Steps To Approach A Development Task appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/9-steps-to-approach-development-task/feed/ 2
Will Reading Fiction Make You a Better Programmer? https://simpleprogrammer.com/will-reading-fiction-make-you-a-better-programmer/ https://simpleprogrammer.com/will-reading-fiction-make-you-a-better-programmer/#comments Fri, 25 Nov 2016 15:00:24 +0000 https://simpleprogrammer.com/?p=18653 For programmers who love to constantly learn throughout their careers, general reading can do a lot of good. I don’t mean reading only technical books, or even non-fiction, which is where many of us land when looking through the bookshelves.\n\nReading general fiction can help you improve as a programmer.\n\nHonestly, I didn’t give fiction full credit until...

The post Will Reading Fiction Make You a Better Programmer? appeared first on Simple Programmer.

]]>
For programmers who love to constantly learn throughout their careers, general reading can do a lot of good. I don’t mean reading only technical books, or even non-fiction, which is where many of us land when looking through the bookshelves.\n\nReading general fiction can help you improve as a programmer.\n\nHonestly, I didn’t give fiction full credit until I read Neil Gaiman’s The View from the Cheap Seats. In this book, Neil includes a few essays and articles about why fiction is important. Let’s go into some of Neil’s key points as well as some of my own that I’ve come to realize as I’ve been reading more fiction.\n\n

Reading Fiction Improves Creativity

\n\ncreativity\n\nReading fiction can help improve your creativity. It introduces you to new ideas and thoughts, and, as you read, these ideas will come to life in your imagination.\n\nNot only are you being introduced to new ideas, such as how technology may change and advance in the future, but you can also imagine how those ideas could work in the real world. You may then think about having that type of technology now and how it would impact your life as it is today.\n\nImagine how different the world would be if many important science fiction novels hadn’t been published, and if young soon-to-be scientists and technologists had never read them. Maybe after reading about the three laws of robotics, you will help uncover a key element to improving artificial intelligence.\n\n

Reading Fiction Can Help You Escape

\n\nReading fiction can help you escape the pressures of daily life. Movies and video games can do the same, but it’s good to get away from a computer or TV screen for a while each day.\n\nWhile there are several reasons to unplug from technology, one of my favorites is that I can use what I read from fiction to create discussions with my friends and family. This can spiral into them going into what novels they have read, and we can discuss what ideas we took from those novels.\n\nI’m sure there are plenty of times you wanted to escape the everyday life of programming.\n\nA lot of you may have one or two personal projects that you’re working on at home in your own time. Burnout can happen, and the best way to overcome that is to take a break. What better way to take a break than to sit down and read how a time traveler handles the year 802,701 AD?\n\nTaking an hour or even just 30 minutes a day to read will help you escape your routine and recharge your energy.\n\n

Reading Fiction Is MeditativeMeditation

\n\nMeditation has been shown to help increase creativity and focus, and in relation, reading can be meditative or zen-like. When you focus on reading fiction, you concentrate on the words and imagine the world and characters the author builds for you.\n\nBecause you’re fully engaged in the story, your mind isn’t wandering in a million other directions. Daily reading of fiction can help build this “muscle” of staying engaged in a task, whether it’s reading or something else.\n\nReading fiction can help reduce any stress the day may have brought. We have all heard how bad stress is for our health, and every job will produce stress at some point. Relaxing with a novel will lower that stress, especially when you’re reading about characters who have it rougher than you. For instance, have you ever read the adventure of Frodo taking the One Ring to Mt. Doom?\n\n

Reading Fiction Boosts Empathy

\n\nReading fiction can help boost your empathy by practicing your ability to see the world through other people’s eyes, whether it be the author’s or a character’s.\n\nAs you read, you begin to care for the characters. You will want and hope for the protagonist can overcome their obstacles throughout the story. You will want and hope for the antagonist to fail as they try to stop the protagonist from accomplishing their goals within the story. Who wouldn’t want Edmond Dantes to return to his former life after being falsely imprisoned?\n\nThis involvement with characters practices the empathy “muscle,” and you will start doing more of this type of caring for people in your life. By having extra empathy, developers will care even more about the software they build and how it gives value to their customers, whether it be a product to help them with their jobs or a service to help save them time.\n\nHaving more empathy can also help your work relationships. Instead of writing an email to the boss that will blame someone for a mistake, having extra empathy will cause you to rethink your wording to make it less blaming and more understanding.\n\n

Reading Fiction Helps Improve Memory

\n\nNovels, especially the really long ones, help improve your memory. It’s hard to finish a novel within a day, or even in one sitting. You will have to come back to it the next day to continue reading. That means it could be 24 hours, or more, until you return to the story.\n\nWhen you return, you will have to remember what has happened in the story, so you will know the context of where you pick up the narrative again. By constantly recalling key elements of the story you’re in, you are improving your memory. This will be extremely helpful if you want to start reading War and Peace.\n\nNow, imagine that improved memory being applied to your career. Perhaps you’ll be the one to remember that one important thing said in a meeting no one else took note of. Maybe you’ll be able to remember more of certain documentation you were reading the day before while others may have to reference it again, causing you to be that little bit more productive. Or maybe you are given a task that causes you to go back to something you wrote six months ago, and you can remember what you were writing at that time so you don’t have to go through all of the code again just to understand what it’s doing.\n\n

Reading Fiction Improves Your Writing

\n\nWriter\n\nWriting is important for your career. You write every day, whether it is technical documentation or that email to your boss. What better way to help improve your writing than to read what other authors have written?\n\nIt is a well known fact that reading can help your writing. Reading fiction, in particular, will improve your own writing by giving you a better understanding of the author’s flow and storytelling ability. Non-fiction is typically much drier in tone. With fiction, you get a better sense of how an author keeps their audience engaged in their writing.\n\nGaining instant audience engagement is crucial because, if you lose your readers after the first couple of sentences of your email, they probably won’t read the rest of what you have to say.\n\n

Can You Get the Same Benefits From Non-Fiction?

\n\nWhile reading non-fiction has its own benefits, it will be hard to get the same benefits that reading fiction can give you. Does reading a book on machine learning help you escape the stress of everyday life? While non-fiction helps you learn more about a specific skill or knowledge set, reading fiction will help you relax and wind down from all that you have done today or have to do tomorrow.\n\nRelaxing with a novel can give you other benefits, such as boosting your empathy which is something that reading non-fiction may struggle to give you. Non-fiction can give you new ideas, but those ideas will be more along the lines of current ideas that are already out in the world. Fiction gives the author’s creativity free reign, so it has more “what if” ideas, ideas that explore what the world may one day have, whether for the improvement of civilization or not.\n\n

What’s on Your Reading List?

\n\nReading is something we’ve all been told is good to do, and I hope this article shows that even reading fiction can be beneficial to you as a programmer.\n\nPerhaps reading a science fiction novel will give you an idea for a project that turns you into the next great entrepreneur, or reading the classics will bring you newly-realized revelations or extra relaxation during the evenings.\n\nWhichever novel you choose, I’m sure you will receive most or all of these benefits. Most importantly, though, I hope you enjoy the novel that you pick out to read. There’s nothing better than having a good book keeping you company.

The post Will Reading Fiction Make You a Better Programmer? appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/will-reading-fiction-make-you-a-better-programmer/feed/ 1
Deliberate Practice for Programmers: A Framework for Learning on the Job https://simpleprogrammer.com/deliberate-practice-for-programmers-a-framework-for-learning-on-the-job/ https://simpleprogrammer.com/deliberate-practice-for-programmers-a-framework-for-learning-on-the-job/#comments Fri, 09 Oct 2015 12:00:16 +0000 https://simpleprogrammer.com/?p=14629 Practice, practice, practice \\n\\nLike most programmers, I am passionate about software development; it’s natural for me to want to get better at it. So, often I look up how to do that online.\\n\\nBut it seemed that everywhere I looked, people were saying: “Practice, practice, practice.” I thought: “Ok, so what?” Then, I looked some more...

The post Deliberate Practice for Programmers: A Framework for Learning on the Job appeared first on Simple Programmer.

]]>
Practice, practice, practice

\\n\\nLike most programmers, I am passionate about software development; it’s natural for me to want to get better at it. So, often I look up how to do that online.\\n\\nBut it seemed that everywhere I looked, people were saying: “Practice, practice, practice.” I thought: “Ok, so what?” Then, I looked some more and stumbled on things like: “write more code!”, “Code Katas are the way!” or “a programmer should practice programming by programming.”\\n\\nEver asked somebody about career advice and all you got was “Follow your passion!” It felt the same to me.\\n\\n“Practice is the key to success”\\n\\nWe’ve heard such trite expressions so many times.\\n\\nSuch kinds of advice lead us to exactly one place: nowhere land.\\n\\nI don’t know about you, but when I’m going out on a trip, I don’t want to start the journey without knowing what direction to take.\\n\\n

young man scientist with glasses thinkingHave you actually read before how  developers should practice?

\\n\\nIn my quest for answers on how we developers can perform deliberate practice, I’ve had to read many books, watch many videos, and take copious notes from blogs.\\n\\nNow, I want to save others the same frustration through which I went. I’ve gone through all these notes and books and compiled some of the best ideas into a list that hopefully you’ll love and apply to your work.\\n\\nBelow you’ll find a 7-step framework that we all can try. You’ll then be able to incorporate your own tactics in addition to those I suggest.\\n\\nHere’s an outline of the framework:\\n\\n

    \\n

  1. Set up your measurable goals: know where you’re going.
  2. \\n

  3. Break the goals down into discrete skills.
  4. \\n

  5. Set up your practice plan: the operating procedure for you and your peers.
  6. \\n

  7. Integrate the skill: understanding others’ code.
  8. \\n

  9. Incorporate feedback: staying on target.
  10. \\n

  11. Reflect on your results: avoiding stagnation.
  12. \\n

  13. Apply the law of the vital few: what’s your 80/20 like?
  14. \\n

\\n\\n

1. Set up your measurable goals

\\n\\nNever start an endeavor before having clear goals, especially on large scale projects.\\n\\nGoals should be made clear in your head so that they help you avoid getting distracted by less important work along the way.\\n\\nTo then achieve it, you need to have a sense for what the destination will look like.\\n\\nExample of a bad goal: Understand system X thoroughly by the end of the year.\\n\\nA better goal could be: Understand the 3 most used features, A, B, and C of system X by the end of the coming fortnight.\\n\\nNote a couple of things about this rephrased goal:\\n\\n\\n

    \\n

  1. Sub-goals are clearly defined: ‘thoroughly’ or ‘the 3 most important features’ are too vague unless these 3 are listed.
  2. \\n

  3. They have a deadline that is not too distant. It should be a time frame that you can reasonably estimate.
  4. \\n

\\n\\nYour next steps can include consulting the architecture diagrams, looking at the user interface or asking a colleague for a walkthrough of the application. The idea here is to get a high-level sense of what you can expect to do on the project.\\n\\nDepositphotos_28996605_m-2015Colleagues will be particularly useful for you here: treat them as your software development mentors. Mentors can help you find where it’s more important to focus your energy and how to organise your practice sessions.\\n\\nWhen you have identified your high-level goals, make sure you understand how they all relate to each other. When goals follow each other, they will give you a sense of progress as you complete each one, and an overall direction on the project as well.\\n\\nTip: When you commit to goals, use the principle of consistency by making your colleagues aware of them, thereby making you more likely to keep up with them.\\n\\nFor a few other ideas on how to make this idea work for you, I invite you to read this article that’s based on the Influence book by one of my favorite authors, Robert Cialdini.  It shows you how you can apply one of the most powerful psychological forces in your own life.\\n\\nRemember the saying: You can’t hit a target that you can’t see. Therefore, make sure you know what you want to achieve beforehand.\\n\\nFor each goal, ask yourself these questions:\\n\\n\\n

    \\n

  • Is your goal measurable? How will you know when you complete it?
  • \\n

  • Does it have a definite deadline?
  • \\n

  • Is it clear and focused?
  • \\n

  • What high-level documentation can you use?
  • \\n

  • Whose help will you need to achieve your learning and practice goals?
  • \\n

\\n\\n

2. Break the goals down into discrete skills

\\n\\nAfter you have defined definite and measurable goals, you’ll need to identify what skills you need to achieve them.\\n\\nSmall and well-defined skills are easier to achieve and give you the confidence you need to pursue your goals.\\n\\nThis is where you’ll identify the libraries, frameworks, and even modules of the project itself.\\n\\nFor example: If you’re using Maven, consult the pom files to see them. If you’re using a major IDE, it should have a way to visualize it, e.g. here is an example of how to do it in IntelliJ.\\n\\nAsk yourself:\\n\\n\\n

    \\n

  • Which parts of the libraries/frameworks used should I learn right now?
  • \\n

  • How are the libraries most frequently used on the project?
  • \\n

\\n\\n

3. Set up your Practice Plan

\\n\\nJust like a well-managed software project is broken down into specific deliverables, so should your practice sessions.\\n\\nNext you’ll write a document to comprehensively list all the skills, in what order you need them, and the expected time  each will require to complete.\\n\\nA side-effect of writing this document is that, just like writing the learning tests (see the next step), it is ready to be used by the new developers in your project without needing to repeat the whole process each time.\\n\\nThis will become the operating procedure to which your newcomers will refer and improve upon.\\n\\nKind of questions to ask yourself when writing the Practice Plan:\\n\\n\\nHave you listed all the skills you need?\\n\\n\\n

    \\n

  • Are the skills small and achievable within the time estimates?
  • \\n

  • Will the next person reading this document have everything he needs to get up and running as soon as possible?
  • \\n

\\n\\n

4. Integrate the skill\\n

\\n\\nNow, you’ll learn how to practice this skill in context. Practicing in context will allow you to make progress faster because you will be learning how to  actually use the skill on the project and not just practice without any clear direction.\\n\\nDon’t try to integrate code and learn it at the same time; that will be quite hard. Explore it first and then integrate it.\\n\\nOne approach that you can try is to write “learning tests.”\\n\\n\\nIf there is a library with which you’ll need to be familiar, follow these suggestions to familiarise yourself with it in the context of your project (of course, you’ll still need to consult the reference for the library).\\n\\nThese steps are applicable to third party code as well as the project’s own modules:\\n\\n\\n

    \\n

  1. Look at some scenarios in which it’s being used in the project.
  2. \\n

  3. Write some tests that use the library in such scenarios.
  4. \\n

  5. Verify your understanding of the new concepts by making variations to the concept that will validate your knowledge.
  6. \\n

  7. Then, and only then, you should integrate the code in new code that you write.
  8. \\n

\\n\\nIncidentally, following these steps will force you to think of the long run. The next developer will be able to get started more easily on the project. Learning tests may even help you catch backward compatibility issues that can arise when you later migrate to newer library versions.\\n\\nI first came across this “learning tests” gem in the fantastic book Clean Code by Robert Martin. In it, Martin explains: \\n\\n

“In learning tests we call the third-party API, as we expect to use it in our application. We’re essentially doing controlled experiments that check out understanding of that API. The tests focus on what we want out of the API”.

\\n\\nThe salient point here is to understand that the more your practice resembles new code that you’re going to write, the more effective your learning will be.\\n\\nSo, when integrating the skill, ask yourself:\\n\\n\\n

    \\n

  • Do your practice sessions resemble the kind of work that is expected of you when you’re actually going to use it?
  • \\n

  • Do you repeat the maneuvers at which you’re the weakest?
  • \\n

\\n\\n

Man presses a touch screen smart phone with the symbol of feedb5. Incorporate feedback\\n

\\n\\nFeedback is the critical component to your practice sessions. You use it as a guide to help you know whether you’re on target or not.\\n\\nYou can receive feedback from several sources:\\n\\n

    \\n

  • People, e.g. your team mates/ mailing lists.
  • \\n

  • Tests, e.g. via tests in your development environment, your continuous integration server, etc.
  • \\n

\\n\\nThe feedback loop is the path between doing something and receiving the results. To accelerate your progress, it makes sense to strive to shorten the feedback loop.\\n\\nThis is why automated test practices like Test-Driven Development (TDD) are effective; you can get feedback quickly and easily, whether in your IDE or your reports from your continuous integration server.\\n\\nHere are some other ways you can shorten the feedback loop:\\n\\n\\n

    \\n

  • Configure your IDE to run tests on save/compile. InfiniTest is a plugin for both Intellij and Eclipse that allows you to do just that.
  • \\n

  • If you are writing front-end web apps, use a tool like LiveReload which will refresh your browser page automatically.
  • \\n

  • Test or even run your code in REPLs as is commonly done in Lisp, Scala, and Python environments.
  • \\n

\\n\\nIf you’re a senior developer, consider tracking and rating your developers on how they successfully take action on feedback. Also, don’t forget that making feedback public can help your team build trust and encourage members to push their limits.\\n\\nWhatever the situation, what you need to keep in mind is that  there should be as little friction as possible between trying out an idea and seeing the results of it.\\n\\nAsk yourself:\\n\\n\\n

    \\n

  • Do you regularly receive and give feedback to your team members?
  • \\n

  • Do you consciously set aside time to practice?
  • \\n

  • Have you set up your environment so that feedback loops are kept as short as possible?
  • \\n

  • Are you in the habit of writing fast automated tests?
  • \\n

\\n\\n

6. Reflect on your results\\n

\\n\\nThis step is primordial. Nothing kills progress as much as working on auto-pilot and stagnating on a plateau.\\n\\nAfter seeing your results, you need to reflect on them by asking questions like:\\n\\n\\n

    \\n

  • Why didn’t it work on your previous attempts? Why does it work now when you tried this particular way?
  • \\n

  • How will you apply the lessons learned in this practice session in the future? Can you write these into a ‘Lessons learned’ document and share it with the team?
  • \\n

  • Did you notice anything in the process that you can improve? Is there anything that you can add to the Practice Plan?
  • \\n

\\n\\nAlso, these tidbits from The Pragmatic Programmer can inspire you to find your own ideas:\\n\\n\\n

    \\n

  • Don’t code blindfolded. If you don’t understand the technology or the application on which you’re working, focus on familiarising yourself with the basics first.
  • \\n

  • Document your assumptions. The Design by Contract allows you to do just that; so, consider giving it a try.
  • \\n

  • Don’t be a slave to history; i.e. don’t let existing code dictate future code. If there’s code that needs to be yanked or refactored, be bold about it and make the changes required.
  • \\n

\\n\\nLike Clean Code, I highly recommend that you read The Pragmatic Programmer  too. Mr. Sonmez also agrees that this book is a must-read. Read his review about it here.\\n\\n

7. Apply the law of ‘the vital few’\\n

\\n\\nThis law, more commonly known as the Pareto Principle, essentially means that there is a small subset of all activities that yield the lion’s share of output.\\n\\nThis idea can be especially useful when you’re optimizing for performance (e.g by identifying the methods that are taking up the most resources in your application), but it’s also useful for your practice plan.\\n\\n\\nDo this in three steps:\\n\\n\\n

    \\n

  1. Identify the things that create the most value. When you’re just getting started on the project, these should be the things that you have identified in your Practice Plan. As you get more and more experienced, they could be a lot of other things. Identify some pain points that your team is facing by asking questions like:\\n
      \\n

    • Is there some area that is  known to be regression-prone or hard to maintain?
    • \\n

    • Can I simplify the architecture in the most frequently used areas?
    • \\n

    • Project goals change; so identify the new top priorities and follow the steps in this post again.
    • \\n

    \\n

  2. \\n

  3. Practice them repeatedly. The key here is to repeat this as often as possible until you feel comfortable with it.
  4. \\n

  5. After every few iterations, identify and remove the things that create the least value, add the things that bring the biggest returns, and repeat.
  6. \\n

\\n\\nAsk yourself:\\n\\n\\n

    \\n

  • Where does your team need help the most right now?
  • \\n

  • In which areas are issues most commonly reported?
  • \\n

  • What parts of the source code are known to cause maintainability issues?
  • \\n

\\n\\n

Your next steps

\\n\\nI’ve summarized the seven steps in a flow chart for you:\\n\\n

\\n\\nYou’ll notice from the key above that there is a central theme: being mindful about the craft. Don’t forget there is a ‘deliberate’ in ‘deliberate practice.’ Observe and extract the principles every step along the way.\\n\\n\\nIn the same way as traveling without direction will get you to nowhere land, practicing without intentionality will cause you to perform without it.\\n\\nTake action. Seeing yourself improve will inspire you to believe in deliberate practice even more. So, don’t leave practice to chance, practice and work deliberately.\\n\\n

Information alone won’t help\\n

\\n\\nIf you already knew some of these ideas, don’t go out looking for the shiny new tactic.\\n\\nYou don’t have to follow all the advice on deliberate practice out there (in fact, you shouldn’t try to). Just follow a simple framework and you’ll be fine.\\n\\nAs you get more at ease with practicing deliberately, you’ll have the opportunity to make changes to it and make it work best for you.\\n\\n

Taking this even further\\n

\\n\\nNext StepsTurn your practice session from just an ‘ok’ one to a great one by adopting systems. Earlier I gave an example of one: your Practice Plan. It can serve as your blueprint for getting from a beginner to a master.\\n\\nThink of what parts of your work can be systemized. \\n\\n

Other recommended resources\\n

\\n\\n

\\n\\nTo give other readers some ideas on how to take action, do share examples in the comments on how you’ll apply this to your work. I can’t wait to see what you think of!\\n\\nYou can also check out my course “10 Steps to Learn Anything Quickly” for methods to optimize your learning.

The post Deliberate Practice for Programmers: A Framework for Learning on the Job appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/deliberate-practice-for-programmers-a-framework-for-learning-on-the-job/feed/ 9
KISS — One Best Practice to Rule Them All https://simpleprogrammer.com/kiss-one-best-practice-to-rule-them-all/ https://simpleprogrammer.com/kiss-one-best-practice-to-rule-them-all/#comments Wed, 19 Aug 2015 12:00:07 +0000 https://simpleprogrammer.com/?p=14193 Why KISS isn’t easy \n\nLet’s talk about KISS, or “Keep It Simple, Stupid” as a principle for effective Software Engineering.\n\nBut before I go any further, just think a little about your favorite best practice when writing code. Is it DRY—Don’t Repeat Yourself? Or are you more a YAGNI—You Aren’t Gonna Need It—person? Do you follow...

The post KISS — One Best Practice to Rule Them All appeared first on Simple Programmer.

]]>
Why KISS isn’t easy

\n\nLet’s talk about KISS, or “Keep It Simple, Stupid” as a principle for effective Software Engineering.\n\nBut before I go any further, just think a little about your favorite best practice when writing code. Is it DRY—Don’t Repeat Yourself? Or are you more a YAGNI—You Aren’t Gonna Need It—person? Do you follow SOLID principles? Or are you really sick and tired of all these abbreviations we have in IT, and just use common sense instead?\n\nkeep it simple, stupid - KISS principleNo matter what your style of coding is, it should follow one rule: Keep It Simple, Stupid!\nSo what should I tell you about KISS? It really just means you have to keep it simple. Simple code is less prone to bugs, and is easier to read and understand for you and the people who’ll be working on the code in the future (including yourself). And now you’re probably thinking you’re already doing that. Duh, why would you write complex code? Maybe you even think of yourself as not being a good enough programmer to write complex code! Let me tell you why this is probably not the case.\n\nKeeping things simple is, ironically, not simple! It requires abstract thinking. It requires knowledge of the domain you’re working on. It requires knowledge of the code, the framework, and the language you’re working with. It requires experience. In fact, let me present you this quote by Martin Fowler:\n\n

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.\n—Martin Fowler

\n\nThink about it for a second—how much code have you seen that was easy to read, that was simple enough to understand? Probably not a lot. And who wrote that code? Were they beginners, hobbyists, seniors? Perhaps you’ve seen code from all those people—chances are, they were all complex monsters. Actually, if you looked at the code closely you’d probably find it littered with so-called “anti-patterns!” But here’s the deal: the same goes for your code. You might understand it (now), but come back in a couple of years (or even months) and look at it again.\n\nBut why is so much code not simple? There just aren’t a lot of people that possess the skills I just laid out: abstract thinking, knowledge of the domain, and technology. Some people just like to show off with complex code. Programmers often like to be “clever” and make code more complex than it has to be (because, let’s be honest, using Reflection to get a properties value is much more fun than just getting the value).\n\nMany programmers just get stuck in a certain train of thought, which isn’t necessarily the right train of thought. In general, each programming task can be performed in countless ways. To fetch data from a database, you may write a stored procedure and call it using ADO.NET or Entity Framework (assuming you use .NET); or you may write the query in your code base using ADO.NET; or perhaps you’re going to write a LINQ query with Entity Framework (or LINQ to SQL, or maybe you’re still stuck with Typed Datasets).\n\nNow, if we were going to count the ways in which you can write your SQL or LINQ query, you’d soon come to the conclusion that literally hundreds of ways exist to do something as simple as get data from a database. And that is usually just a small step of a bigger process, so count the different ways you can complete that process, multiply it by the different ways you can get data from a database, and the ways you can write this process probably gets close to an infinite number. Unless you’re in Tenacious D, who just so happened to play the best song in the world, you’re not going to write the best code in the world.\n\n

Applying KISS

\n\nSo how, then, can we write simple code? What I’m going to say now may be a little controversial, but I’m a big fan of counting the number of lines in my code base.\n\nActually, to be more precise, I count the number of statements in my code. A statement is an action a program takes—for example, declaring and/or assigning a variable, calling methods, looping through a collection, and so on. Most languages allow nesting statements or putting multiple statements on a single line, so lines of code obviously aren’t going to help much.\n\nBill Gates had similar feelings about counting lines:\n\n

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.\n—Bill Gates

\n\nStill, when I inherit a project, I like to take a look at the line count in files I need to work with. If the line count is thousands of lines of code, then the file, and likely the entire project, probably isn’t KISS.\n\nLess is More Minimal Simplicity Efficient Complexity ConceptBefore you go and write me hate mail on why number of statements is a bad measure, let me explain why I think it’s actually pretty valid. First of all, if people read our code, there’s simply going to be less to read. Less to read means less for them to understand. Less is more, right? Second, less statements means less debugging! If there’s a bug in your code, you’d rather check ten statements than a hundred statements.\n\nAnd last, but not least, each statement you write contains a potential bug. “That’s stupid,” you might say, but think about it: a program written in hundred statements is less likely to contain bugs than the same program written with a thousand statements (assuming the latter just has a lot of unnecessary calculations and overhead).\n\nLet’s look at a real world (C#) example. Suppose we have a function that takes a string as input and returns a bool indicating whether the input is numeric (more precisely, an Int32). Here’s what I think we can do. We can loop through the characters and use Char.IsDigit to check if every character is a digit. If we find one that isn’t, we return false; otherwise, we return true. We can also use a Regular Expression to match the input with all numeric values. Last, we can use Int32.TryParse, which would actually give us the converted input as well, but we can discard it.\n\nSo here are the three functions:\n\n\n\nI’ve actually seen a combination of looping through the characters and using RegEx to match each character with the [0-9] pattern… Obviously not KISS!\n\nThat already exposes a problem with the RegEx solution. RegEx is just difficult. It’s great to solve some problems, but it already brings an initial complexity to the table that most programmers aren’t familiar with.\n\nIn this case, we need to make sure the entire input is matched, and not just a part of the input. The programmer who used the loop with RegEx probably wasn’t aware that the start and end of an input can be indicated in RegEx with ^ and $, so the [0-9] pattern would only work for single characters. Therefore, the RegEx solution is not KISS (even though it has the least statements).\n\nThat leaves the TryParse and IsDigit solutions. In this case, I’m simply going for the least statements rule, and IsDigit isn’t KISS. Now I’ll let you in on a little secret. The TryParse solution is the only one that isn’t bugged. IsDigit and RegEx don’t recognize the – character for negative values, but they do return true for 2147483648, which isn’t an Int32 (overflow).\n\nThere’s another problem with the RegEx and IsDigit examples. We’re trying to reinvent the wheel. One rule that’s certainly KISS is not to do that. We already have a function that checks if something is an Int32, so let’s just use it. Obviously, the programmer who used a mix between the IsDigit and the RegEx solution didn’t know about TryParse (or about Char.IsDigit), so it presents a problem if someone isn’t aware of this KISS solution.\n\nWhen I’m faced with a challenge that isn’t specific to my domain, I usually wonder if my problem was already solved. A quick Google usually does the trick. Googling for “c# check if string is numeric” will return all of the above solutions, so use your best judgement. If you find nothing, or none of the found solutions fit your requirements, Google some more.\n\nOnly after that should you be allowed to conjure up your own solutions. All of the “reinvented” code I’ve seen was bugged, including functions for DateTimes, security, and commonly-used algorithms. Those problems are widely known and can be solved by (standard) libraries written by people who are much more experienced with the material than you are, so use them. Here are some principles I follow when coding.\n\n

    \n

  • Keep the scope of variables as small as possible. For example, don’t declare a variable outside an if-block if it’s only used within the if-block. The less declared variables you have at any given time, the less you have to worry about.
  • \n

\n\n

    \n

  • Don’t re-use variables (unless in a loop). I’ve seen code reusing a variable like i for temperature, height, and time. Just declare three variables, name them properly, and use them only for what they represent. Failing to notice a variable has a different meaning or use in other parts of the code can lead to some very strange bugs.
  • \n

\n\n

    \n

  • Keep functions as small as possible and make sure they do just one thing. I’d rather have ten functions doing just one thing than one function doing ten things.
  • \n

\n\n

    \n

  • Use proper naming for your variables.
  • \n

\n\n

    \n

  • DRY: Don’t Repeat Yourself. I’ve already mentioned it, but it’s worth mentioning again. If you have duplicated code, try to make a function out of it.
  • \n

\n\n

    \n

  • YAGNI: You Aren’t Gonna Need It. Also mentioned before. Don’t code more than you currently need; just write the simplest thing that would make your use case work.
  • \n

\n\n

    \n

  • SOLID: This actually stands for a bunch of principles. Every object-oriented programmer should know them. It is perhaps equally important to know when NOT to use them! I will not explain them here, but SOLID on Wikipedia gives a nice overview.
  • \n

\n\nCoincidentally, all these principles happen to be KISS. It’s not easy to put them into practice, especially SOLID; but once you know them you can write better, maintainable, and above all simpler software. They might be open doors for you, but unfortunately there are some sloppy programmers out there who don’t follow any of those rules. Don’t be that programmer.\n\n

Designing with KISS

\n\nYoung business man drawing a graph on a glass window in an office Let’s also look a little at the bigger picture with an example. Say you’re writing a program for a company that has a sales department, and now they want to show some statistics for each salesman.\n\nIn this application, you pick a salesman and the application shows the customers of this salesman, how many orders he’s made, how much money he has earned you, maybe how much provision he’s getting, and other similar data. What would be KISS?\n\nI’m just going to “think out loud” in an abstract manner on how I would write this code. Maybe the user chooses a salesman and presses a button. On the button click, our (pseudo) code could look something like this:\n\n\n\nEach statistic needs only one function call, so that’s as few statements as possible.\n\nJust a quick disclaimer: I wouldn’t use var like that in production code, since it makes our code less readable!\n\nSeems pretty KISS, right? Actually, it’s not! Let’s drill down a little deeper.\n\nJudging from the method signatures, all of these functions need to acquire two pieces of information: the selected salesman and their respective statistic. Why would a function to get a statistic also get a salesman? That’s not KISS—that’s just weird and against our best practice of keeping functions small and assigning them a singular task.\n\nSo here’s a better version of the code:\n\n\n\nBy just thinking about this a bit, we’ve eliminated repeating code before actually writing it in the first place. That certainly gets the overall number of statements way down. Additionally, the GetSalesManStatisticX methods are now simpler since they only do one thing (get the statistic).\n\nAs an added bonus, the methods just became reusable (just in case we ever need to get statistics for an additional salesman).\n\nNotice that this isn’t against YAGNI, since we actually need this code now. Would this do the trick? Maybe… But chances are, each of those methods has to do a roundtrip to the database. Could they be accessing the same data? Probably!\n\nSo we should combine some of those functions for two reasons. First, and actually most important: getting data from the database can take a while. Doing this multiple times can be a huge performance hit! So always try to get a piece of data just once.\n\nSecond, if our functions are getting the same data, we are probably repeating our code. So we now have a few options. I won’t say one is better than the other, but here they are. How about having a function that gets the data and passes it as input to the functions?\n\n\n\nPerhaps we could have a single method that calculates and returns all statistics at once.\n\n\n\nPerhaps we can do all our calculations in the database.\n\n\n\nDepending on the complexity of the calculations, I would probably go with the first or third method (although there are some pros and cons to putting these calculations in your database as well). The takeaway here is that all proposed solutions solve the problem of doing multiple round trips and fetching the same data.\n\nThis is actually a real-life example. A project I worked on used the first method I illustrated, just separate method calls that all get their own statistic. Things didn’t end well when the data became bigger and more statistics were added. Lots of repeating code and redundant database calls. It’s not hard to see why this method was chosen, however, as it seemed pretty KISS at first.\n\nThat also shows that being KISS is not easy. There is not one way to do things, and it takes knowledge and experience to pick a good method out of the infinite options for writing your code. I’ve found that a little common sense goes a long way.\n\n

Getting KISS!

\n\nhappy male office worker showing thumbs upSo how can you become better at writing KISS code?\n\nFirst of all, just read up on best practices! Here’s a book I can recommend: Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin. If my recommendation isn’t enough, John recommends it too in his book, Soft Skills! So be sure to read it. Also by Robert C. Martin is this series on SOLID principles, which you should really read and put into practice.\n\nSecond, be sure you Google for solutions before inventing them yourself. Googling effectively is a skill in itself. Sometimes I don’t call myself a programmer, but a professional Googler! In these times, being a good Googler can really separate you from the flock. You can’t know everything, but you can Google everything.\n\nWhile we’re on the subject, don’t trust everything you read on the web. Even MSDN/TechNet has some articles that showcase bad practices! Keep using your common sense.\n\nJust practice, practice, practice! Practice makes perfect, or so they say.\n\nThen read code—lots of it. Find out what works and what doesn’t.\n\nAnd last, but not least, make sure your code is read too. Ask colleagues if they agree with your coding practices. If they don’t understand your code, don’t assume they’re just too stupid to understand it. Ask them how you could improve it. If you don’t trust your colleagues, or if you don’t have any, write about your code, start a blog (using John’s free blogging course), write for websites like CodeProject, or just ask a quick question on CodeProject or StackOverflow.\n\nIf you can apply KISS to your code, that certainly makes you stand out as a programmer. You can do something most people can’t. That’s gotta be worth something.\n\nGood luck, and happy coding!

The post KISS — One Best Practice to Rule Them All appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/kiss-one-best-practice-to-rule-them-all/feed/ 51
Why Comments Are Stupid, a Real Example https://simpleprogrammer.com/why-comments-are-stupid-a-real-example/ https://simpleprogrammer.com/why-comments-are-stupid-a-real-example/#comments Mon, 13 Apr 2015 15:00:00 +0000 https://simpleprogrammer.com/?p=13460 Commenting on your code makes you a good Software Engineer, right? Nothing seems to stir up religious debate more so than when I write a post or do a YouTube video that mentions how most of the time comments are not necessary and are actually more harmful than helpful. I first switched sides in this...

The post Why Comments Are Stupid, a Real Example appeared first on Simple Programmer.

]]>
Commenting on your code makes you a good Software Engineer, right?

Nothing seems to stir up religious debate more so than when I write a post or do a YouTube video that mentions how most of the time comments are not necessary and are actually more harmful than helpful.

I first switched sides in this debate when I read the second edition of Code Complete.

In that book, Steve McConnell, made it abundantly clear to me that the reasons I was putting so many comments in my code was that:

  • I wasn’t naming things in a way that would make explanatory comments unnecessary
  • My methods and functions were far too large and thus needed extra explaining

The way I wrote code drastically changed.

I had believed I was doing a good job, and being a dutiful programmer by writing comments to explain my code and make it easier for the next developer to understand them.

But, when I started applying what I learned in Code Complete, and started writing code that was often more clear than the comments I was previously writing, I realized that I was doing a greater favor to any developers who would inherit my code than simply writing comments. I was keeping it simple – obeying the KISS principle – and making my code even more clear.

When I read Uncle Bob’s book, Clean Code, my position further strengthened.

Not only did Uncle Bob say we should avoid comments, he said—and showed—how comments, more often than not, indicated a failure to express intention in code.

Bob made me realize that I was still leaning too heavily on comments and that I needed to further improve my naming and strive to have my code communicate its intention without the need of outside aid.

Showing a real comment-removing example

Now, this was my own personal progression—and I don’t expect everyone to have the same experience I did, or even to see things the same way—but, I do feel there is still a large amount of ignorance that seems to spew forth whenever I mention that comments should generally be avoided in favor of more communicative code.

For a while now, I’ve felt the burden of needing to back up what I am saying.

It is one thing for me to extol the value of clear, communicative code, but it is another thing for me to show how clear—or as Uncle Bob would put it “clean”—code is far more understandable and maintainable than equally “good” code that is heavily commented.

At first I was going to make up some code example to show you how this is the case.

I was going to write some code that was not named very well and full of comments, and then show you how I could refactor that code to get rid of the comments and actually increase the clarity.

But, I know from experience that is a trap.

Too many people will cry foul and claim I have setup a “straw man” that didn’t represent real world code.

Fortunately, I realized an excellent opportunity that is now open to me.

Refactoring some real code from the .NET framework

Since Microsoft decided to open source the entire .NET code base, I decided I would instead pick a real example of real code that is not bad, but just could be refactored to eliminate comments and still make the code just as clear—and in my opinion clearer.

I’ve just pulled out one method in this code, SplitDirectoryFile, to illustrate my point.

I don’t know who wrote this code, and I don’t even consider this code bad. I’m just using it as an example, so keep that in mind.

I picked a fairly small method, so that it could be easily understood and fit into this blog post, but my general approach could be applied to much larger swatches of code.

Let’s take a look at what the code looked like before I refactored it:

Like I said before, this code isn’t bad.

It’s pretty clear what it is doing.

The comments even make sense.

But, could we eliminate all of these comments and actually make the code more understandable?

Let’s start with the first comment. It seems innocent enough.

// assumes a validated full path

Is there was way we can communicate this in the code?

Replacing a comment with a better parameter name

What if we change the name of the variable from path to validatedFullPath?

Not a huge difference—almost trivial—but, not only have we eliminated a comment, we’ve made it so someone calling this method can tell from the variable name that they are not just supposed to pass in a path, but a validated full path.

Again, seems like a rather small change, but, I do believe it has made the code more clear.

A bit of a bigger change…

Moving on, we can take a look at the next comment:

// ignore a trailing slash

Now, there are a few ways we can handle this one.

We can simply replace the comment with a method, so we have:

if (ShouldIgnoreTrailingSlash(length, rootLength, validatedFullPath)

length–;

We could also create a simple boolean variable to replace the comment:

bool ShouldIgnoreTrailingSlash = length > rootLength && EndsInDirectorySeparator(validatedFullPath);

if(ShouldIgnoreTrailingSlash)

length–;

Another, perhaps better possibility, would be to do something like this:

length = LengthWithoutTrailingSlash(length, rootLength, validatedFullPath);

But, I see an opportunity here to improve the overall readability and structure of the code and get rid of a comment.

How about this refactor?

It might seem like overkill here, but I think it makes a lot of sense to make this static method into an actual class.

We can then very clearly communicate what the class is supposed to do and utilize the state of the class to simplify the code.

Trying to cleanly remove comments led me to this refactoring of the method itself, because I found that the clearest way to express the intent was to encapsulate it.

Now, you might not agree with this particular refactoring—and that is fine—but I’m sure you can still see how we can easily eliminate comments by expressing the intent in the code more clearly.

Now it gets easy

From here, it is trivial to get rid of the next comment:

// find the pivot index between end of string and root

All we have to do is change this into a method that says exactly what it does.

https://gist.github.com/simpleprogrammer-shared/372ed51cc310d20ead580ac702be5942

Again, I couldn’t resist changing the structure a bit as well.

I moved the Directory and File to properties on the class instead of out parameters on the method.

But, that isn’t as important as removing the comment and replacing it with a method that says the same thing while providing an abstraction on top of the logic.

I also pulled out the idea of finding the pivot into a variable, so we could use that state, explicitly rather than counting on an early return. (Which wasn’t even explained by a comment.)

Now the intent is much more clear. If we didn’t find a pivot we just want to return the trimmed directory.

The final refactor

That brings us to our final refactor:

We’ve simply extracted the trimming of the directory into a method that says exactly what it does.

Now, in my opinion, this code is much more clear, yet it has zero comments.

I can quickly look at this code and understand exactly what it is doing.

The structure and naming of the variables and methods communicates in a much more precise and clear way what was being communicated in the comments of the original code.

Compare and contrast

Take a look at the original code versus this refactored code and see which one you think is easier to understand and maintain.

Specifically compare the main method doing the work in each case:

Yes, I have changed the structure of the code to make it a class and I’ve replaced the out parameters with properties, but I could have achieved a similar result just getting rid of comments and replacing them with code and variable names that were more expressive. (Although, in this particular case, I’ll admit the out parameters makes things a bit more difficult.)

Code without comments is easier to maintain

Nevertheless, I’d make the argument that trying to write code in a way that the code expresses the intent rather than relying on comments causes you to structure code in a better way which results in more cohesive classes and a better overall structure.

Whether you think I’ve made things better or not, one thing you can perhaps agree on is that I certainly haven’t made things worse.

And if you can refactor from comments to no comments without losing clarity, it’s a net win in my book, because code gets updated, comments do not. (At least they often do not.)

And remember, this was an example with some already decent code, where the comments weren’t very extraneous.

Most commented code I see doesn’t look like this at all.

In the code, the variables already had pretty good names and the comments talked about what the logic did, not how it did it.

Most of the commented code I see uses comments as a crutch for code that is not very clear at all.

So, in a sense, I picked a bad example.

I didn’t cherry-pick some crappy code with bad comments and make it better by removing them—that would have been easy.

Anyway, I await the barrage of angry commentators (no pun intended.)

What do you think?

Have I convinced you at all?

Can you at least see why writing code without comments isn’t lazy, but could actually be beneficial—or at the very least a matter of taste?

Here’s a practice that isn’t a stupid: marketing yourself. Your success won’t be defined solely on your technical skills — learn more in my course “How to Market Yourself as a Software Developer”

The post Why Comments Are Stupid, a Real Example appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/why-comments-are-stupid-a-real-example/feed/ 204
Why I Don’t Do Code Katas https://simpleprogrammer.com/dont-code-katas/ https://simpleprogrammer.com/dont-code-katas/#comments Mon, 26 Aug 2013 14:30:44 +0000 https://simpleprogrammer.com/?p=5683 “Want to improve as a programmer? It’s about practice, practice, practice..”\n\nI don’t want to seem like I am bragging, but there is something I just have to get off my chest.\n\nBut, before I tell you what amazing skill I have mastered through countless hours of boring practice, let me tell you a bit about my...

The post Why I Don’t Do Code Katas appeared first on Simple Programmer.

]]>
“Want to improve as a programmer? It’s about practice, practice, practice..”\n\nI don’t want to seem like I am bragging, but there is something I just have to get off my chest.\n\nBut, before I tell you what amazing skill I have mastered through countless hours of boring practice, let me tell you a bit about my training schedule.\n\nEveryday I get up in the morning. I put on my shoes. I begin my practice.\nUsually I start with a small warm-up, just to get the blood flowing on the way to my office at the end of the hall.\n\nLater in the day, I’ll wander out of my office for lunch and practice more on the way to the kitchen.\n\nRight now as I am typing out this blog post, I am on the treadmill honing my craft one painstaking repetitive step at a time.\n\nThat is right, you may have guessed it by now—I am a master walker.\n\nAll my life I have been practicing this humble skill.  Each and every day I practice my secret craft.  I see other fools riding around on mopeds and motorized scooters sheepishly talking of their perceived skill at bipedal transportation.  But, although outwardly I acknowledge their words, inwardly I know that I am special, because I hone my skill to a craft.\n\nSounds ludicrous?  That is what it sounds like to me when some people talk about doing code katas.\n\n

Code Katas

\n\nWhat is a Code Kata you may ask?  Some people think a Code Kata is when you solve the same programming problem over and over again, thinking you are actually practicing something other than using shortcuts in your IDE. (To be fair, not all people view Code Katas that way.)code kata\n\nThese kinds of Code Katas come from a failed attempt to forcibly simulate in coding the same kind of practicing that a musician or athlete would perform in order to become better at their vocation.\n\n

Why Code Katas aren’t effective

\n\nDon’t get me wrong, the intention behind Code Katas seems to be well placed, and I am all for software craftsmanship (although not the elitism that sometimes accompanies it.)  But, just as walking every single day doesn’t make you a master walker, and driving a car every day doesn’t make you a superior driver, solving the same sets of programming problems over and over again won’t make you a master programmer.\n\nIf you still have your doubts, consider old people.  Old people are not master walkers or master drivers, yet they have been doing both of those activities day in and day out for many years.  Not only do they not master these skills, the skills actually atrophy—they become worse at them, and not just because their muscles and reflexes become worse from age, it is because repeating the same thing over and over again without an increasing level of challenge actually results in the mind becoming complacent with the activity which leads to the eventual degradation of it.  (At least, this appears to be the case to me.)\n\nDon’t lose hope though, a little later on I will tell you a real way to practice your craft in software development—one that will give you results—but, first let’s dissect the cases of walking and driving a little bit further to see why repeated practice of those activities seems to have diminishing returns.\n\n

Doing the same thing over and over again doesn’t make us better at it

\n\nWe first learn from walking and driving, because everything is new and challenging.  Although walking seems like a repetitive process, it is actually the lack of repetition that provides the challenge our brain and body need to actually benefit from it.\n\nAs a toddler learning to walk or a teenager learning to drive, we are constantly bombarded with new scenarios and challenges that we haven’t faced before.  What happens when the dog runs by and brushes our leg?  How does this affect our balance and what do we have to do to adjust?  What about this new surface?  The carpet seems to absorb our feet and create more friction when we attempt to walk on it.  How do we compensate to balance on this surface?  Walking with socks on the floor gives us less grip, etc.cute baby girl making first steps, colorful outdoors\n\nBut, as an adult, or experienced walker or driver, we are not challenged in nearly the same way;  we’ve already seen most of the scenarios.  Our daily commute to work rarely presents us with an unfamiliar stimulus or problem to solve.  We operate on autopilot, automatically walking and driving to our destinations without much effort or thought.\n\nRepeatedly writing the code to solve the same programming problem over and over again is exactly the same thing, except unless you are introducing new challenges by adding constraints and twists, you are only benefiting from the exercise the first, and perhaps, the second time, you undertake the activity.\n\nNow, not all programmers who do Code Katas repeat the exact same code over and over again.  Some of them attempt to solve the same problem, but this time not using any loops or limited the line count to a certain number or some other similar constraint.   This kind of practice is actual worthwhile practice which challenges the mind and introduces new scenarios that create new neural pathways in the brain and strengthen others. (Here is a great example of book that encourages you to do just that.  I highly recommend working through the problems in this book.)\n\nSimply typing the same code into the same IDE over and over again for 10 minutes a day may make you feel relaxed and calm or even like a concert violinist arduously practicing their scales, but at the very best it will make you faster at using your IDE and typing code; skills which can be easily practiced through the course of a normal day’s work.  If you want to be really good at writing the code to sort lists of words and calculate prices for grocery store items in a cart, go ahead, be my guest.\n\n

How real mastery is achieved

\n\nIf you are resisting what I am saying at this point, it is likely because you still mistakenly believe that walking and driving are in a different category than playing music, sports and programming.  But, the truth of the matter is that walking, running, music, sports, and programming are in the same category, or rather, there are no categories.\n\nIt turns out there are actually master walker and master drivers.  One sport that is not all that widely known goes by the name of Parkour or Freerunning.  Don’t believe me, check out this video for an example.  In this sport, the athlete becomes exceptionally good at traversing around everyday locations on their own two feet.  It is amazing what some of these practitioners can do—just watch the video if you don’t believe me.\n\nAnd as for driving, I probably don’t need to convince you that Nascar is “kind of a big deal.”\n\nMy point is that you are not going to become a Parkour expert or Nascar driver by just walking around your neighborhood or driving your car to and from work, even if you do tend to drive like a bat out of hell.  To get to that level of skill in those seemingly mundane activities, you have to constantly practice at a higher level of difficulty and continually introduce new challenges.\n\nIn fact, when we actually look at what real musicians and sports athletes do, it is much of the same.  I seriously doubt many musicians you hear on the radio or see in concert repeatedly played “bah bah black sheep” or “twinkle twinkle little star” on their instruments until one day they achieved mastery.  And in the professional sports world, achievement only comes through repeatedly pushing beyond one’s limits day after day.\n\nThe point is this: if you want to get better at something, repeating practice alone is not enough.  You must practice with increased difficulty and challenge.\n\n

How to improve your programming skills

\n\nSo, how then do you become a master craftsman at the vocation of software development?  If you don’t use Code Katas, how do you practice your craft?\nLet me start off by giving you the best example I have ever seen.\n\nThis is Jennifer Dewalt’s blog; she decided to learn to code by building 180 websites in 180 days.  While you are sitting at your keyboard typing the same 20 lines of code into your IDE over and over again, Jennifer is creating a new thing every single day and facing a brand new challenge.\n\nWho do you think will improve their skills more after 180 days, you or Jennifer?  I know who I’d hire without even thinking twice.\n\nI get lots of emails asking me about the best way to learn programming or how someone can improve their skills.  Recently, I’ve gotten a lot of emails asking about how to learn Android development.  Do you know what I tell all these inquisitive minds?\n\nMake Android apps.\n\nBut, umm, what book can I read?\n\nNo book, just come up with an idea and try to create it.  Figure out what you need to do along the way.  When you get stuck, go look for the answer or seek help.\nBut, I need to know what I am doing first.\n\nSays who?  Do and then learn.  Learn and do at the same time, reading a book or repeating the same exercise over and over again won’t make you smarter or more skillful; constantly challenging your mind and current skills will.\n\n

Want to learn more?

\n\nI’ve got plenty more to say on the topic and many more techniques that are way more effective then Code Katas which you can use to hone your programming skills.  I can’t fit it into a single post like this, but I’ll be putting it into the top secret project I am working on to help developers boost their careers and learn to market themselves.\n\nIf you’d like to be one of the first to be notified when it is available, sign up here.  I’ll be including lots of practical valuable information that you probably won’t find anywhere else.\n\nSo, what do you think?  Do you do Code Katas right now?  If so, do you think they are actually useful?  Let me know in the comments below.

The post Why I Don’t Do Code Katas appeared first on Simple Programmer.

]]>
https://simpleprogrammer.com/dont-code-katas/feed/ 31