Automation With Python

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 15

Module 1

print(1/4)
print(1.0/4.0)

The output of both calculations is the float value of .25.

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:

 ("wjaffrey", "arutley", "dkot")


 (46, 2, 13, 2, 8, 0, 0)

 (True, False, True, True)

 ("wjaffrey", 13, True)


Pro tip: Tuples are more memory efficient than lists, so they are useful when you are
working with a large quantity of data.

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:

{"jlanksy", "drosas", "nmason"}

More on loops in Python


Previously, you explored iterative statements. An iterative statement is code that repeatedly
executes a set of instructions. Depending on the criteria, iterative statements execute zero or
more times. We iterated through code using both for loops and while loops.

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:

computer_assets = ["laptop1", "desktop20", "smartphone03"]


for asset in computer_assets:
if asset == "desktop20":
continue
print(asset)

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.

Global and local variables


To better understand how functions interact with variables, you should know the difference
between global and local variables.

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):

total_string = "Welcome" + name


return total_string

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.

max() and min()


The max() function returns the largest numeric input passed into it. The min() function
returns the smallest numeric input passed into it.

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.

Import modules and libraries in Python


Previously, you explored libraries and modules. You learned that a module is a Python file that
contains additional functions, variables, classes, and any kind of runnable code. You also
learned that a library is a collection of modules that provide code users can access in their
programs.

The Python Standard Library


The Python Standard Library is an extensive collection of Python code that often comes
packaged with Python. It includes a variety of modules, each with pre-built code centered
around a particular type of task.
For example, you were previously introduced to the the following modules in the Python
Standard Library:

 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

Importing an entire module


To import an entire Python Standard Library module, you use the import keyword. The
import keyword searches for a module or library in a system and adds it to the local Python
environment. After import, specify the name of the module to import. For example, you can
specify import statistics to import the statistics module. This will import all the functions
inside of the statistics module for use later in your code.

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)

Importing specific functions from a module


To import a specific function from the Python Standard Library, you can use the from
keyword. For example, if you want to import just the median() function from the
statistics module, you can write from statistics import median.

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:

from statistics import mean, median


monthly_failed_attempts = [20, 17, 178, 33, 15, 21, 19, 29, 32, 15, 25,
19]
mean_failed_attempts = mean(monthly_failed_attempts)
print("mean:", mean_failed_attempts)
median_failed_attempts = median(monthly_failed_attempts)
print("median:", median_failed_attempts)
External libraries
In addition to the Python Standard Library, you can also download external libraries and
incorporate them into your Python code. For example, previously you were introduced to
Beautiful Soup (bs4) for parsing HTML files and NumPy (numpy) for arrays and
mathematical computations. Before using them in a Jupyter Notebook or a Google Colab
environment, you need to install them first.

To install a library, such as numpy, in either environment, you can run the following line
prior to importing the library:

%pip install numpy

This installs the library so you can use it in your notebook.

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"))

Finding substrings with .index()


A substring is a continuous sequence of characters within a string. For example, "llo" is a
substring of "hello".

tshah_index = "tsnow, tshah, bmoreno - updated".index("tshah")


print(tshah_index)

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.

username_list = ["elarson", "bmoreno", "tshah", "sgilmore"]


print("Before inserting an element:", username_list)
username_list.insert(2,"wjaffrey")
print("After inserting an element:", username_list)

Result: Before inserting an element: ['elarson', 'bmoreno',


'tshah', 'sgilmore']

After inserting an element: ['elarson', 'bmoreno', 'wjaffrey',


'tshah', 'sgilmore']

.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.

username_list = ["elarson", "bmoreno", "wjaffrey", "tshah", "sgilmore"]


print("Before removing an element:", username_list)
username_list.remove("elarson")
print("After removing an element:", username_list)

.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.

username_list = ["bmoreno", "wjaffrey", "tshah", "sgilmore"]


