Python

Data Types

Primitive Data Types
  • Integer - any whole number - 421
  • Float - any decimal number - 16.6
  • String - any alphanumeric characters - ‘hello!’
    • Useful methods for manipulation include split(seperator), strip(), lstrip(), rstrip()
    • Can use string literal (f-string) method to insert variables into a string - for example:
    x = 'router1'
    model = '3800'
    os = 'ios-xe'
    f"The model of {x} is {model} with os {os}."
    #Returns: 'The model of router1 is 3800 with os ios-xe.'
    • This is much easier and faster than using the .format() method
    • Escape characters:
      • \n creates a new line
      • \t creates a tab
      • \ escapes any character after it
  • Boolean - true or false - False
  • None - special data type - None
Non-primitive Data Types
  • List - Data enclosed in brackets, indexed starting at 0 - [‘hello’, ‘Hi’, ‘Hey’]
    • Also called an array in some other languages
    • To print values from lists, print(list[0]). You can also print values right of an index with print(list[1:]) which includes second and all other values
    • Even easier to use by looping without an index number, like for item in list:
    • List can contain any kind of object, including primitive data types, dictionaries or other lists
    • list.append('example') allows adding an item to the end of a list
    • list.insert(3,'example') allows adding an item to a specific index in a list
    • list.pop(3) allows removing an object from a specific index
      • Can also use list.remove('example') to remove an object by name
    • Can use the built-in len function to return the length of lists: number_of_items = len(my_list)
    • You can slice a list to pull specific values from it, like list[start:stop:step]
      • start determines start place, stop where you’ll stop and step by how much you’ll increment
    • You can use the built-in keyword del to delete items from objects: python nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] # delete the fourth item del nums[3]
    • You can use the in keyword to check for the contents of a list very easily, like so: python fruits = ["apple", "orange", "banana"] print("banana" in fruits) # Prints: True
    • Allows nesting of other lists, dictionaries etc as objects
  • Tuple - Similar to lists, data enclosed in parenthesis, but different in that they are immutable (cannot be changed at runtime) (1001, 1002)
  • Dictionary - Key value pairs enclosed in curly brackets - {‘Gi0/1’:‘shutdown’, ‘Gi0/2’:‘no shutdown’}
    • Can add items with dictionary['key1']='keyvalue'
    • Can return key values with dictionary.get('key1')
    • Can return all items in a dictionary with dictionary.items()
    • Can return all keys in a dictionary with dictionary.keys()
    • Can return all values in a dictionary with dictionary.values()
    • Can remove items from a dictionary with dictionary.pop('key1')
    • Can merge dictionaries together with dictionary.update(dict2)
    • Allows nesting of other dictionaries, lists etc as objects
  • Set - Collection of unique objects enclosed in curly braces - unordered and not indexed - {‘yes’, ‘no’}
    • Similar to list but will not allow duplicates
    • Can join two sets with set1.union(set2) which will automatically remove duplicate objects, or use set1.intersection(set2) which will return duplicate objects

Variables

  • Containers that store data of any type - naming convention is lowercase with underscores between words
  • switch_os = 'IOS-XE' would be an example of assigning a string data type to a variable with proper naming convention
  • Variables can exist both locally within a loop, function or class and globally
  • Different languages have their own variable naming conventions - Python recommends Snake Case
Name Description Code Language(s) that recommend it
Snake Case All words are lowercase and separated by underscores num_new_users Python, Ruby, Rust
Camel Case Capitalize the first letter of each word except the first one numNewUsers JavaScript, Java
Pascal Case Capitalize the first letter of each word NumNewUsers C#, C++
No Casing All lowercase with no separation numnewusers No one: don’t do this

Arithmetic Operations

a = 10
b = 5

summation = a + b  # Addition
difference = a - b # Subtraction
product = a * b    # Multiplication
quotient = a / b   # Division
floor = a // b     # Floor Division (always rounds down remainder, e.g. 11 // 2 = 5)
exponent = a ** b  # Exponent
a += 1             # In-place addition, equals 11
a -= 1             # In-place subtraction, equals 10 (after above operation)
a /= 2             # In-place division, equals 5 (after above operation)

print(summation)   # 15
print(difference)  # 5
print(product)     # 50
print(quotient)    # 2.0
print(floor)       # 2
print(exponent)    # 100000

Operators

Comparison Operators
  • == - Are the values equal
  • != - Are the values not equal
  • -< - Is the left value less
  • -> - Is the right value less
  • <= - Is the left less than or equal to
  • >= - Is the right less than or equal to
Boolean Operators
  • and - Both statements true
  • or - Either statement true
  • not - Opposite of original value
Membership Operators
  • in - Checks whether value on left exists in object on right
  • not in - Checks whether value on left does not exists in object on right
Identity Operators

Conditionals

  • If - If statement is true, execute
  • Elif - Below initial if, if statement is true, execute
  • Else - If all conditionals are false, execute

Loops

  • For - Functions like ‘for each’ in other languages. Iterates through string, range, or nonprimitive data types. Syntax is for <var> in <object_of_iteration>: ```Python def countdown_to_start(): for i in range(10, 0, -1): if i == 1: print(f”{i}…Fight!“) else: print(f”{i}…“)

      #Returns countdown to match start from 10 - 1

    ```

  • While - Like a for loop, iterates over code, except only executes while the supplied condition is true. Prone to infinite loops if not careful. Syntax is while <var> <=10:


Functions

  • Organized blocks of code to be called later in a program, allowing for code reuse
  • Syntax is the following: def my_function(var1, var2): and then called later with my_function(x, y)
  • Use return to provide value(s) back after the function is called, like below:
def sumfunction(a,b):
    result = a + b
    return result
  • Parameters are the names used for inputs when defining a function, (def sumfunction(a,b) would have ‘a’ and ‘b’ as a parameters) whereas arguments are the actual values used when calling a function (sum = sumfunction (5,10) would have ‘5’ and ‘10’ as arguments
  • You can specify default values for a function parameter if no input is supplied - these optional arguments must always come at the end of the function parameter list
def get_greeting(email, name="there,"):
    print("Hello", name, " welcome! You've registered your email:", email)

get_greeting("lane@example.com")
    # Would return: Hello there, welcome! You've registered your email: lane@example.com

Scope

  • Refers to where a variable or function is available to be used
  • Variables created within a function are only applicable within those given code blocks, whereas variables created at the top of a script and unindented will be available anywhere (global scope)
def subtract(x, y):
    return x - y

result = subtract(5, 3)

print(x)
# ERROR! "name 'x' is not defined"

Main() Function

  • Used as a convention to allow code importing, reuse without accidentally running code
def greet_user(name):
    print(f"Hello, {name}!")

def main():
    name = input("Enter your name: ")
    greet_user(name)

if __name__ == "__main__":
    main()
  • When run directly, the above code will prompt for a username and run greet_user, however when imported nothing will occur until the functions are explicitly called

Classes

  • A blueprint for creating objects, allowing bundling data and methods together to make code reuse easier
  • Example:
# Define a class called BankAccount
class BankAccount:
    # The __init__ method initializes the BankAccount object
    # with the account holder's name and an optional starting balance
    def __init__(self, account_holder, balance=0):
        self.account_holder = account_holder
        self.balance = balance

    # Define a method to deposit money into the account
    def deposit(self, amount):
        self.balance += amount
        print(f"Deposited {amount}. New balance is {self.balance}.")

    # Define a method to withdraw money from the account
    def withdraw(self, amount):
        if amount > self.balance:
            print("Insufficient funds!")
        else:
            self.balance -= amount
            print(f"Withdrew {amount}. New balance is {self.balance}.")

# Create an instance of BankAccount with account holder "Alice" and initial balance of 100
account = BankAccount("Alice", 100)

# Call the deposit method to add 50 to the account balance
# Outputs: Deposited 50. New balance is 150.
account.deposit(50)

# Call the withdraw method to remove 30 from the account balance
# Outputs: Withdrew 30. New balance is 120.
account.withdraw(30)

# Attempt to withdraw 200 from the account balance, which exceeds the current balance
# Outputs: Insufficient funds!
account.withdraw(200)
  • You can also extend a class’ functionality with a child class:
# Define a child class that inherits from BankAccount
class SavingsAccount(BankAccount):
    def __init__(self, account_holder, balance=0, interest_rate=0.01):
        # Call the parent class's __init__ method to set up common attributes
        super().__init__(account_holder, balance)
        # Add a new attribute specific to the child class
        self.interest_rate = interest_rate

    # Add a new method specific to the child class
    def add_interest(self):
        interest = self.balance * self.interest_rate
        self.balance += interest
        print(f"Added interest of {interest:.2f}. New balance is {self.balance:.2f}.")
  • When inheriting from a parent class, the super() method allows you to initialize the attributes from the parent class and allows you to call any parent method from the child class

File Operations

  • with can be used to open a file and automatically close it after the end of a code block, rather than having to manually close it
  • If no mode is specified, defaults to read-only mode, but can specify 'r','w','a', for read, write, append, respectively
with open("example.txt", "r") as file:
    content = file.read()
    print(content)

User Input

  • The input() built-in function allows you to take user input, whereas getpass requires importing but allows you to take user input without displaying text to the screen
  • By default input() takes the value as a string, but this can be modified to an int, float etc as required
import getpass

username = input("Enter a username:")
password = getpass.getpass("Enter a password:")

Command-Line Arguments

  • You can run Python scripts with command like arguments, like python pyscript.py arg1 arg2
  • The easiest way to get Python to interpret these arguments is by importing the sys module, however the argparse module is generally better to use as it has additional functionality
  • argparse allows you to identify short and long options, help text and whether or not a argument is mandatory - parser.add_argument(short_option, long_option, help, action)
  • Basic example below:
import argparse

text = 'This program takes input for router information.'
parser = argparse.ArgumentParser(description="This program takes input for router info")
parser.add_argument("-R", "--router", help=" Enter router name")
parser.add_argument("-IP", help=" Enter ip address")

router = parser.parse_args()

print(f'The router name is {router.router} with IP address {router.IP}')

Exception Handling

  • You can use try-except-else-finally blocks handle runtime errors
  • except can be used with or without a specified ExceptionType - it’s always recommended to include an ExceptionType, otherwise you will catch all errors with an except (referred to as a bare except)
  • else executes only if no exceptions occur
  • finally always executes, regardless of whether an error occurs
  • Example below:
def handle_exceptions():
    try:
        number = int(input("Enter a number: "))
        result = 10 / number
    except ZeroDivisionError:
        print("Cannot divide by zero")
    else:
        print(f"Success! Result: {result}")
    finally:
        print("Done")

handle_exceptions()

Useful Commands & Methods

  • python in CMD, Powershell to enter an interactive Python shell
  • python <file> to run a Python script
  • py -m pip install <x> to install packages
  • type() built-in function allows you to determine the data type of an object
  • dir() built-in function shows you what methods can apply to different variables/data types
  • import requests allows sending HTTP requests with Python
  • import re allows you to use Regex patterns in Python
  • import json, print(json.dumps(<var>, indent=4)) - Allows printing of nested dictionaries as JSON which improves readability

Misc Tips

  • Keeping Python environment running in VScode after script execution
    • Best way to do this seems to be selecting all code (CTRL+A) and doing a ‘Run Selection in Terminal’ with (Shift+Enter).
  • Underscores as variables
    • It’s convention in Python to use underscores as variables if you don’t intend to use the variable later
    • For example, with ip, _, username, password = ['1.1.1.1', '255.255.255.0', 'cisco', 'cisco'] the subnet would still be stored as a variable but you’ll know you don’t need that variable later
  • APIs
    • Python usage with APIs detailed in the APIs section