How should somebody new to coding get started learning a language and maybe even automating something? Where should they begin?

 

It's probably obvious that there are a huge number of factors that go into choosing a particular language to learn. I'll look at that particular issue in the next post, but before worrying about which arcane programming language to choose, maybe it's best to take a look at what programming really is. In this post, we'll consider whether it's going to be something that comes naturally to you, or require a very conscious effort.

 

If you're wondering what I mean by understanding programming rather than understanding a language, allow me to share an analogy. When I'm looking for, say, a network engineer with Juniper Junos skills, I'm aware that the number of engineers with Cisco skills outnumbers those with Juniper skills perhaps at a ratio of 10:1 based on the résumés that I see. So rather than looking for who can program in Cisco IOS and who can program in Junos OS, I look for engineers who have an underlying understanding of the protocols I need. The logic here is that I can teach an engineer (or they can teach themselves) how to apply their knowledge using a new configuration language, but it's a lot more effort to go back and teach them about the protocols being used. In other words, if an engineer understands, say, the theory of OSPF operation, applying it to Junos OS rather than IOS is simply a case of finding the specific commands that implement the design the engineer already understands. More importantly, learning the way a protocol is configured on a particular vendor's operating system is far less important than understanding what those commands are doing to the protocol.

 

Logical Building Blocks

 

Micro Problem: Multiply 5 x 4

 

Here's a relatively simple example of turning a problem into a logical sequence. Back in the days before complex instruction sets, many computer CPUs did not have a multiply function built in, and offered only addition and subtraction as native instructions. How can 5x4 be calculated using only addition or subtraction? The good news for anybody who has done common core math (a reference for the readers in the USA) is that it may be obvious that 5x4 is equivalent to 5+5+5+5. So how should that be implemented in code? Here's one way to do it:


answer = 0  // create a place to store the eventual answer
answer = answer + 5  // add 5
answer = answer + 5  // add 5 (2nd time)
answer = answer + 5  // add 5 (3rd time)
answer = answer + 5  // add 5  (4th time)

At the end of this process, answer should contain a value of 20, which is correct. However, this approach isn't very scalable. What if next time I need to know the answer to 5 x 25? I really don't want to have to write the add 5 line twenty-five times! More importantly, if the numbers being multiplied might be determined while the program is running, having a hard-coded set of additions is no use to us at all. Instead, maybe it's possible to make this process a little more generic by repeating the add command however many times we need to in some kind of loop. Thankfully there are ways to achieve this. Without worrying about exactly how the loop itself is coded, the logic of the loop might look something like this:


answer = 0
number_to_add = 5
number_of_times = 4
do the following commands [number_of_times] times:
  answer = answer + [number_to_add]
done

Hopefully that makes sense written as pseudocode. We define the number that we are multiplying (number_to_add), and how many times we need to add it to the answer (number_of_times), and the loop will execute the addition the correct number of times, giving us the same answer as before. Now, however, to multiply different pairs of numbers, the addition loop never needs to change. It's only necessary to change number_to_add and number_of_times.

 

This is a pretty low level example that doesn't achieve much, but understanding the logic of the steps taken is something that can then be implemented across multiple languages:

 

sw_code_example_1.png

 

I will add (before somebody else comments!) that there are other ways to achieve the same thing in each of these languages. The point I'm making is that by understanding a logical flow, it's possible to implement what is quite clearly the same logical sequence of steps in multiple different languages in order to get the result we wanted.

 

Macro Problem: Automate VLAN Creation

 

Having looked at some low level logic, let's look at an example of a higher level construct to demonstrate that the ability to follow (and determine) a logical sequence of steps applies all the way up to higher levels as well.

 

In this example, I want to define a VLAN ID and a VLAN Name, and have my script create that VLAN on a list of devices. At the very highest level, my theoretical sequence might look like this:


Login to router
Create VLAN
Logout

After some more thought, I realize that I need to do those steps on each device in turn, so I need to create some kind of loop:


do the following for each switch in the list (s1, s2 ...  sN ):
  Login to router 
  Create VLAN
  Logout
done

It occurs to me that before I begin creating the VLANs, I ought to confirm that it doesn't exist on any of the target devices already, and if it does, I should stop before creating it. Now my program logic begins to look like this:


do the following for each switch in the list (s1, s2 ...  sN ):
  Login to router
  Check if VLAN exists
  Logout
  IF the chosen VLAN exists on this device, THEN stop!
  ENDIF
done

do the following for each switch in the list (s1, s2 ...  sN ):
  Login to router
  Create VLAN
  Logout
done

The construct used to determine whether to stop or not is referred to as an if/then/else clause. In this case, IF the vlan exists, THEN stop (ELSE, implicitly, keep on running).

Each step in the sequence above can then be broken down into smaller parts and analyzed in a similar way. For example:


Login to router
IF login failed THEN:
| log an error
| stop ELSE:
| log success
ENDIF

Boolean (true/false) logic is the basic for all these sequences, and multiple conditions can be tested simultaneously and even nested within other clauses. For example, I might expand the login process to cope with RADIUS failure:


Login to router
IF login failed THEN:
| IF error message was "RADIUS server unavailable" THEN:
| | attempt login using local credentials
| ELSE:
| | log an error
| | stop
| ENDIF
ELSE:
| log success
ENDIF

 

So What?

 

The so what here is that if following the kind of nested logic above seems easy, then in all likelihood so will coding. Much of the effort in coding is figuring out how to break a problem down into the right sequence of steps, the right loops, and so forth. In other words, the correct flow of events. To be clear, choosing a language is important too, but without having a grasp of the underlying sequence of steps necessary to achieve a goal, expertise in a programming language isn't going to be very useful.

 

My advice to a newcomer taking the first steps down the Road to Code (cheese-y, I know), is that it's good to look at the list of tasks that would ideally be automated and see if they can be broken down into logical steps, and then break those steps down even further until there's a solid plan for the approach. Think about what needs to happen in what order. If information is being used in a particular step, where did that information come from? Start thinking about the problems with a methodical, programming mindset.

 

In this series of posts, it's obviously not going to be possible to teach anybody how to code, but instead I'll be looking at how to select a linguistic weapon of choice, how to learn to code, ways to get started and build on success, and finally to offer some advice on when coding is the right solution.