This post will describe the exercises and solutions for week three of Kirk Byers Python for Network Engineers.

The first exercise of the week is the following:

I. Create an IP address converter (dotted decimal to binary).  This will be similar to what we did in class2 except:

    A. Make the IP address a command-line argument instead of prompting the user for it.
        ./binary_converter.py 10.88.17.23

    B. Simplify the script logic by using the flow-control statements that we learned in this class.

    C. Zero-pad the digits such that the binary output is always 8-binary digits long.  Strip off the leading '0b' characters.  For example,

        OLD:     0b1010
        NEW:    00001010

    D. Print to standard output using a dotted binary format.  For example,

        IP address          Binary
      10.88.17.23        00001010.01011000.00010001.00010111


    Note, you might need to use a 'while' loop and a 'break' statement for part C.
        while True:
            ...
            break       # on some condition (exit the while loop)

    Python will execute this loop again and again until the 'break' is encountered. 

The first thing we want to do is to import the module sys because we are going to be working with command line arguments.

import sys

When the script is run the first argument of “sys.argv” (index 0) is the script name itself. The second argument (index 1) is the argument we supply to the script. Let’s prove this with the following code:

import sys
print(sys.argv)
print(type(sys.argv))

When this code is run we can see that “sys.argv” is a list:

daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py 192.168.1.1
['ip_converter.py', '192.168.1.1']

When this script is run, there should be exactly two arguments given. The script name itself and then the IP address. If there were less than two arguments then only the script name was supplied and if more than two arguments were supplied too many arguments were supplied.

How can we check how many arguments were supplied? We can check the length of “sys.argv” since it’s a list. The length should be two. If it’s not we will use “sys.exit” to display a message about the usage of the script and exit.

if len(sys.argv) != 2:
	sys.exit("Usage: ./ip_converter.py ")

If we run the script with too few or too many arguments the script will exit and print a help text.

daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py
Usage: ./ip_converter.py 
daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py 192.168.1.1 192.168.2.2
Usage: ./ip_converter.py 

The next thing we want to do is store the IP address that was entered when the script was run. We can use Pythons bult-in “pop()” function for this. “pop()” when no index is given will remove the last item from a list and return it. It would also be possible to refer to “sys.argv[1]” if not using “pop()”.

ip_address = sys.argv.pop()

Then we take another variable called “octets” and run “split()” on “ip_address” to store the octets of the IP address there. The delimiter is a dot.

octets = ip_address.split(".")

The next thing we want to do is to check that it’s a validly formatted IP address, meaning that we should have four octets. This is not a full check but prevents someone from entering an IP like “192.168.1.1.1”. If the length of “octets” is not 4 the script will exit. I’m printing the length of “octets” if the script exits just to demonstrate but it won’t be in the final code.

if len(octets) == 4:
        pass
else:
    print(len(octets))  
    sys.exit("Invalid IP address entered...")

This produces the following output if we enter a too long IP address.

daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py 192.168.1.1.1
5
Invalid IP address entered...

What we need to do next is to loop through each octet(string) that is stored in the list “octets”. Let’s first print the content of “octets” and the type so that you can follow along.

print(octets)
print(type(octets))

Running this then produces the following output:

daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py 192.168.1.1
['192', '168', '1', '1']

We create an empty list to which we will append our octets later:

ip_addr_bin = []

To loop through the contents of “octets” we use a For loop:

for octet in octets:

Then we want to convert the octet to binary. We can’t run “bin()” on a string though so first we must turn the string into an integer.

bin_octet = bin(int(octet))

We were told to strip off “0b” from our binary number which will be there by default. This is a prefix and it’s two characters long. So say that we have the binary number 16. It would be represented like this: “0b10000”. If we remove the first two chars, meaning index 0 and 1 from the string we will have a string without “0b”. Do note that “bin_octet” is a string which is why we can use slicing.

bin_octet = bin_octet[2:]

In case our binary string isn’t 8 chars long we need to pad it with zeroes. Since the length of “bin_octet” can vary a For loop is not really suitable. We will use a While loop instead. A “while True” loop can be used to loop until some condition becomes True and the loop “breaks”.

while True:
    if len(bin_octet) >= 8:
        break

This While loop will run indefinitely if we don’t break it since we are using the “while True” syntax.

The string “bin_octet” will be padded with zeroes until it is 8 chars long:

bin_octet = "0" + bin_octet

We concatenate to prepend a “0” to “bin_octet” until it becomes the right length.

We then append this octet after padding to the empty list we created earlier called “ip_addr_bin”:

ip_addr_bin.append(bin_octet)

The next step is to put all of the octets together with a dot as the delimiter.

ip_addr_bin = ".".join(ip_addr_bin)

Finally we print a pretty table with the IP address and its binary representation:

print("\n{:<15} {:<45}".format("IP address", "Binary"))
print("{:<15} {:<45}".format(ip_address, ip_addr_bin))

The end result is this:

daniel@daniel-iperf3:~/python/Week3$ python3 ip_converter.py 192.168.1.1

IP address      Binary                                       
192.168.1.1     11000000.10101000.00000001.00000001

The code is available at Github and thanks for reading! See you next time!

Python – Kirk Byers Course Week 3 Part 1

One thought on “Python – Kirk Byers Course Week 3 Part 1

  • June 7, 2020 at 2:35 am
    Permalink

    Just sharing my approach. I have used lstrip on “ob” and “rjust” to pad zeros to the left and it worked fine. Just an alternative to using “while” for padding.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *