This post will describe the exercises and solutions for week four of Kirk Byers Python for Network Engineers.
The final exercise of week 4 is the following.
[code lang=”text”]
III. Create a program that converts the following uptime strings to a time in seconds.
uptime1 = ‘twb-sf-881 uptime is 6 weeks, 4 days, 2 hours, 25 minutes’
uptime2 = ‘3750RJ uptime is 1 hour, 29 minutes’
uptime3 = ‘CATS3560 uptime is 8 weeks, 4 days, 18 hours, 16 minutes’
uptime4 = ‘rtr1 uptime is 5 years, 18 weeks, 8 hours, 23 minutes’
For each of these strings store the uptime in a dictionary using the device name as the key.
During this conversion process, you will have to convert strings to integers. For these string to integer conversions use try/except to catch any string to integer conversion exceptions.
For example:
int(‘5’) works fine
int(‘5 years’) generates a ValueError exception.
Print the dictionary to standard output.
[/code]
The first step is to import pretty print which we will use to print the dictionary.
[python]
# Import pretty print
import pprint
[/python]
To do the conversion from years, weeks and days to seconds, we are going to need some constants. Constants are usually defined with the variable names all in upper case in Python, although this is not enforced in any way.
[python]
# Define constants used to convert years, weeks, days to seconds
MINUTE_SECONDS = 60
HOUR_SECONDS = 60 * MINUTE_SECONDS
DAY_SECONDS = 24 * HOUR_SECONDS
WEEK_SECONDS = 7 * DAY_SECONDS
YEAR_SECONDS = 365 * DAY_SECONDS
[/python]
Then we store the strings containing the hostnames and the uptime of each device.
[python]
# Define variables containing hostnames and uptime
uptime1 = "wb-sf-881 uptime is 6 weeks, 4 days, 2 hours, 25 minutes"
uptime2 = "3750RJ uptime is 1 hour, 29 minutes"
uptime3 = "CATS3560 uptime is 8 weeks, 4 days, 18 hours, 16 minutes"
uptime4 = "rtr1 uptime is 5 years, 18 weeks, 8 hours, 23 minutes"
[/python]
We are going to solve this exercise in two different ways. The first way is a bit more readable and easy to follow along and the second one is a bit more effective in the number of lines needed. For this reason we are defining two empty dictionaries where we will later store data.
[python]
# Create two empty dictionaries for storing hostname and uptime
uptime_dict = {}
uptime_dict2 = {}
[/python]
We are going to loop through each of the uptime strings with a For loop. The For loop looks like this:
[python]
# Use For loop to loop through the uptime values
for uptime in (uptime1, uptime2, uptime3, uptime4):
[/python]
This loop may look a bit weird. What we are doing here is to temporarily group the uptime values in to a tuple. To demonstrate this we can assign our strings into a new variable.
[python]
uptime = (uptime1, uptime2, uptime3, uptime4)
print(type(uptime))
[/python]
This then gives us the following output:
[code lang=”text”]
daniel@daniel-iperf3:~/python/Week4$ python3 uptime.py
<class ‘tuple’>
[/code]
Tuples are a sequence of immutable Python objects meaning that they can’t be changed. Tuples use paranthesis while lists use brackets and dictionaries use curly brackets.
Let’s move on. The next step is to split our uptime strings using a comma as a delimiter. Our string will then turn into a list where we can later extract the number of years, weeks, days, hours and minutes from.
[python]
# Split uptime with comma as delimiter to get managable chunks
uptime_fields = uptime.split(",")
[/python]
Please keep in mind that the variable uptime_fields is being populated with information for each run in the For loop. That is, we’re simply storing information in this variable to be processed further, we’re not planning to use this data outside of the loop later.
We can print the type of uptime_fields and its contents to show that it’s a list and what the content is at each step of the For loop.
[python]
print(type(uptime_fields))
print(uptime_fields)
[/python]
[code lang=”text”]
daniel@daniel-iperf3:~/python/Week4$ python3 uptime.py
<class ‘list’>
[‘wb-sf-881 uptime is 6 weeks’, ‘ 4 days’, ‘ 2 hours’, ‘ 25 minutes’]
<class ‘list’>
[‘3750RJ uptime is 1 hour’, ‘ 29 minutes’]
<class ‘list’>
[‘CATS3560 uptime is 8 weeks’, ‘ 4 days’, ‘ 18 hours’, ‘ 16 minutes’]
<class ‘list’>
[‘rtr1 uptime is 5 years’, ‘ 18 weeks’, ‘ 8 hours’, ‘ 23 minutes’]
[/code]
As you can see there’s still some white space, hostnames etc. in there in the list.
The next thing we need to do is to extract the hostname out of the uptime.
[python]
"""Extract hostname from variable "uptime_fields" by using split().
Delimiter is " uptime is " so whatever comes before " uptime is "
is the hostname and what comes after is part of the uptime.
By using " uptime is " as the delimiter we remove this text
from our list."""
(hostname, time_field1) = uptime_fields[0].split(" uptime is ")
uptime_fields[0] = time_field1
[/python]
Here we are once again using a temporary tuple. We are using ” uptime is ” as the delimiter meaning that that the text before this delimiter will be stored in hostname and whatever comes after that text will be stored in time_field1.
To illustrate what we have stored in the variables I’ll input some code to print them.
[python]
# Extract hostname from variable "uptime_fields"
(hostname, time_field1) = uptime_fields[0].split(" uptime is ")
print(hostname)
print(time_field1)
uptime_fields[0] = time_field1
print(uptime_fields[0])
[/python]
When we run the script we get the following output.
[code lang=”text”]
daniel@daniel-iperf3:~/python/Week4$ python3 uptime.py
wb-sf-881
6 weeks
6 weeks
3750RJ
1 hour
1 hour
CATS3560
8 weeks
8 weeks
rtr1
5 years
5 years
[/code]
We now have temporary variables where we have stored the hostname and part of the uptime.
Now we have to go through our list and look for years, weeks, days, hours and minutes. We will initialize the variable uptime_seconds with a value of 0 and loop through each of the strings stored in the list named uptime_fields.
[python]
# Initialize uptime_seconds as 0
uptime_seconds = 0
# Loop through each string in the list "uptime_fields"
for time_field in uptime_fields:
[/python]
Looping through the list we will look for keywords such as year, week, day and so on.
[python]
# Check if there are any years in the uptime
if "year" in time_field:
(years, junk) = time_field.split(" year")
try:
uptime_seconds += int(years) * YEAR_SECONDS
except ValueError:
print("Error during string conversion to integer")
[/python]
We are using the in operator to search for an item in a list. If there is a match we want to extract the number of years. We use the split function and use ” year” as a delimiter. What comes before that string should be the number of years.
Remember the variable uptime_seconds that we initialized as 0? We will increment this value with the number of years multiplied with our constant YEAR_SECONDS. Using “+=” is the same as saying “uptime_seconds = uptime_seconds + int(years) * YEAR_SECONDS”. Before we can do the multiplication we must convert the number of years, which is a string, to an integer. That is done by using the int() function.
Also worth noting here is that we are using try/except to raise a ValueError if we fail in the conversion from a string to an integer.
Then we just repeat the same code but look for days, hours etc. and increase the variable uptime_seconds with the number of seconds each of those values is equivalent to.
[python]
elif "week" in time_field:
(weeks, junk) = time_field.split(" week")
try:
uptime_seconds += int(weeks) * WEEK_SECONDS
except ValueError:
print("Error during string conversion to integer")
elif "day" in time_field:
(days, junk) = time_field.split(" day")
try:
uptime_seconds += int(days) * DAY_SECONDS
except ValueError:
print("Error during string conversion to integer")
elif "hour" in time_field:
(hours, junk) = time_field.split(" hour")
try:
uptime_seconds += int(hours) * HOUR_SECONDS
except ValueError:
print("Error during string conversion to integer")
elif "minute" in time_field:
(minutes, junk) = time_field.split(" minute")
try:
uptime_seconds += int(minutes) * MINUTE_SECONDS
except ValueError:
print("Error during string conversion to integer")
[/python]
What is left now is to store the variable uptime_seconds in our dictionary uptime_dict under the key hostname.
[python]
# Insert number of seconds in dictionary under hostname
uptime_dict[hostname] = uptime_seconds
[/python]
All that is left is to use prettyprint to print the dictionary.
[python]
# print using prettyprint
pprint.pprint(uptime_dict)
[/python]
Running the script produces the following output.
[code lange=”text”]
daniel@daniel-iperf3:~/python/Week4$ python3 uptime.py
{‘3750RJ’: 5340, ‘CATS3560’: 5249760, ‘rtr1’: 168596580, ‘wb-sf-881’: 3983100}
daniel@daniel-iperf3:~/python/Week4$
[/code]
That’s all for this time! Get the code at Github!.
In the next blog we will use other code to solve the same task in a slightly different way.
Hi Daniel,
My name is Ritesh and I am a Network Administrator.
I would like to thank you for your valuable blogs.
I have been following your blogs from past 2 months only.
I appreciate your hard work. I learned so many things about python from your blogs.
Thank you so much.