Automation With Python
Automation With Python
Automation With Python
print(1/4)
print(1.0/4.0)
If you want to return a whole number from a calculation, you must use the symbol // instead:
It will round down to the nearest whole number. In the case of print(1//4), the output is the integer
value of 0 because using this symbol rounds down the calculation from .25 to the nearest whole
number. In the case of print(1.0//4.0), the output is the float value of 0.0 because it maintains the
float data type of the values in the calculation while also rounding down to the nearest whole
number.
Tuple
Tuple data is a data structure that consists of a collection of data that cannot be changed.
Like lists, tuples can contain elements of varying data types.
The syntax of a tuple is also different from the syntax of a list. A tuple is placed in
parentheses rather than brackets. These are all examples of the tuple data type:
Dictionary
Dictionary data is data that consists of one or more key-value pairs. Each key is mapped to a
value. A colon (:) is placed between the key and value. Commas separate key-value pairs
from other key-value pairs, and the dictionary is placed within curly brackets ({}).
Dictionaries are useful when you want to store and retrieve data in a predictable way. For
example, the following dictionary maps a building name to a number. The building name is
the value, and the number is the key. A colon is placed after the key.
{ 1: "East",
2: "West",
3: "North",
4: "South" }
Set
In Python, set data is data that consists of an unordered collection of unique values. This
means no two values in a set can be the same.
Elements in a set are always placed within curly brackets and are separated by a comma.
These elements can be of any data type. This example of a set contains strings of usernames:
for loops
If you need to iterate through a specified sequence, you should use a for loop.
Note: When used in a for loop, the in operator precedes the sequence that the for loop will iterate
through. When used in a conditional statement, the in operator is used to evaluate whether an
object is part of a sequence. The example if "elarson" in ["tshah", "bmoreno", "elarson"]
evaluates to True because "elarson" is part of the sequence following in.
Note: It is also possible to loop through a string. This will return every character one by one. You
can observe this by running the following code block that iterates through the string "security":
Using range()
It accepts inputs for the start point, stop point, and increment in parentheses. For example, the
following code indicates to start the sequence of numbers at 0, stop at 5, and increment each
time by 1:
range(0, 5, 1)
while loops
If you want a loop to iterate based on a condition, you should use a while loop.
Managing loops
You can use the break and continue keywords to further control your loop iterations. Both
are incorporated into a conditional statement within the body of the loop.
break
When you want to exit a for or while loop based on a particular condition in an if statement
being True, you can write a conditional statement in the body of the loop and write the
keyword break in the body of the conditional.
continue
When you want to skip an iteration based on a certain condition in an if statement being True, you
can add the keyword continue in the body of a conditional statement within the loop. In this
example, continue will execute when the loop variable of asset is equal to "desktop20". You can
run this code to observe how this output differs from the previous example with break:
Infinite loops
If you create a loop that doesn't exit, this is called an infinite loop. In these cases, you should
press CTRL-C or CTRL-Z on your keyboard to stop the infinite loop. You might need to do
this when running a service that constantly processes data, such as a web server.
Module 2:
Functions in cybersecurity
A function is a section of code that can be reused in a program. Functions are important
in Python because they allow you to automate repetitive parts of your code. In cybersecurity,
you will likely adopt some processes that you will often repeat.
When defining and calling functions, you're working with local variables, which are different
from the variables you define outside the scope of a function.
Global variables
A global variable is a variable that is available through the entire program. Global variables
are assigned outside of a function definition. Whenever that variable is called, whether inside
or outside a function, it will return the value it is assigned.
For example, you might assign the following variable at the beginning of your code:
device_id = "7ad2130bd"
Local variables
A local variable is a variable assigned within a function. These variables cannot be called or
accessed outside of the body of a function. Local variables include parameters as well as
other variables assigned within a function definition.
In the following function definition, total_string and name are local variables:
def greet_employee(name):
The variable total_string is a local variable because it's assigned inside of the function. The
parameter name is a local variable because it is also created when the function is defined.
There's something else to consider too. If you reuse the name of a global variable within a
function, it will create a new local variable with that name. In other words, there will be
both a global variable with that name and a local variable with that name, and they'll have
different values. You can consider the following code block:
username = "elarson"
print("1:" + username)
def greet():
username = "bmoreno"
print("2:" + username)
greet()
print("3:" + username)
RESULT:
1:elarson
2:bmoreno
3:elarson
sorted()
The sorted() function sorts the components of a list. The sorted() function also works on any
iterable, like a string, and returns the sorted elements in a list. By default, it sorts them in
ascending order. When given an iterable that contains numbers, it sorts them from smallest to
largest; this includes iterables that contain numeric data as well as iterables that contain string
data beginning with numbers. An iterable that contains strings that begin with alphabetic
characters will be sorted alphabetically.
The max() and min() functions accept arguments of either multiple numeric values or of an
iterable like a list, and they return the largest or smallest value respectively.
The re module, which provides functions used for searching for patterns in log files
The csv module, which provides functions used when working with .csv files
The glob and os modules, which provide functions used when interacting with the
command line
The time and datetime modules, which provide functions used when working with
timestamps
import statistics
monthly_failed_attempts = [20, 17, 178, 33, 15, 21, 19, 29, 32, 15, 25,
19]
mean_failed_attempts = statistics.mean(monthly_failed_attempts)
print("mean:", mean_failed_attempts)
An important detail to note is that if you import specific functions from a module, you no
longer have to specify the name of the module before those functions. You can examine
this in the following code, which specifically imports only the median() and the mean()
functions from the statistics module and performs the same calculations as the previous
examples:
To install a library, such as numpy, in either environment, you can run the following line
prior to importing the library:
After a library is installed, you can import it directly into Python using the import keyword in
a similar way to how you used it to import modules from the Python Standard Library. For
example, after the numpy install, you can use this code to import it:
import numpy
Module 3
String data in a security setting
String functions and methods
The str() and len() functions are useful for working with strings. You can also apply methods
to strings, including the .upper(), .lower(), and .index() methods. A method is a function that
belongs to a specific data type.
print("h32rb17".index("r"))
result: 7
Indices
An index is a number assigned to every element in a sequence that indicates its position.
With strings, this means each character in the string has its own index.
Indices start at 0.
You can also use negative numbers as indices. This is based on their position relative to the last
character in the string
You can also take a slice from a string. When you take a slice from a string, you extract more than
one character from it.
print("h32rb17"[0:3])
result: h32
Note: The slice starts at the 0 index, but the second index specified after the colon is excluded.
This means the slice ends one position before index 3, which is at index 2.
List methods
List methods are functions that are specific to the list data type. These include the .insert() ,
.remove(), .append() and .index().
.insert()
The .insert() method adds an element in a specific position inside a list. It has two
parameters. The first is the index where you will insert the new element, and the second is the
element you want to insert.
.remove()
The .remove() method removes the first occurrence of a specific element in a list. It has only
one parameter, the element you want to remove.
.append()
The .append() method adds input to the end of a list. Its one parameter is the element you
want to add to the end of the list.
Regular expressions are stored in Python as strings. Then, these strings are used in re module
functions to search through other strings. There are many functions in the re module, but you will
explore how regular expressions work through re.findall(). The re.findall() function returns a list
of matches to a regular expression.
The first is the string containing the regular expression pattern, and the second is the string you
want to search through.
You can use these additional symbols to match to specific kinds of characters:
The following code searches through the same device ID as the previous example but
changes the regular expression pattern to "\d". When you run it, it will return a different list:
import re
re.findall("\d", "h32rb17")
result: ['3', '2', '1', '7']
For example, the + symbol represents one or more occurrences of a specific character. In the
following example, the pattern places it after the "\d" symbol to find matches to one or more
occurrences of a single digit:
import re
re.findall("\d+", "h32rb17")
Another symbol used to quantify the number of occurrences is the * symbol. The * symbol
represents zero, one, or more occurrences of a specific character. The following code substitutes
the * symbol for the + used in the previous example. You can run it to examine the difference:
import re
re.findall("\d*", "h32rb17")
Because it also matches to zero occurrences, the list now contains empty strings for the characters
that were not single digits.
If you want to indicate a specific number of repetitions to allow, you can place this number in curly
brackets ({ }) after the character or symbol. In the following example, the regular expression
pattern "\d{2}" instructs Python to return all matches of exactly two single digits in a row from a
string of multiple device IDs:
import re
re.findall("\d{2}", "h32rb17 k825t0m c2994eh")
Note: Python scans strings left-to-right when matching against a regular expression. When Python
finds a part of the string that matches the first expected character defined in the regular
expression, it continues to compare the subsequent characters to the expected pattern. When the
pattern is complete, it starts this process again. So in cases in which three digits appear in a row, it
handles the third digit as a new starting digit.
You can also specify a range within the curly brackets by separating two numbers with a comma.
The first number is the minimum number of repetitions and the second number is the maximum
number of repetitions. The following example returns all matches that have between one and
three repetitions of a single digit
import re
re.findall("\d{1,3}", "h32rb17 k825t0m c2994eh")
Note: Working with regular expressions can carry the risk of returning unneeded information or
excluding strings that you want to return. Therefore, it's useful to test your regular expressions.
Module 4:
Working with files in cybersecurity
Opening files in Python
To open a file called "update_log.txt" in Python for purposes of reading it, you can
incorporate the following line of code:
This line consists of the with keyword, the open() function with its two parameters, and the as
keyword followed by a variable name. You must place a colon (:) at the end of the line.
with
The keyword with handles errors and manages external resources when used with other
functions. In this case, it's used with the open() function in order to open a file. It will then
manage the resources by closing the file after exiting the with statement.
Note: You can also use the open() function without the with keyword. However, you should
close the file you opened to ensure proper handling of the file.
open()
The open() function opens a file in Python.
In the following file structure, "update_log.txt" is located in the same directory as the Python file
that will access it, "log_parser.ipynb":
Because they're in the same directory, only the name of the file is required. The code can be
written as with open("update_log.txt", "r") as file:.
Note: In Python, the names of files or their file paths can be handled as string data, and like
all string data, you must place them in quotation marks.
The second parameter of the open() function indicates what you want to do with the file. In both of
these examples, the second parameter is "r", which indicates that you want to read the file.
Alternatively, you can use "w" if you want to write to a file or "a" if you want to append to a file.
as
When you open a file using with open(), you must provide a variable that can store the file
while you are within the with statement. You can do this through the keyword as followed by
this variable name. The keyword as assigns a variable that references another object. The
code with open("update_log.txt", "r") as file: assigns file to reference the output of the
open() function within the indented code block that follows it.
print(updates)
The .read() method converts files into strings. This is necessary in order to use and display
the contents of the file that was read.
In this example, the file variable is used to generate a string of the file contents through
.read(). This string is then stored in another variable called updates. After this,
print(updates) displays the string.
Once the file is read into the updates string, you can perform the same operations on it that
you might perform with any other string. For example, you could use the .index() method to
return the index where a certain character or substring appears. Or, you could use len() to
return the length of this string.
To write to a file, you will need to open the file with "w" or "a" as the second argument of
open().
You should use the "w" argument when you want to replace the contents of an existing file.
When working with the existing file update_log.txt, the code with open("update_log.txt",
"w") as file: opens it so that its contents can be replaced.
Additionally, you can use the "w" argument to create a new file. For example, with
open("update_log2.txt", "w") as file: creates and opens a new file called "update_log2.txt".
You should use the "a" argument if you want to append new information to the end of an
existing file rather than writing over it. The code with open("update_log.txt", "a") as file:
opens "update_log.txt" so that new information can be appended to the end. Its existing
information will not be deleted.
Like when opening a file to read from it, you should indicate what to do with the file on the
indented lines that follow when you open a file to write to it. With both "w" and "a", you
can use the .write() method. The .write() method writes string data to a specified file.
The following example uses the .write() method to append the content of the line variable to
the file "access_log.txt".
line = "jrafael,192.168.243.140,4:56:27,True"
file.write(line)
Note: Calling the .write() method without using the with keyword when importing the file
might result in its arguments not being completely written to the file if the file is not properly
closed in another way.
Parsing
Part of working with files involves structuring its contents to meet your needs. Parsing is the
process of converting data into a more readable forma
Methods that can help you parse your data include .split() and .join().
.split()
The basics of .split()
The .split() method converts a string into a list. It separates the string based on a specified
character that's passed into .split() as an argument.
In the following example, the usernames in the approved_users string are separated by a comma.
For this reason, a string containing the comma (",") is passed into .split() in order to parse it into a
list. Run this code and analyze the different contents of approved_users before and after the
.split() method is applied to it:
approved_users = "elarson,bmoreno,tshah,sgilmore,eraab"
print("before .split():", approved_users)
approved_users = approved_users.split(",")
print("after .split():", approved_users)
If you do not pass an argument into .split(), it will separate the string every time it encounters
a whitespace.
Note: A variety of characters are considered whitespaces by Python. These characters include
spaces between characters, returns for new lines, and others.
.join()
The basics of .join()
If you need to convert a list into a string, there is also a method for that. The .join() method
concatenates the elements of an iterable into a string. The syntax used with .join() is distinct
from the syntax used with .split() and other methods that you've worked with, such as
.index().
For example, in the following code, the approved_users variable contains a list. If you want to join
that list into a string and separate each element with a comma, you can use
",".join(approved_users). Run the code and examine what it returns:
Note: Another way to separate elements when using the .join() method is to use "\n", which is the
newline character. The "\n" character indicates to separate the elements by placing them on new
lines.
RESULT:
before .join(): ['elarson', 'bmoreno', 'tshah', 'sgilmore',
'eraab']
after .join(): elarson
bmoreno
tshah
sgilmore
eraab
Debugging strategies
Debugging is the practice of
identifying and fixing errors in code.
In this video, we'll explore some techniques for this.
There are three types of errors:
syntax errors, logic errors, and exceptions.
Syntax errors involve invalid usage
of the Python language,
such as forgetting to
add a colon after a function header
Debuggers
In this course, you have been running code in a notebook environment. However, you may
write Python code in an Integrated Development Environment (IDE). An Integrated
Development Environment (IDE) is a software application for writing code that provides
editing assistance and error correction tools. Many IDEs offer error detection tools in the
form of a debugger. A debugger is a software tool that helps to locate the source of an error
and assess its causes.