print("Before appending an element:", username_list)
username_list.append("btang")
print("After appending an element:", username_list)
Regular expressions in Python
Let's explore the regular expression symbols that we need to do this.
To begin, let's learn about the plus sign.
The plus sign is a regular expression symbol that represents one or
more occurrences of a specific character.
Let's explain that through an example pattern.
The regular expression pattern a+
matches a string of any length in which "a" is repeated.
For example, just a single "a", three "a's" in a row, or
five "a's" in a row. It could even be 1000 "a's" in a row.
We can start working with a quick example to see which strings this pattern would
extract.

More about regular expressions


Basics of regular expressions
A regular expression (regex) is a sequence of characters that forms a pattern. You can use these in
Python to search for a variety of patterns. This could include IP addresses, emails, or device IDs.

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.

It requires two parameters.

The first is the string containing the regular expression pattern, and the second is the string you
want to search through.

Regular expression symbols


Symbols for character types
You can use a variety of symbols to form a pattern for your regular expression. Some of these
symbols identify a particular type of character. For example, \w matches with any
alphanumeric character.

Note: The \w symbol also matches with the underscore ( _ ).

You can use these additional symbols to match to specific kinds of characters:

 . matches to all characters, including symbols

 \d matches to all single digits [0-9]

 \s matches to all single spaces

 \. matches to the period character

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']

Symbols to quantify occurrences


Other symbols quantify the number of occurrences of a specific character in the pattern. In a
regular expression pattern, you can add them after a character or a symbol identifying a
character type to specify the number of repetitions that match to the pattern.

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")

result: ['32', '17']

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")

result: ['', '32', '', '', '17', '']

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")

['32', '17', '82', '29', '94']

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")

Result: ['32', '17', '825', '0', '299', '4']

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:

with open("update_log.txt", "r") as file:

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.

The first parameter identifies the file you want to open.

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:.

However, "access_log.txt" is not in the same directory as the Python file


"log_parser.ipynb". Therefore, it's necessary to specify its absolute file path. A file path is
the location of a file or directory. An absolute file path starts from the highest-level directory,
the root. In the following code, the first parameter of the open() function includes the
absolute file path to "access_log.txt":

with open("/home/analyst/logs/access_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.

Reading files in Python


After you use the code with open("update_log.txt", "r") as file: to import "update_log.txt"
into the file variable, you should indicate what to do with the file on the indented lines that
follow it. For example, this code uses the .read() method to read the contents of the file:

with open("update_log.txt", "r") as file:


updates = file.read()

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.

Writing files in Python


Security analysts may also need to write to files. This could happen for a variety of reasons.
For example, they might need to create a file containing the approved usernames on a new
allow list. Or, they might need to edit existing files to add data or to adhere to policies for
standardization.

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"

with open("access_log.txt", "a") as file:

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)

Result: before .split(): elarson,bmoreno,tshah,sgilmore,eraab


after .split(): ['elarson', 'bmoreno', 'tshah', 'sgilmore',
'eraab']

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:

approved_users = ["elarson", "bmoreno", "tshah", "sgilmore", "eraab"]


print("before .join():", approved_users)
approved_users = ",".join(approved_users)
print("after .join():", approved_users)

RESULT: before .join(): ['elarson', 'bmoreno', 'tshah',


'sgilmore', 'eraab']
after .join(): elarson,bmoreno,tshah,sgilmore,eraab

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.

approved_users = ["elarson", "bmoreno", "tshah", "sgilmore", "eraab"]


print("before .join():", approved_users)
approved_users = "\n".join(approved_users)
print("after .join():", approved_users)

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

Logic errors may not cause error messages;


instead, they produce unintended results.
A logic error could be as simple as writing
the incorrect text within a print statement, or
it might involve something like writing
a less than symbol instead
of less than or equal to symbol.

Another option for identifying


logic errors is to use a debugger.
A debugger will let you
insert breakpoints into your code.
Breakpoints allow you to segment your code into
sections and run just one portion at a time.
Just like with the print statements,
running these sections independently
can help isolate problems in the code.

Let's move on to our last type of error: an exception.


Exceptions happen when the program doesn't know how to
execute code even though
there are no problems with the syntax.
Exceptions occur for a variety of reasons.

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.

You might also like