01 HCIP-Datacom-Python Programming Basics Lab Guide
01 HCIP-Datacom-Python Programming Basics Lab Guide
HCIP-Datacom-Network Automation
Developer
Python Programming Basics
Lab Guide
V1.0
and other Huawei trademarks are trademarks of Huawei Technologies Co., Ltd.
All other trademarks and trade names mentioned in this document are the property of their respective
holders.
Notice
The purchased products, services and features are stipulated by the contract made between Huawei and
the customer. All or part of the products, services and features described in this document may not be
within the purchase scope or the usage scope. Unless otherwise specified in the contract, all statements,
information, and recommendations in this document are provided "AS IS" without warranties,
guarantees or representations of any kind, either express or implied.
The information in this document is subject to change without notice. Every effort has been made in the
preparation of this document to ensure accuracy of the contents, but all statements, information, and
recommendations in this document do not constitute a warranty of any kind, express or implied.
Website: https://e.huawei.com/
HCIP-Datacom-Network Automation Developer Lab Guide
The Huawei certification system introduces the industry, fosters innovation, and imparts cutting-
edge datacom knowledge.
Introduction
This document is an HCIP-Datacom-Network Automation Developer certification
training course and is intended for trainees who are going to take the HCIP-
Datacom-Network Automation Developer exam or readers who want to
understand Python programming basics and practices.
● HCIA-Datacom
Lab Environment
Description
This lab environment is intended for datacom engineers who are preparing for the
HCIP-Datacom-Network Automation Developer exam. The experiments can be
carried out on any Python compiler, and Juypter Notebook and Pycharm are
recommended.
Compilation Environment
The compilation environment is based on the following compiler versions:
Anaconda3 2020.02
Contents
You can also use other development environments (such as PyCharm) to run Python scripts.
PyCharm is a Python IDE that provides a set of tools to help users improve efficiency in
development using Python, such as debugging, syntax highlighting, project management,
code jumping, intelligent tips, automatic completion, unit test, and version control. In
addition, the IDE provides some advanced functions to support professional Web
development under the Django framework.
Select the version for Windows, macOS, or Linux. In this example, select Windows,
select Python 3.7 (recommended) or Python 2.7, and click 64-Bit Graphical
Installer (not supported by a 32-bit computer).
Click I Agree.
----End
2. Click New in the upper right corner of the page and select Python 3 to create
a Jupyter file.
The title in the red box is the default title, which can be changed if you
double-click the title.
Enter the code in the green rectangle, and click Run to run the code.
The title in the red box is the default title, and you can double-click the title to
change the file name.
The blue box in the following figure is the code input box. After the code is
complete, click Run to run the code.
print(5+1.6) # The output is 6.6. By default, the sum of numbers in different precisions follow the highest
precision of the numbers.
Immutability of strings:
# str.split(str="", num=-1): The string is split by separator. If the “num”argument has a value, the string is
split into num+1 substrings. The value “-1” indicates that all strings are split.
print(S.split('h')) # Output ['pyt','on'], and split the string based on “h”.
# str.replace(old, new[, max]): A string generated after “old” in the string is replaced with “new”. If the third
argument “max” is specified, this replacement can take place for not more than max times.
print(S.replace('py','PY')) # PYthon: Replace “py” in the string with “PY”.
# str.upper(): Return the value after lowercase letters are converted to uppercase letters.
print(S.upper()) # PYTHON
# str.lower(): Return the value after uppercase letters are converted to lowercase letters.
print('PYTHON'.lower()) # Output python. The string is converted into lowercase letters.
# str.join(sequence): “sequence” indicates a sequence to be joined. In the output, the new string generated
after the elements are specified in the sequence is returned.
print(''.join(['life', 'is' ,'short'])) # Output “life is short” and “join” joins the string.
# list.insert(index, obj): Insert a specified object to a specified position in the list. The index indicates
the position.
animals.insert(1,’fish’) # Insert the element “fish” at the position of subscript 1.
print(animals) # Output ['cat', 'fish', 'dog', 'monkey'].
# list.pop([index=-1]): Remove the element (the last element by default) corresponding to the
subscript in the list. The index indicates the subscript.
animals.pop(1) # Delete the element whose subscript is 1.
print(animals) # Output ['cat', 'dog', 'monkey'].
Output:
(0, cat)
(1, dog)
(2, monkey)
● List derivations
squares = [x*2 for x in animals] # Generate a list of elements that comply with rules in batches.
print(squares) # ['catcat ', 'dogdog ', 'monkeymonkey ']
● Sorting
list.sort(cmp=None, key=None, reverse=False): The “cmp” parameter is
optional. If it is specified, the method of this parameter is used for sorting.
“key” is an element used for comparison. “reverse” indicates the sorting rule,
and “False” indicates the ascending order.
list1 = [12,45,32,55] # Define a new list, list1.
list1.sort() # Sort the list.
print(list1) # Output [12,32,45,55].
A tuple cannot be assigned a value for a second time, which is similar to a read-
only list.
A dictionary consists of indexes (keys) and their values. Compared with a list,
elements in a dictionary are saved as keys instead of offsets.
# Element access.
print(d['name']) # Error information is obtained.
print(d.get('name')) # Output none.
print(d.get('name','The key value does not exist.')) # Output “The key value does not exist”.
print(d.keys()) # Output “dict_keys(['food', 'quantity', 'color'])”.
print(d.values()) # Output “dict_values(['Spam', 4, 'red'])”.
print(d.items()) # Output “dict_items([('food', 'Spam'), ('quantity', 4), ('color', 'red')])”.
d.clear() # Clear all data in the dictionary.
print(d) # Output “{}”.
del(d) # Delete the dictionary.
# set.add(obj): Add an element to a set. If the element to be added already exists in the set, no operation is
performed.
sample_set.add('Data') # Add element “Data” to the set.
print(sample_set) # Output “{'Prince', 'Techs', 'Data'}”.
print(len(sample_set)) # Output “3”.
list2 = [1,3,1,5,3]
print(list(set(list2))) # Output [1,3,5]. The unique set elements are used to de-duplicate the list.
print(list(set(list2))) # Output the [1,3,5] list.
sample_set = frozenset(sample_set) # Immutable set.
In this experiment, the copy module in Python is used to differentiate deep copy
from shallow copy.
Output:
2.2.3 if Statement
The programming language provides various control structures, which allow more
complex execution paths. if statement is one of the control structures, and is used
to execute subsequent instructions after a condition is matched.
# try: except Exception: … is a Python statement used to capture exceptions. If an exception occurs in the
statement in “try”, the statement in “except “is executed.
try:
score = float(score) # Convert the score to a number.
if 100>=score>=90: # Check whether the entered value is greater than the score of a
level.
print("Excellent") # Generate the level when conditions are met.
elif 90 > score >= 80:
print("good")
elif 80>score>=60:
print("medium")
elif 60>score>=0:
print("bad")
else:
raise
except Exception:
print("Enter a correct score.")
● for loop
The for loop can traverse any sequence of items, such as a list or string.
In this example, a Python script is compiled to print the multiplication table.
for i in range(1,10): # Define the outer loop.
for j in range(1,i+1): # Define the inner loop.
print ("%d * %d = %2d" % (i, j, i*j), end=" \t ") # Print a string in format to align the print.
print() # The “end” attribute sets the end symbol of the print, which is /n by default.
Output:
1*1= 1
2*1= 2 2*2= 4
3*1= 3 3*2= 6 3*3= 9
4*1= 4 4*2= 8 4*3=12 4*4=16
5*1= 5 5*2=10 5*3=15 5*4=20 5*5=25
6*1= 6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1= 7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1= 8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1= 9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
● while loop
Output:
1
2
End the current loop.
4
End the current big loop.
● Define a function.
Use the “def” keyword to define a function, which can call the function (print
information).
def Print_Hello(): # Function name, no input value.
print("Hello, Python.") # Output
Print_Hello() # Call function.
Output:
Hello, Python.
Output:
hello, world!
Greetings, world!
hello, Huawei!
Greetings, universe!
● Length-variable parameters
A function with length-variable parameters can process parameters more
than defined. In this case, * indicates a tuple-type parameter and ** indicates a
dictionary-type parameter.
def test (a, b, *c, **d):
print (a)
print (b)
print (c)
print (d)
test (1,2,3,4,5,6,x=10,y=11) # The transfered parameters are automatically distinguished as the tuple or
dictionary type.
Output:
1
2
(3, 4, 5, 6)
{'x': 10, 'y': 11}
● Returned values
The returned value of a function is the result that the function returns to the
caller after completing the method. Use the return statement.
def plus_one (number):
return int(number)+1
plus_one (10)
Output:
11
Python I/O operations are performed to read and write files. Generally, you can
use the open function to perform the operations.
w Write-only. The file pointer is placed in the file header, and the file
overwrites the original content.
a Append. The pointer is placed at the end of the file. If no file exists,
a file is created.
r+ Read and write. The file pointer is placed in the file header.
w+ Read and write. If a file exists, the file will be overwritten. If no file
exists, a file is created.
● Write a file
f = open("text.txt", 'w') # Open the text.txt file. If the file does not exist, a new file is created. w: write
mode
Str = input("Please enter the content to be written.") # The built-in function “input” gets the input of
the console.
f.write(Str) # Write “Str” to file f.
f.close() # Close the file.
Output:
● Read a file
The read method is used to read files. If read() is not specified, all content is
read.
f = open("text.txt", 'r') # r indicates that the file is read.
print(f.read(6)) # Read six characters and move the cursor six characters backward.
print(f.read()) # Read from the current position of the cursor to the end.
f.close()
Output:
Python
file operation
simplifies code and improves its readability. The context manager works with
the “with” statement. The basic syntax is as follows:
“with” context expression [“as” resource object]: # “as” indicates that the
return value of the context is assigned to the resource object.
Object operation:
with open("text1.txt", 'w') as f: # Use the “with” statement to write data to the file.
f.write("python file operation")
with open("text1.txt", 'r') as f: # Use the “with” statement to read the file content.
print(f.read())
Output:
Python file operation
There are more methods for file operations, such as reading a line of
readlines, positioning files with “tell”, and finding files with “seek”. For details,
see Python Tutorial.
Python uses the “try-except” statement to handle exceptions. The “try” statement
is used to check exceptions, and the “except” statement to capture exceptions.
● Create exceptions.
First, let's create an exception where the divisor in a division is 0.
num1 = input('Please enter the first digit:')
num2 = input('Please enter the second digit:')
print('The first number divided by the second number is %f'%(int(num1)/int(num2)) #%f indicates a
floating point number.
Output:
Please enter the first digit: 10
Please enter the second digit: 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-10-5cc9c0d19753> in <module>
1 num1 = input('Please enter the first digit:')
2 num2 = input('Please enter the second digit:')
----> 3 print ('The first number divided by the second number is %f'%(int(num1)/int(num2)))
4
ZeroDivisionError: division by zero
Output:
Please enter the first digit: 10.
Please enter the second digit: 0.
The second digit cannot be 0.
Output:
Please enter the first digit: hello.
Please enter the second digit: 0.
Captured exception: invalid literal for int() with base 10: 'hello'
For example, in the first case, Dog is a class and Husky is an object of the class.
Husky has all the features and behaviors of the Dog class.
Each instance created based on the Dog class stores the name and age. We will
give each dog the sit () and roll_over () abilities.
Output:
In this example, the name and age attributes are initialized to the Dog class.
self.name+" is now sitting") # The method uses “self” to access the name attribute.
def roll_over(self):
"""Simulate a dog rolling over when ordered."""
print(self.name+" rolled over!")
dog = Dog("Husky",2) # Create an object and use Dog to save its reference.
print (dog.age) # Access attributes.
dog.sit() # Call the method.
dog.roll_over()
Output:
2
Husky is now sitting
Husky rolled over!
class Dog():
def __init__ (self,name,age):
self.name = name
self.__age = age # Set age to a private attribute __age.
def get_age(self):
return self.__age
dog = Dog ("Husky",2)
print (dog.name)
dog.get_age() # Call the get_age() method and return parameters.
print (dog.__age) # The program reports an error, indicating that the __age attribute does not exist
and cannot be directly called by external systems.
Output:
Husky
2
AttributeError Traceback (most recent call last)
<ipython-input-23-374e764e1475> in <module>
5 dog = Dog('Husky', '2')
6 print (dog.name)
----> 7 print (dog.__age)
8
AttributeError: 'Dog' object has no attribute '__age'
In this example, the subclass Husky of class Dog is constructed to inherit the
attributes and methods of the parent class. The method of subclass (parent class)
class Dog():
def __init__ (self,name,age):
self.name = name
self.__age = age # Set age as a private attribute __age.
def get_age(self):
return self.__age
class Husky(Dog): # Declare a subclass Husky and a parent class Dog.
pass
mydog = Husky('Larry','3') # The subclass inherits the construction method of the parent class.
print (mydog.name) # The subclass inherits the name attribute of the parent class, but cannot inherit private
attributes.
mydog.get_age() # The subclass inherits the get_age() method of the parent class.
Output:
Larry
3
In this example, the parent class is Dog and has the shout method. The subclasses
of Dog, Husky and Tibetan Mastiff, rewrite the shout method of the parent class.
A function sound can be defined. When calling the shout method, the program
does not care whether the object is a parent class or subclass, but cares only
whether they all have the shout method.
dog.shout()
Output:
Woo
Dog shouts
Barking
3 Python - Advanced
3.1 Introduction
This experiment uses independent code practices of each module to help readers
master the advanced Python3 syntax.
● Regular expressions
● Decorators
● Iterators
● Generators
● Multiple tasks
Flag Description
re.U Parses characters based on the Unicode character set. This flag affects
\w, \W.
This guide briefly describes how to use regular expressions. For more information,
see official documents.
3.2.1.1 re.match
The re.match function attempts to match a pattern from the start position of the
string. If the match is not successful, match() returns none.
Function syntax:
Example:
import re
print(re.match('www', 'www.huawei.com')) # Match www at the start position by default.
print(re.match('com', 'www.huawei.com')) # No match
print(re.match('.*com$','www.huawei.com')) # Match an object whose name ends with .com.
Output:
3.2.1.2 re.search
The re.search expression scans the entire string and returns the first successful
match.
Function syntax:
Example:
import re
print(re.search('www', 'www.huawei.com')) # Search for www from the start.
print(re.search('com', 'www.huawei.com')) # Search for com to the end.
print(re.search('.*com$','www.huawei.com')) # Match an object whose name ends with .com.
print(re.search('COM', 'www.huawei.com',re.I)) # Case insensitive.
Output:
Syntax:
pattern indicates regular expression, repl indicates the replacement string, which
can also be a function, and string indicates the original object for search. Count
refers to the maximum number of replacements (the value 0 indicates all).
Example:
import re
print(re.sub('^WWW','support', 'www.huawei.com',flags=re.I)) # Replace www with support.
Output:
support.huawei.com
3.2.1.4 re.compile
The compile function is used to compile regular expressions and generate a
regular expression object (pattern), which can be called by the match() and
search() functions.
re.compile(pattern[, flags])
Example:
import re
pattern = re.compile('\d+') # Match with at least one digit.
print (pattern.match('www.huawei123.com')) # Check whether the header contains digits. No match.
The first digit is returned for print (pattern.search('www.huawei123.com')) # Search and return the first digit.
Output:
None
<re.Match object; span=(10, 13), match='123'>
3.2.1.5 findall
findall indicates that all substrings that match the regular expression are found in
the string and a list is returned. If no substring is found, an empty list is returned.
string: the string to be matched; Pos: start position of the string, 0 as default;
Endpos: end position of the string, string length as default
Example:
import re
pattern = re.compile('\d+') # Match with at least one digit.
print(pattern.findall('www.huawei123.com \n 345')) # Search all strings.
Output:
['123', '345']
3.2.1.6 re.split()
The split expression splits a string based on the matched substring and returns a
list. This expression is used as follows:
Example:
import re
s = re.split('\W+', 'www.huawei.com') # \W+ indicates that non-English characters and digits are split for one
or more times.
print(s)
Output:
3.2.2 Decorators
As essentially a Python function, a decorator is special as it returns a function. It
can extend the functionality without changing the existing function. The syntax of
a decorator starts with @. It is used as follows:
Output:
I am learning Decorators.
This solves the problem, but changes the existing function. If you want to
solve the problem without changing the original function, you can use a
decorator.
Output:
I learned Python Data Structures.
I am learning Decorators.
3.2.3 Generators
Sometimes, the number of elements in a set is large. If all the elements are read
and stored in the memory, there will be excessive hardware requirements. In this
case, you can use a generator to get the subsequent elements in a set through
loop.
In Python, a function that uses the yield keyword is called generator. A generator
can be used as follows:
Output:
<class 'generator'>
0
2
4
6
8
if current > n: # The value is greater than the parameter value and
the loop ends.
return
yield num1 # yield turns the function into a generator, and the function is cyclically executed.
num1, num2 = num2, num1+num2
current += 1
fib(5)
for i in fib(5):
print (i)
Output:
0
1
1
2
3
5
3.2.4 Iterators
Iteration is a powerful function of Python and a way to access sets. An iterator is
an object that remembers the traversed positions. An iterator starts from the first
element for access until all elements are accessed.
An iterator has two basic methods: iter() and next(). The following is an example
of iterator:
print(isinstance([], Iterable))
print(isinstance('abc', Iterable))
print(isinstance({'a':1,'b':2},Iterable))
print(isinstance(100, Iterable))
Output:
True
True
True
False
Output:
1
2
3
4
5
A process contains a main thread and can generate multiple sub-threads. Each
thread contains its own registers and stacks. Processes can be single-thread or
multi-thread. Generally, an execution instance of a program is a process.
def work2(): # Define the work2 function and output the work2 string at an interval of 1s.
for i in range(3):
print("work2 is being executed...%d"%i)
sleep(1)
if __name__ == '__main__':
print('---Start---:%s'%ctime())
sleep(5)
print('---End---:%s' %ctime())
Output:
---Start---:Mon Apr 15 10:55:16 2019
work1 is being executed...0
work2 is being executed...0
work1 is being executed...1
work2 is being executed...1
work1 is being executed...2
work2 is being executed...2
---End---:Mon Apr 15 10:55:21 2019
● Synchronize threads.
If multiple threads modify a piece of data at the same time, unexpected
results may occur. To ensure correct data, multiple threads need to be
synchronized. Lock can be used to implement simple thread synchronization.
This object has acquire and release methods. The concept of lock is
introduced to implement synchronization. A lock has two states: locked and
unlocked. Each time a thread, for example, wants to access shared data, it
must get the locked state. If another thread has gotten the locked state, the
thread is suspended. In this case, thread synchronization is blocked. Wait until
other threads finish their accesses and release the lock, and then continue
with the thread.
Example:
import threading
import time
g_num = 0 # Define a global variable and set its value to 0.
def test1(num): # Define the function test1 and perform the add operation to global variables.
global g_num # Use global variables.
for i in range(num):
mutex.acquire() # Lock
g_num += 1
mutex.release() # Unlock
print("---test1--- g_num=%d" %g_num)
def test2(num): # Define the function test2 and perform the add operation to global variables.
global g_num
for i in range(num):
mutex.acquire() # Lock
g_num += 1 # Perform the add operation.
mutex.release() # Unlock
p2 = threading.Thread(target=test2, args=(1000000,))
p2.start()
print("After two threads operate the same global variable, the final result is: %s" % g_num)
Output:
---test1--- g_num=1868536
---test2--- g_num=2000000
After two threads operate the same global variable, the final result is: 2,000,000.
def work1():
"Code to be executed by subprocess 1. The nums list is extended."
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums)) # Get the process ID.
for i in range(3):
nums.append(i)
time.sleep(1)
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
def work2():
"Code to be executed by subprocess 2. Process ID is output and list of nums is called.”
print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
if __name__ == '__main__':
p1 = Process(target=work1)
p1.start()
p1.join() # After this thread is executed, execute other threads.
p2 = Process(target=work2)
p2.start()
Output:
Note: The Jupyter Notebook does not generate the result of this experiment
because of the editor. You can use Pycharm to execute code or create a .py file to
run it in CMD.