├── Automations ├── BootStraping │ └── WebServers │ │ ├── ec2-httpd-curl.sh │ │ ├── ec2-httpd.sh │ │ └── php_webserver.sh ├── csv │ ├── csvdata_to_dictionary.py │ ├── generate_report.py │ ├── read_csv_employee_list.py │ ├── without_turning_indo_dict.py │ └── write_csv_services_file.py ├── dirs_and_files │ ├── create_new_directory.py │ ├── create_new_script.py │ ├── file_date.py │ └── parent_directory.py ├── health_check_demo │ ├── cpu_usage.py │ ├── disk_report.py │ └── health_check.py ├── health_check_main │ ├── health_checks.py │ └── network.py ├── linux_and_python │ └── pipes │ │ ├── capitalize.py │ │ └── haiku.txt ├── reading_data_interractively │ ├── create_file_script.py │ ├── example_log.txt │ ├── exmaple.txt │ ├── find_error_in_logfile.py │ ├── read_file_sys.py │ ├── reading_env_variables.py │ ├── syslog.py │ └── time_to_seconds.py ├── regex │ ├── basic_regex.py │ ├── capturing_groups.py │ ├── creating_basics_regex.py │ ├── escaping_chars.py │ ├── extrac_pid.py │ ├── final_quiz.py │ ├── re_module.py │ ├── re_quiz.py │ ├── regex_qwik_lab.py │ ├── repetition_qualifiers.py │ ├── split_replace.py │ └── test_re.py └── subprocesses │ ├── change_env_varriable.py │ └── get_date.py ├── Bash_basics ├── create_backup.sh ├── hello_world.sh ├── webserver_with_staticwebsite └── webserver_with_staticwebsite.sh ├── Encryping └── hashlib_demo.py ├── README.md ├── Testing ├── errors │ ├── __pycache__ │ │ └── validate_user.cpython-38.pyc │ ├── character_frequency.py │ ├── emails.py │ ├── emails_test.py │ ├── practice_errors.py │ ├── test_file.txt │ ├── validate_user.py │ └── validate_user_test.py └── re_arrange │ ├── __pycache__ │ └── re_arrange.cpython-38.pyc │ ├── re_arrange.py │ └── re_arrange_test.py └── intro ├── create_a_command_line_parse ├── click_group.py ├── parse.py ├── using_argparse.py ├── using_click.py └── using_fire.py ├── creating_a_module ├── __pycache__ │ └── first_module.cpython-38.pyc ├── first_module.py └── script.py ├── make_script_executable └── script_0.py └── use_command_line_args └── sys_args.py /Automations/BootStraping/WebServers/ec2-httpd-curl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum update -y 3 | yum install httpd -y 4 | systemctl start httpd 5 | systemctl enable httpd 6 | cd /var/www/html 7 | EC2AZ=$(curl -s http://169.254.169.254/latest/meta-data/hostname) 8 | echo "This instance is named #EC2AZ" > index.html -------------------------------------------------------------------------------- /Automations/BootStraping/WebServers/ec2-httpd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #========================================== 4 | # INSTALL APACHE SERVER ON AMAZON LINUX 2 5 | #========================================== 6 | 7 | # Get super user priviliges 8 | sudo su 9 | 10 | #=== Update and Install httpd (Linux 2 Version) === 11 | 12 | # Updates instance (server) 13 | yum update -y 14 | # Install httpd.x86_64 15 | yum install -y httpd.x86_64 16 | # Start httpd service 17 | systemctl start httpd.service 18 | # Enables httpd service auto-restart if instance gets re-started 19 | systemctl enable http.service 20 | # -OPTIONAL: Overwrites apache welcome index.html file with instance name 21 | echo "Welcome $(hostname -f) is now running..." > /var/www/html/index.html -------------------------------------------------------------------------------- /Automations/BootStraping/WebServers/php_webserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Install Apache Web Server and PHP 3 | yum install -y httpd mysql php 4 | # Download Lab files 5 | wget https://aws-tc-largeobjects.s3.amazonaws.com/ILT-TF-100-TUFOUN-1/4-lab-vpc-web-server/lab-app.zip 6 | unzip lab-app.zip -d /var/www/html/ 7 | # Turn on web server 8 | chkconfig httpd on 9 | service httpd start -------------------------------------------------------------------------------- /Automations/csv/csvdata_to_dictionary.py: -------------------------------------------------------------------------------- 1 | import os 2 | import csv 3 | 4 | # Create a file with data in it 5 | 6 | 7 | def create_file(filename): 8 | with open(filename, "w") as file: 9 | file.write("name,color,type\n") 10 | file.write("carnation,pink,annual\n") 11 | file.write("daffodil,yellow,perennial\n") 12 | file.write("iris,blue,perennial\n") 13 | file.write("poinsettia,red,perennial\n") 14 | file.write("sunflower,yellow,annual\n") 15 | 16 | # Read the file contents and format the information about each row 17 | 18 | 19 | def contents_of_file(filename): 20 | return_string = "" 21 | 22 | # Call the function to create the file 23 | create_file(filename) 24 | 25 | # Open the file 26 | with open(filename) as file: 27 | # Read the rows of the file into a dictionary 28 | reader = csv.DictReader(file) 29 | # Process each item of the dictionary 30 | for row in reader: 31 | return_string += "a {} {} is {}\n".format( 32 | row["color"], row["name"], row["type"]) 33 | return return_string 34 | 35 | 36 | # Call the function 37 | print(contents_of_file("flowers.csv")) 38 | -------------------------------------------------------------------------------- /Automations/csv/generate_report.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import csv 4 | 5 | 6 | def read_employees(csv_file_location): 7 | with open(csv_file_location) as csv_file: 8 | csv.register_dialect('empDialect', skipinitialspace=True, strict=True) 9 | csv_reader = csv.DictReader(csv_file, dialect='empDialect') 10 | employee_list = [] 11 | for data in csv_reader: 12 | employee_list.append(data) 13 | 14 | return employee_list 15 | 16 | 17 | employee_list = read_employees( 18 | "/home/student-04-25f29a151feb/data/employees.csv") 19 | 20 | 21 | def process_data(employee_list): 22 | department_list = [] 23 | for employee_data in employee_list: 24 | department_list.append(employee_data["Department"]) 25 | 26 | department_data = {} 27 | for department_name in set(department_list): 28 | department_data[department_name] = department_list.count( 29 | department_name) 30 | 31 | return department_data 32 | 33 | 34 | dictionary = process_data(employee_list) 35 | print(dictionary) 36 | 37 | 38 | def write_report(dictionary, report_file): 39 | with open(report_file, 'w+') as f: 40 | for k in sorted(dictionary): 41 | f.write(str(k)+':'+str(dictionary[k])+'\n') 42 | f.close() 43 | 44 | 45 | write_report(dictionary, "/home/student-04-25f29a151feb/test_report.txt") 46 | -------------------------------------------------------------------------------- /Automations/csv/read_csv_employee_list.py: -------------------------------------------------------------------------------- 1 | import csv 2 | 3 | 4 | def read_employees_list(filename): 5 | """Reads csv file with list of employees""" 6 | file = open(filename) 7 | csv_file = csv.reader(file) 8 | 9 | for row in csv_file: 10 | name, phone, role = row 11 | print(f"Name: {name}, Phone: {phone}, Role: {role}") 12 | 13 | file.close() 14 | -------------------------------------------------------------------------------- /Automations/csv/without_turning_indo_dict.py: -------------------------------------------------------------------------------- 1 | import os 2 | import csv 3 | 4 | # Create a file with data in it 5 | 6 | 7 | def create_file(filename): 8 | with open(filename, "w") as file: 9 | file.write("name,color,type\n") 10 | file.write("carnation,pink,annual\n") 11 | file.write("daffodil,yellow,perennial\n") 12 | file.write("iris,blue,perennial\n") 13 | file.write("poinsettia,red,perennial\n") 14 | file.write("sunflower,yellow,annual\n") 15 | 16 | # Read the file contents and format the information about each row 17 | 18 | 19 | def contents_of_file(filename): 20 | return_string = "" 21 | 22 | # Call the function to create the file 23 | create_file(filename) 24 | 25 | # Open the file 26 | with open(filename) as csv_file: 27 | # Read the rows of the file 28 | rows = csv.DictReader(csv_file) 29 | # Process each row 30 | for row in rows: 31 | csv_row = row 32 | # Format the return string for data rows only 33 | return_string += "a {} {} is {}\n".format( 34 | csv_row["color"], csv_row["name"], csv_row["type"]) 35 | return return_string 36 | 37 | 38 | # Call the function 39 | print(contents_of_file("flowers.csv")) 40 | -------------------------------------------------------------------------------- /Automations/csv/write_csv_services_file.py: -------------------------------------------------------------------------------- 1 | import csv 2 | 3 | hosts = [["workstation.local", "192.168.25.46"], 4 | ["webserver.cloud", "10.2.5.6"]] 5 | 6 | with open("hosts.csv", "w") as hosts_csv: 7 | writer = csv.writer(hosts_csv) 8 | writer.writerows(hosts) 9 | 10 | 11 | with open("sofware.csv") as software: 12 | reader = csv.DictReader(software) 13 | for row in reader: 14 | print(("{} has {} users").format(row["name"], row["users"])) 15 | 16 | 17 | # DictReader() allows us to convert the data in a CSV file into a standard dictionary 18 | # DictWriter() \ allows us to write data from a dictionary into a CSV file 19 | 20 | # with list of dictionaries 21 | users = [{"name": "Sol Mansi", "username": "solm", "department": "IT infrastructure"}, 22 | {"name": "Lio Nelson", "username": "lion", "department": "Development"}, 23 | {"name": "Charlie Grey", "username": "greyc", "department": "UX"} 24 | ] 25 | # we set they keys we want to write to the file 26 | keys = ["name", "username", "department"] 27 | # open the file for writing 28 | with open("by_department.csv", "w") as by_department: 29 | writer = csv.DictWriter(by_department, fieldnames=keys) 30 | writer.writeheader() # writes csv header 31 | writer.writerows(users) # turn list of dictionaries into lines 32 | -------------------------------------------------------------------------------- /Automations/dirs_and_files/create_new_directory.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def new_directory(directory, filename): 5 | # Before creating a new directory, check to see if it already exists 6 | if os.path.isdir(directory) == False: 7 | os.mkdir(directory) 8 | 9 | # Create the new file inside of the new directory 10 | os.chdir(directory) 11 | with open(filename, "w") as file: 12 | pass 13 | 14 | # Return the list of files in the new directory 15 | return os.listdir(os.path.join(os.getcwd())) 16 | 17 | 18 | print(new_directory("PythonPrograms", "script.py")) 19 | -------------------------------------------------------------------------------- /Automations/dirs_and_files/create_new_script.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def create_python_script(filename): 5 | comments = "# Start of a new Python program" 6 | with open(filename, "w") as file: 7 | file.write(comments) 8 | 9 | filesize = os.path.getsize(filename) 10 | return(filesize) 11 | 12 | 13 | print(create_python_script("program.py")) 14 | -------------------------------------------------------------------------------- /Automations/dirs_and_files/file_date.py: -------------------------------------------------------------------------------- 1 | import os 2 | import datetime 3 | 4 | 5 | def file_date(filename): 6 | # Create the file in the current directory 7 | new_file = open(filename, "w") 8 | path = os.path.join(os.getcwd(), filename) 9 | timestamp = os.path.getmtime(path) 10 | # Convert the timestamp into a readable format, then into a string 11 | date = datetime.datetime.fromtimestamp(timestamp) 12 | str_date = str(date) 13 | date_list = str_date.split(" ") 14 | # Return just the date portion 15 | # Hint: how many characters are in “yyyy-mm-dd”? 16 | return ("{}".format(date_list[0])) 17 | 18 | 19 | print(file_date("newfile.txt")) 20 | # Should be today's date in the format of yyyy-mm-dd 21 | -------------------------------------------------------------------------------- /Automations/dirs_and_files/parent_directory.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def parent_directory(): 5 | # Create a relative path to the parent 6 | # of the current working directory 7 | relative_parent = os.path.join(os.getcwd(), "..") 8 | 9 | # Return the absolute path of the parent directory 10 | return os.path.abspath(relative_parent) 11 | 12 | 13 | print(parent_directory()) 14 | -------------------------------------------------------------------------------- /Automations/health_check_demo/cpu_usage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import psutil 3 | 4 | 5 | cpu_stats = psutil.cpu_percent(0.5) 6 | 7 | print(cpu_stats) 8 | -------------------------------------------------------------------------------- /Automations/health_check_demo/disk_report.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import shutil 3 | 4 | du = shutil.disk_usage("/") 5 | 6 | # Disk Space 7 | print("Your Total Space ->", du) 8 | 9 | # * Calculate amount of free disk space percentage 10 | print("Free Disk Space % :", du.free / du.total * 100) 11 | -------------------------------------------------------------------------------- /Automations/health_check_demo/health_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import shutil 4 | import psutil 5 | 6 | 7 | def check_disk_usage(disk): 8 | """Verifies that there's enough free space on disk""" 9 | du = shutil.disk_usage(disk) 10 | free = du.free / du.total * 100 11 | return free > 20 12 | 13 | 14 | def check_cpu_usage(): 15 | """Verifies that there's enough unused CPU""" 16 | usage = psutil.cpu_percent(1) 17 | return usage < 75 18 | 19 | 20 | if not check_disk_usage("/") or not check_cpu_usage(): 21 | print("Error!") 22 | else: 23 | print("Everything is OK!", psutil.cpu_percent(1)) 24 | -------------------------------------------------------------------------------- /Automations/health_check_main/health_checks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import shutil 3 | import psutil 4 | from network import * 5 | 6 | 7 | def check_disk_usage(disk): 8 | """Verifies that there's enough free space on disk""" 9 | du = shutil.disk_usage(disk) 10 | free = du.free / du.total * 100 11 | return free > 20 12 | 13 | 14 | def check_cpu_usage(): 15 | """Verifies that there's enough unused CPU""" 16 | usage = psutil.cpu_percent(1) 17 | return usage < 75 18 | 19 | 20 | # If there's not enough disk, or not enough CPU, print an error 21 | if not check_disk_usage('/') or not check_cpu_usage(): 22 | print("ERROR!") 23 | elif check_localhost() and check_connectivity(): 24 | print("Everything ok") 25 | else: 26 | print("Network checks failed") 27 | -------------------------------------------------------------------------------- /Automations/health_check_main/network.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests 4 | import socket 5 | 6 | 7 | def check_localhost(): 8 | localhost = socket.gethostbyname('localhost') 9 | return localhost == "127.0.0.1" 10 | 11 | 12 | def check_connectivity(): 13 | request = requests.get("http://www.google.com") 14 | response = request 15 | return response.status_code == 200 16 | -------------------------------------------------------------------------------- /Automations/linux_and_python/pipes/capitalize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | 4 | # * We use sys.stdin to read from the standard input 5 | 6 | # Loops over each line of file 7 | # that is pass-in in the stdin 8 | for line in sys.stdin: 9 | # strips the new line character 10 | # then capitalize eatch sentence 11 | print(line.strip().capitalize()) 12 | 13 | 14 | # * We can now re-direct or pipe the context of a file to our capitalize.py script 15 | # * Use: cat haiku.txt | ./capitalize.py 16 | # * Note you can also use: capitalize.py < haiku.txt 17 | -------------------------------------------------------------------------------- /Automations/linux_and_python/pipes/haiku.txt: -------------------------------------------------------------------------------- 1 | advance your career, 2 | automating witth Python, 3 | it's so fun to learn -------------------------------------------------------------------------------- /Automations/reading_data_interractively/create_file_script.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | 6 | filename = sys.argv[1] 7 | 8 | if not os.path.exists(filename): 9 | with open(filename, 'w') as f: 10 | f.write('New file created\n') 11 | 12 | else: 13 | print(f'Error, the file {filename} already exists!') 14 | exit(1) 15 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/example_log.txt: -------------------------------------------------------------------------------- 1 | JAN 6 14:04:01 computer.anem CRON[29440]: USER (naughty_user) 2 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/exmaple.txt: -------------------------------------------------------------------------------- 1 | New file created 2 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/find_error_in_logfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import os 4 | import re 5 | 6 | 7 | def error_search(log_file): 8 | error = input("What is the error? ") 9 | returned_errors = [] 10 | with open(log_file, mode='r', encoding='UTF-8') as file: 11 | for log in file.readlines(): 12 | error_patterns = ["error"] 13 | for i in range(len(error.split(' '))): 14 | error_patterns.append(r"{}".format( 15 | error.split(' ')[i].lower())) 16 | if all(re.search(error_pattern, log.lower()) for error_pattern in error_patterns): 17 | returned_errors.append(log) 18 | file.close() 19 | return returned_errors 20 | 21 | 22 | def file_output(returned_errors): 23 | with open(os.path.expanduser('~') + '/data/errors_found.log', 'w') as file: 24 | for error in returned_errors: 25 | file.write(error) 26 | file.close() 27 | 28 | 29 | if __name__ == "__main__": 30 | log_file = sys.argv[1] 31 | returned_errors = error_search(log_file) 32 | file_output(returned_errors) 33 | sys.exit(0) 34 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/read_file_sys.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "Read Log file and Search for CRON lines" 3 | import sys 4 | import re 5 | 6 | if sys.argv[1]: 7 | logfile = sys.argv[1] 8 | else: 9 | print('Please include a file path') 10 | exit(1) 11 | 12 | usernames = {} 13 | 14 | with open(logfile) as f: 15 | for line in f: 16 | if 'CRON' not in line: 17 | continue 18 | pattern = r'USER \((\w+)\)$' 19 | result = re.search(pattern, line) 20 | 21 | if result is None: 22 | continue 23 | name = result[1] 24 | usernames[name] = usernames.get(name, 0)+1 25 | print('Found --->', line.strip()) 26 | print(usernames) 27 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/reading_env_variables.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | 5 | print('HOME: ' + os.environ.get('HOME', '')) 6 | print('SHELL: ' + os.environ.get('SHELL', '')) 7 | print('ROCK: ' + os.environ.get('ROCK', '')) 8 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/syslog.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def show_time_of_pid(line): 5 | # how to do it in one group? 6 | pattern = r'^([A-Za-z]+ \d \d+:\d+:\d+)' 7 | result = re.search(pattern, line) 8 | p2 = r'(\d{5})' 9 | r2 = re.search(p2, line) 10 | return '{} pid:{}'.format(result[1], r2[1]) pattern = r'^([A-Za-z]+ \d \d+:\d+:\d+)' 11 | 12 | 13 | # pattern = r'^([A-Za-z]+ \d \d+:\d+:\d+) (\[\d+\])' 14 | # result = re.search(pattern, line) 15 | # print(type(result)) 16 | # return f'{result[1]}' 17 | 18 | # When searching log files using regex, which regex statement will search for the alphanumeric word "IP" followed by one or more digits wrapped in parentheses using a capturing group? 19 | #r"IP \((\d+)\)$" 20 | 21 | # 22 | # Jul 6 14:01:23 pid:29440 23 | print(show_time_of_pid( 24 | "Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)")) 25 | 26 | # Jul 6 14:02:08 pid:29187 27 | print(show_time_of_pid( 28 | "Jul 6 14:02:08 computer.name jam_tag=psim[29187]: (UUID:006)")) 29 | 30 | # Jul 6 14:02:09 pid:29187 31 | print(show_time_of_pid( 32 | "Jul 6 14:02:09 computer.name jam_tag=psim[29187]: (UUID:007)")) 33 | 34 | # Jul 6 14:03:01 pid:29440 35 | print(show_time_of_pid( 36 | "Jul 6 14:03:01 computer.name CRON[29440]: USER (naughty_user)")) 37 | 38 | # Jul 6 14:03:40 pid:29807 39 | print(show_time_of_pid( 40 | "Jul 6 14:03:40 computer.name cacheclient[29807]: start syncing from \"0xDEADBEEF\"")) 41 | 42 | # Jul 6 14:04:01 pid:29440 43 | print(show_time_of_pid( 44 | "Jul 6 14:04:01 computer.name CRON[29440]: USER (naughty_user)")) 45 | 46 | # Jul 6 14:05:01 pid:29440 47 | print(show_time_of_pid( 48 | "Jul 6 14:05:01 computer.name CRON[29440]: USER (naughty_user)")) 49 | -------------------------------------------------------------------------------- /Automations/reading_data_interractively/time_to_seconds.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def to_seconds(hours, minutes, seconds): 4 | return hours*3600+minutes*60+seconds 5 | 6 | 7 | cont = 'y' 8 | 9 | while (cont.lower() == 'y'): 10 | hours = int(input('Enter the number of hours: ')) 11 | minutes = int(input('Enter the number of minutes: ')) 12 | seconds = int(input('Enter the number of seconds: ')) 13 | 14 | res = to_seconds(hours, minutes, seconds) 15 | print(f"That's {res} seconds") 16 | print("-----------------------------------------------") 17 | cont = input('Do you want to do another conversion? [y to continue]') 18 | 19 | print('Good bye :)') 20 | -------------------------------------------------------------------------------- /Automations/regex/basic_regex.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # Starts and ends with 'a' 4 | # works 5 | print(re.search(r'A.*a', 'Argentina')) 6 | 7 | # this way it wont matched the whole string 8 | # but it still matches the pattern 9 | print(re.search(r'A.*a', 'Azerbaijan')) 10 | 11 | # 12 | -------------------------------------------------------------------------------- /Automations/regex/capturing_groups.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | 4 | # * GROUPS () () 5 | 6 | result = re.search(r'^(\w*), (\w*)$', 'Lovelace, Ada') 7 | 8 | print(result) 9 | 10 | # Since we use Groups we can now call 11 | print(result.group()) # returns a Tuple 12 | 13 | # Using Tuple's indexing 14 | print(result[0]) 15 | print(result[1]) 16 | print(result[2]) 17 | print(f'Her name is {result[2]} and her lastname is {result[1]}') 18 | 19 | # * In function 20 | 21 | 22 | def rearrange_name(name): 23 | result = re.search(r'^(\w*), (\w*)$', name) 24 | 25 | if result is None: 26 | return name 27 | return f'{result[2], result[1]}' 28 | 29 | 30 | print(rearrange_name('Lovelace, Ada')) 31 | print(rearrange_name('Wayne, Bruce')) 32 | 33 | # not match bc of extra space and dot 34 | print(rearrange_name('Hopper, Dennis M.')) 35 | 36 | # * Matching middle names, middle initials and double surnames 37 | 38 | 39 | def rearrange_fullname(name): 40 | result = re.search(r'^(\w*), (\w*) ?(\w)?(.)?(\w*)$', name) 41 | 42 | result1 = re.search(r'"^([\w \.-]*), ([\w \.-]*)$"', name) 43 | 44 | if result is None: 45 | return name 46 | return f'{result[2]} {result[3]}{result[4]} {result[1]}' 47 | 48 | 49 | print(rearrange_fullname('Kennedy, John F.')) 50 | -------------------------------------------------------------------------------- /Automations/regex/creating_basics_regex.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # Name of country start and ends with A a 4 | print(re.search(r'A.*a', 'Argentina')) 5 | 6 | # This will also match the following country 7 | print(re.search(r'A.*a', 'Azerbaijan')) 8 | 9 | # We need to make our pattern strictier 10 | # Adding (^ $) makes sure we only get matching that beggins and ends with A a in this case 11 | # Should not match now 12 | print(re.search(r'^A.*a$', 'Azerbaijan')) 13 | 14 | # But still work for 15 | print(re.search(r'^A.*a$', 'Australia')) 16 | 17 | # * Checks if variable name is valid 18 | 19 | # Pattern Desc 20 | # 1- can only start with letters or underscore 21 | # 2- Can contain letters, numbers and underscores till end of pattern 22 | pattern = r'^[a-zA-Z_][a-zA-Z0-9_]*$' 23 | 24 | print(re.search(pattern, '_valid_name')) # ok 25 | print(re.search(pattern, 'no spaces allowed')) # nop 26 | print(re.search(pattern, 'my_var1')) # ok 27 | print(re.search(pattern, '1my_var')) # nop 28 | -------------------------------------------------------------------------------- /Automations/regex/escaping_chars.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # no escaping 4 | print(re.search(r'.com', 'welcome')) 5 | # escaping the . 6 | print(re.search(r'\.com', 'welcome')) 7 | # escaping the . 8 | print(re.search(r'\.com', 'mydomain.com')) 9 | 10 | # \d digits \s whitespaces \w alphanumeric 11 | 12 | # using \w* 13 | print(re.search(r'\w*', 'This is an example')) 14 | # using \w* 15 | print(re.search(r'\w*', 'And_this_is_another')) 16 | -------------------------------------------------------------------------------- /Automations/regex/extrac_pid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | log = 'January 2 10:30:03 mycomputer bad_process[12345]: Error Performing package upgrade' 6 | 7 | regex = r'\[(\d+)\]' 8 | result = re.search(regex, log) 9 | 10 | # whole object 11 | print(result) 12 | # list array 13 | print(result[0]) 14 | # element 15 | print(result[1]) 16 | 17 | # will case an Type error if we try to access undefined value 18 | reg_str = '99 elephants in a [cage]' 19 | result_error = re.search(regex, reg_str) 20 | # print(result_error[1]) 21 | 22 | # function 23 | 24 | 25 | def extract_pid(log_line): 26 | regex = r'\[(\d+)\]' 27 | result = re.search(regex, log_line) 28 | 29 | if result is None: 30 | return 'No Matches' 31 | return result[1] 32 | 33 | 34 | print('Result -->', extract_pid(log)) 35 | # will handle Type error and return error message 36 | print('Result -->', extract_pid(reg_str)) 37 | 38 | 39 | # Add to the regular expression used in the extract_pid function, to return the uppercase message in parenthesis, after the process id. 40 | 41 | def extract_pid1(log_line): 42 | regex = r"\[(\d+)\][:] (\w+)" 43 | result = re.search(regex, log_line) 44 | if result is None: 45 | return None 46 | return "{} ({})".format(result[1], result[2]) 47 | 48 | 49 | # 12345 (ERROR) 50 | print(extract_pid1( 51 | "July 31 07:51:48 mycomputer bad_process[12345]: ERROR Performing package upgrade")) 52 | print(extract_pid1("99 elephants in a [cage]")) # None 53 | print(extract_pid1( 54 | "A string that also has numbers [34567] but no uppercase message")) # None 55 | # 67890 (RUNNING) 56 | print(extract_pid1( 57 | "July 31 08:08:08 mycomputer new_process[67890]: RUNNING Performing backup")) 58 | -------------------------------------------------------------------------------- /Automations/regex/final_quiz.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | # * Question 1 6 | # We're working with a CSV file, which contains employee information. Each record has a name field, followed by a phone number field, and a role field. The phone number field contains U.S. phone numbers, and needs to be modified to the international format, with "+1-" in front of the phone number. Fill in the regular expression, using groups, to use the transform_record function to do that. 7 | 8 | 9 | def transform_record(record): 10 | new_record = re.sub(r'([\d-]+)', r'+1-\1', record) 11 | return new_record 12 | 13 | 14 | print(transform_record("Sabrina Green,802-867-5309,System Administrator")) 15 | # Sabrina Green,+1-802-867-5309,System Administrator 16 | 17 | print(transform_record("Eli Jones,684-3481127,IT specialist")) 18 | # Eli Jones,+1-684-3481127,IT specialist 19 | 20 | print(transform_record("Melody Daniels,846-687-7436,Programmer")) 21 | # Melody Daniels,+1-846-687-7436,Programmer 22 | 23 | print(transform_record("Charlie Rivera,698-746-3357,Web Developer")) 24 | # Charlie Rivera,+1-698-746-3357,Web Developer 25 | 26 | 27 | # * Question 2 28 | # The multi_vowel_words function returns all words with 3 or more consecutive vowels (a, e, i, o, u). Fill in the regular expression to do that. 29 | 30 | def multi_vowel_words(text): 31 | pattern = r'\b(?=[a-z]*[aeiou]{3,})[a-z]+\b' 32 | result = re.findall(pattern, text, re.IGNORECASE) 33 | return result 34 | 35 | 36 | print(multi_vowel_words("Life is beautiful")) 37 | # ['beautiful'] 38 | 39 | print(multi_vowel_words("Obviously, the queen is courageous and gracious.")) 40 | # ['Obviously', 'queen', 'courageous', 'gracious'] 41 | 42 | print(multi_vowel_words( 43 | "The rambunctious children had to sit quietly and await their delicious dinner.")) 44 | # ['rambunctious', 'quietly', 'delicious'] 45 | 46 | print(multi_vowel_words("The order of a data queue is First In First Out (FIFO)")) 47 | # ['queue'] 48 | 49 | print(multi_vowel_words("Hello world!")) 50 | # [] 51 | 52 | 53 | # *Question 4 54 | # The transform_comments function converts comments in a Python script into those usable by a C compiler. This means looking for text that begins with a hash mark (#) and replacing it with double slashes (//), which is the C single-line comment indicator. For the purpose of this exercise, we'll ignore the possibility of a hash mark embedded inside of a Python command, and assume that it's only used to indicate a comment. We also want to treat repetitive hash marks (##), (###), etc., as a single comment indicator, to be replaced with just (//) and not (#//) or (//#). Fill in the parameters of the substitution method to complete this function: 55 | 56 | def transform_comments(line_of_code): 57 | result = re.sub(r'([\#])+', r'//', line_of_code) 58 | return result 59 | 60 | 61 | print(transform_comments("### Start of program")) 62 | # Should be "// Start of program" 63 | print(transform_comments(" number = 0 ## Initialize the variable")) 64 | # Should be " number = 0 // Initialize the variable" 65 | print(transform_comments(" number += 1 # Increment the variable")) 66 | # Should be " number += 1 // Increment the variable" 67 | print(transform_comments(" return(number)")) 68 | # Should be " return(number)" 69 | 70 | 71 | # * Question 5 72 | # The convert_phone_number function checks for a U.S. phone number format: XXX-XXX-XXXX (3 digits followed by a dash, 3 more digits followed by a dash, and 4 digits), and converts it to a more formal format that looks like this: (XXX) XXX-XXXX. Fill in the regular expression to complete this function. 73 | 74 | def convert_phone_number(phone): 75 | result = re.sub(r'^([A-Za-z ]+),\b(\d{3})\b', r'(\2)', phone) 76 | return result 77 | 78 | 79 | # My number is (212) 345-9999. 80 | print(convert_phone_number("My number is 212-345-9999.")) 81 | # Please call (888) 555-1234 82 | print(convert_phone_number("Please call 888-555-1234")) 83 | print(convert_phone_number("123-123-12345")) # 123-123-12345 84 | # Phone number of Buckingham Palace is +44 303 123 7300 85 | print(convert_phone_number("Phone number of Buckingham Palace is +44 303 123 7300")) 86 | 87 | # Not quite. How did you define the capturing groups that are 88 | # used to change the format of the passed text? Did you 89 | # remember the escape characters for digits and word 90 | # boundaries? 91 | -------------------------------------------------------------------------------- /Automations/regex/re_module.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | log = "July 31 07:51:48 mycomputer bad_process[12345]: ERROR Performing package upgrade" 4 | 5 | regex = r"\[(\d+)\]" 6 | result = re.search(regex, log) 7 | print(result[1]) 8 | 9 | # NORMAL SERACH STRING LITERAL 10 | print(re.search(r"aza", "plaza")) 11 | print(re.search(r"aza", "bazaar")) 12 | 13 | # ^ THE CARET SEARCH FOR BEGGINING OF STRING 14 | print(re.search(r"^x", "xenon")) 15 | 16 | # SEARCH FOR (ANY CHAR) IN BETWEEN p.ng pattern 17 | print(re.search(r"p.ng", "penguin")) 18 | print(re.search(r"p.ng", "clapping")) 19 | print(re.search(r"p.ng", "sponge")) 20 | 21 | # case insensitive 22 | print(re.search(r"p.ng", "Pangaea", re.IGNORECASE)) 23 | 24 | # * character classes 25 | print("Pp ->", re.search(r"[Pp]ython", "Python")) 26 | print(re.search(r"[a-z]way", "The end of the highway")) 27 | print(re.search(r"[a-z]way", "What a way to go!")) 28 | 29 | # combinding ranges 30 | print(re.search(r"cloud[a-zA-Z0-9]", "cloudy")) 31 | print(re.search(r'cloud[a-zA-Z0-9]', 'cloud9')) 32 | 33 | # * non letter characters 34 | 35 | # Fill in the code to check if the text passed contains punctuation symbols: commas, periods, colons, semicolons, question marks, and exclamation points 36 | print(re.search(r"[^a-zA-Z ]", 'The sentence with spaces.')) 37 | 38 | # * Search for two either or case 39 | print(re.search(r"cat|dog", 'I like dogs')) 40 | # match first case 41 | print(re.search(r"cat|dog", 'I like both cats dogs.')) 42 | 43 | # * find all 44 | print(re.findall(r'cat|dog', "I like both cats and dogs.")) 45 | -------------------------------------------------------------------------------- /Automations/regex/re_quiz.py: -------------------------------------------------------------------------------- 1 | 2 | import re 3 | 4 | # * The repeating_letter_a function checks if the text passed includes the letter "a"(lowercase or uppercase) at least twice.For example, repeating_letter_a("banana") is True, while repeating_letter_a("pineapple") is False.Fill in the code to make this work. 5 | 6 | 7 | def repeating_letter_a(text): 8 | result = re.search(r"a.*a", text, re.IGNORECASE) 9 | return result != None 10 | 11 | 12 | print(repeating_letter_a("banana")) # True 13 | print(repeating_letter_a("pineapple")) # False 14 | print(repeating_letter_a("Animal Kingdom")) # True 15 | print(repeating_letter_a("A is for apple")) # True 16 | 17 | 18 | # * Fill in the code to check if the text passed has at least 2 groups of alphanumeric characters (including letters, numbers, and underscores) separated by one or more whitespace characters. 19 | 20 | def check_character_groups(text): 21 | result = re.search(r"\w \w", text) 22 | return result != None 23 | 24 | 25 | print(check_character_groups("One")) # False 26 | print(check_character_groups("123 Ready Set GO")) # True 27 | print(check_character_groups("username user_01")) # True 28 | print(check_character_groups("shopping_list: milk, bread, eggs.")) # False 29 | 30 | 31 | # * Fill in the code to check if the text passed looks like a standard sentence, meaning that it starts with an uppercase letter, followed by at least some lowercase letters or a space, and ends with a period, question mark, or exclamation point. 32 | 33 | 34 | def check_sentence(text): 35 | result = re.search(r"^[A-Z][a-z ]*[.,?.!]$", text) 36 | return result != None 37 | 38 | 39 | print(check_sentence("Is this is a sentence?")) # True 40 | print(check_sentence("is this is a sentence?")) # False 41 | print(check_sentence("Hello")) # False 42 | print(check_sentence("1-2-3-GO!")) # False 43 | print(check_sentence("A star is born.")) # True 44 | -------------------------------------------------------------------------------- /Automations/regex/regex_qwik_lab.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | import csv 5 | 6 | 7 | def contains_domain(address, domain): 8 | """Returns True if the email address contains the given,domain,in the domain position, false if not.""" 9 | domain = r'[\w\.-]+@'+domain+'$' 10 | if re.match(domain, address): 11 | return True 12 | return False 13 | 14 | 15 | def replace_domain(address, old_domain, new_domain): 16 | """Replaces the old domain with the new domain in the received address.""" 17 | old_domain_pattern = r'' + old_domain + '$' 18 | address = re.sub(old_domain_pattern, new_domain, address) 19 | return address 20 | 21 | 22 | def main(): 23 | """Processes the list of emails, replacing any instances of the old domain with the new domain.""" 24 | old_domain, new_domain = 'abc.edu', 'xyz.edu' 25 | csv_file_location = '' 26 | report_file = '' + '/updated_user_emails.csv' 27 | user_email_list = [] 28 | old_domain_email_list = [] 29 | new_domain_email_list = [] 30 | 31 | with open(csv_file_location, 'r') as f: 32 | user_data_list = list(csv.reader(f)) 33 | user_email_list = [data[1].strip() for data in user_data_list[1:]] 34 | 35 | for email_address in user_email_list: 36 | if contains_domain(email_address, old_domain): 37 | old_domain_email_list.append(email_address) 38 | replaced_email = replace_domain( 39 | email_address, old_domain, new_domain) 40 | new_domain_email_list.append(replaced_email) 41 | 42 | email_key = ' ' + 'Email Address' 43 | email_index = user_data_list[0].index(email_key) 44 | 45 | for user in user_data_list[1:]: 46 | for old_domain, new_domain in zip(old_domain_email_list, new_domain_email_list): 47 | if user[email_index] == ' ' + old_domain: 48 | user[email_index] = ' ' + new_domain 49 | f.close() 50 | 51 | with open(report_file, 'w+') as output_file: 52 | writer = csv.writer(output_file) 53 | writer.writerows(user_data_list) 54 | output_file.close() 55 | 56 | 57 | main() 58 | -------------------------------------------------------------------------------- /Automations/regex/repetition_qualifiers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | 4 | # * Repetition Qualifiers 5 | 6 | # (.*) Any character repeated as many times as possible including 0 7 | print(re.search(r'Py.*n', 'Pygmalion')) # RETURNS WHOLE WORD 8 | 9 | # Being Greedy -> the * takes as many as charaters as possible 10 | print(re.search(r'Py.*n', 'Python Programming')) 11 | 12 | # MATCHING JUST ANY LETTERS [a-z] 13 | print(re.search(r'Py[a-z]*n', 'Python Programming')) 14 | 15 | # 16 | print(re.search(r'Py[a-z]*n', 'Pyn')) 17 | 18 | # (+) SEARCH FOR CHAR REPETIOTIONS (OL) WILL MATCH 19 | print(re.search(r'o+l+', 'goldfish')) 20 | # MATCHING MUTIPLE REPETITIONS 21 | print(re.search(r'o+l+', 'woolly')) 22 | # HERE ARE NO REPETITIONS OF OO OR LL 23 | print(re.search(r'o+l+', 'boil')) 24 | 25 | # * Optional 26 | # (?) MARKS THE CHAR FEFORE IT AS "OPTIONAL" MEANING ZERO TO ONE OCCURANCES 27 | print(re.search(r'p?each', 'To each their own')) 28 | # HERE (?) WILL MATCH ONCE 29 | print(re.search(r'p?each', 'I like peaches')) 30 | 31 | 32 | ###############* Advanced #################### 33 | 34 | # specify the num of characters we search for 35 | print(re.search(r'[A-za-z]{5}', 'a ghost in a shell')) # search for 5 chars 36 | # returns the firt matching pattern 37 | print(re.search(r'[a-zA-Z]{5}', 'a scary ghost appeared')) 38 | # finding all will also return 'appre' 39 | print(re.findall(r'[A-Za-z]{5}', 'a scary ghost appreared')) 40 | # fi we only want full words use \b 41 | print(re.findall(r'\b[A-Za-z]{5}\b', 'a scary ghost appreared')) 42 | 43 | # * Using ranges 44 | # all words from 5 to 10 chars 45 | print(re.findall(r'\w{5,10}', 'I really like strawberries')) 46 | # five an up 47 | print(re.findall(r'\w{5,}', 'I really like strawberries')) 48 | # from 0 up to n with a (s) 49 | print(re.search(r's\w{,20}', 'I really like strawberries')) 50 | # full words only 51 | print(re.findall(r'\b\w{5,10}\b', 'I really like strawberries')) 52 | 53 | 54 | # * The long_words function returns all words that are at least 7 characters. Fill in the regular expression to complete this function. 55 | 56 | 57 | def long_words(text): 58 | pattern = r'\w{7,}' 59 | result = re.findall(pattern, text) 60 | return result 61 | 62 | 63 | print(long_words("I like to drink coffee in the morning.")) # ['morning'] 64 | # ['chocolate', 'afternoon'] 65 | print(long_words("I also have a taste for hot chocolate in the afternoon.")) 66 | print(long_words("I never drink tea late at night.")) # [] 67 | -------------------------------------------------------------------------------- /Automations/regex/split_replace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | 4 | re_str = 'One sentence. Another sentence? And last sentence!' 5 | 6 | # * Split 7 | # split exclude split values 8 | print(re.split(r'[.?!]', re_str)) 9 | 10 | # split includes split values 11 | print(re.split(r'([.?!])', re_str)) 12 | 13 | 14 | # We want to split a piece of text by either the word "a" or "the", as implemented in the following code.What is the resulting split list? 15 | 16 | print(re.split(r"the|a", "One sentence. Another one? And the last one!")) 17 | #['One sentence. Ano', 'r one? And ', ' l', 'st one!'] 18 | 19 | # * Sub 20 | re_str1 = 'Received an email for go_nuts95@my.exmaple.com' 21 | print(re.sub(r'[\w.%+-]+@[\w.-]+', '[REDACTED FROM TEXT]', re_str1)) 22 | 23 | # Using capturing groups to reverse name 24 | print(re.sub(r'^([\w .-]*), ([\w .-]*)$', r'\2 \1', 'Lovelace, Ada')) 25 | -------------------------------------------------------------------------------- /Automations/regex/test_re.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | # Question 1 5 | # The check_web_address function checks if the text passed qualifies as a top - level web address, meaning that it contains alphanumeric characters(which includes letters, numbers, and underscores), as well as periods, dashes, and a plus sign, followed by a period and a character - only top - level domain such as ".com", ".info", ".edu", etc.Fill in the regular expression to do that, using escape characters, wildcards, repetition qualifiers, beginning and end - of - line characters, and character classes 6 | 7 | def check_web_address(text): 8 | pattern = r'' ^ [A-Za-z][A-Za-z0-9_.-]*[.\w]$' 9 | result = re.search(pattern, text) 10 | print(result) 11 | return result != None 12 | 13 | 14 | print(check_web_address("gmail.com")) # True 15 | print(check_web_address("www@google")) # False 16 | print(check_web_address("www.Coursera.org")) # True 17 | print(check_web_address("web-address.com/homepage")) # False 18 | print(check_web_address("My_Favorite-Blog.US")) # True 19 | 20 | 21 | # Question 2 22 | # The check_time function checks for the time format of a 12-hour clock, as follows: the hour is between 1 and 12, with no leading zero, followed by a colon, then minutes between 00 and 59, then an optional space, and then AM or PM, in upper or lower case. Fill in the regular expression to do that. How many of the concepts that you just learned can you use here? 23 | 24 | def check_time(text): 25 | pattern = r'[1-12]*:[00-59][00-59] ?[AM,PM,am,pm]*' 26 | result = re.search(pattern, text) 27 | print(result) 28 | return result != None 29 | 30 | 31 | print(check_time("12:45pm")) # True 32 | print(check_time("9:59 AM")) # True 33 | print(check_time("6:60am")) # False 34 | print(check_time("five o'clock")) # False 35 | 36 | #! Not quite, check_time(6:02km) returned True, should be 37 | # False. 38 | 39 | 40 | # Question 3 41 | # The contains_acronym function checks the text for the presence of 2 or more characters or digits surrounded by parentheses, with at least the first character in uppercase (if it's a letter), returning True if the condition is met, or False otherwise. For example, "Instant messaging (IM) is a set of communication technologies used for text-based communication" should return True since (IM) satisfies the match conditions." Fill in the regular expression in this function: 42 | 43 | def contains_acronym(text): 44 | pattern = r'\(?[A-Z][A-Za-z0-9]*\)' 45 | result = re.search(pattern, text) 46 | return result != None 47 | 48 | 49 | print(contains_acronym( 50 | "Instant messaging (IM) is a set of communication technologies used for text-based communication")) # True 51 | print(contains_acronym("American Standard Code for Information Interchange (ASCII) is a character encoding standard for electronic communication")) # True 52 | print(contains_acronym("Please do NOT enter without permission!")) # False 53 | print(contains_acronym( 54 | "PostScript is a fourth-generation programming language (4GL)")) # True 55 | print(contains_acronym( 56 | "Have fun using a self-contained underwater breathing apparatus (Scuba)!")) # True 57 | 58 | 59 | # Q6 Fill in the code to check if the text passed includes a possible U.S. zip code, formatted as follows: exactly 5 digits, and sometimes, but not always, followed by a dash with 4 more digits. The zip code needs to be preceded by at least one space, and cannot be at the start of the text. 60 | 61 | def check_zip_code(text): 62 | result = re.search(r" \d{5}(\-\d{4})?", text) 63 | print(result) 64 | return result != None 65 | 66 | 67 | print(check_zip_code("The zip codes for New York are 10001 thru 11104.")) # True 68 | print(check_zip_code("90210 is a TV show")) # False 69 | print(check_zip_code("Their address is: 123 Main Street, Anytown, AZ 85258-0001.")) # True 70 | print(check_zip_code( 71 | "The Parliament of Canada is at 111 Wellington St, Ottawa, ON K1A0A9.")) # False 72 | -------------------------------------------------------------------------------- /Automations/subprocesses/change_env_varriable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import subprocess 5 | 6 | # * Copy enviroment variables 7 | my_env = os.environ.copy() 8 | # print(my_env) 9 | print(type(my_env)) # dict 10 | 11 | # * Add new path to the PATH variable 12 | my_env['PATH'] = os.pathsep.join(['/opt/myapp', my_env['PATH']]) 13 | 14 | result = subprocess.run(['myapp'], env=my_env) 15 | -------------------------------------------------------------------------------- /Automations/subprocesses/get_date.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import subprocess 4 | 5 | # * Running basic methods 6 | subprocess.run(['date']) 7 | 8 | subprocess.run(['sleep', '2']) 9 | 10 | # * run ping command 11 | # subprocess.run(['ping', 'www.google.com']) 12 | 13 | # * Return Error Message 14 | result = subprocess.run(['ls', 'no_such_file_or_dir']) 15 | print('error msg --->', result.returncode) 16 | 17 | # * Capturing output 18 | 19 | output_result = subprocess.run(['host', '8.8.8.8'], capture_output=True) 20 | print(output_result) 21 | print(output_result.returncode) 22 | print(output_result.stdout.decode().split()) 23 | 24 | # * Capturing -> STDOUT and STDERR 25 | 26 | result_2 = subprocess.run(['rm', 'no_such_file'], capture_output=True) 27 | 28 | print(result_2.returncode) 29 | print(result_2.stdout) 30 | print(result_2.stderr) 31 | -------------------------------------------------------------------------------- /Bash_basics/create_backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Description: 4 | #Script automate the backup, tramsfer, and removal of a local backup file. 5 | 6 | #Author: Abraham 7 | #========================================================================= 8 | 9 | #Current day 10 | DAY="$(date+%Y%m%d)" 11 | 12 | #Input to the scp command 13 | SAVE="labsuser@127.0.0.1:/tmp" 14 | 15 | #Back up file 16 | BACKUP="/home/labsuser/$DAY-backup-companyA.tar.gz" 17 | 18 | #Creates tarbal 19 | sudo tar -csvpzf $BACKUP /home/labsuser/companyA 20 | 21 | # Sends backup file to tmp directory 22 | scp $BACKUP $SAVE 23 | 24 | #Removes backup from original location 25 | rm $BACKUP -------------------------------------------------------------------------------- /Bash_basics/hello_world.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Echo Hello World 4 | echo Hello Wolrd! 5 | 6 | # Variables: 7 | # Use uppercase by convention. 8 | # Letters, numbers, underscores 9 | NAME="Abe" 10 | echo "My name is $NAME" -------------------------------------------------------------------------------- /Bash_basics/webserver_with_staticwebsite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbeTavarez/Python_DevOps_Scripts/d5da15fd39ed186b464a2296f90ceb267ae9dcdb/Bash_basics/webserver_with_staticwebsite -------------------------------------------------------------------------------- /Bash_basics/webserver_with_staticwebsite.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbeTavarez/Python_DevOps_Scripts/d5da15fd39ed186b464a2296f90ceb267ae9dcdb/Bash_basics/webserver_with_staticwebsite.sh -------------------------------------------------------------------------------- /Encryping/hashlib_demo.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | secret_message = 'Is is a super secret message' 4 | 5 | bsecret_message = secret_message.encode() 6 | 7 | # Creates Hashed Object 8 | m = hashlib.md5() 9 | 10 | 11 | m.update(bsecret_message) 12 | 13 | 14 | print(m.digest()) 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python 👨🏻‍💻 Scripts for DevOps, SysAdmins, IT Specilist, Devs and more. 2 | 3 | ### Note 📝 4 | 5 | The main purpose of this repo is to create a huge collection of useful script for all levels (Beginners to Experts) of 6 | IT Specialits, SysAdmins, DevOps, Developers and more... 7 | 8 | Please feel free to fork this repo and contribute! 9 | 10 | If you want to help with the README you're welcome as well. I want to make it as instructional as possible. 11 | 12 | If you spot any errors please let me know. 13 | 14 | Finally don't forget to give the repo a star if you like it. Thanks! 15 | 16 | ## Intro 🗣 17 | 18 | ### Python Cheatsheet 19 | 20 | - Here is a nice handy python cheatsheet (https://overapi.com/python) 21 | 22 | ### How to create a python scripts 23 | 24 | - Create a python file `vim script_0.py` type `#!/usr/bin/env python3` on the first line. 25 | 26 | Note: Inserting a shebang line (such as #!/usr/bin/env python3) as the first line tells the operating system what command we want to use to execute the script. or (sets the interpreter) 27 | 28 | - On the next line type `print("Running script...")` 29 | - On your terminal type `chmod +x script_0.py` to change the file permission. 30 | - Run the script from the terminal `./script_0.py` 31 | 32 | ### How to SSH 33 | 34 | - You can SSH to another computer by: 35 | 36 | `ssh -p username@ip.address` 37 | 38 | - Here is an example: 39 | 40 | `ssh -p 2220 bandit0@bandit.labs.overthewire.org` 41 | 42 | - Sometimes you'll need a certificate or keys to ssh to some systems. 43 | 44 | - You can practice SSH and Linux in this link -> (https://overthewire.org/wargames/bandit/bandit0.html) 45 | 46 | ## Regex Cheatsheet 🕵️‍♀️ 47 | 48 | ![regex_cheatsheet](https://res.cloudinary.com/abetavarez/image/upload/v1609986054/Screen_Shot_2021-01-03_at_8.40.38_PM_wyhtfv.png) 49 | -------------------------------------------------------------------------------- /Testing/errors/__pycache__/validate_user.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbeTavarez/Python_DevOps_Scripts/d5da15fd39ed186b464a2296f90ceb267ae9dcdb/Testing/errors/__pycache__/validate_user.cpython-38.pyc -------------------------------------------------------------------------------- /Testing/errors/character_frequency.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def character_frequency(filename): 4 | """Counts the frecuency of each character in the given file""" 5 | # Fist try to open the file 6 | try: 7 | f = open(filename) 8 | 9 | except OSError: 10 | return None 11 | 12 | # Now process the file 13 | characters = {} 14 | for line in f: 15 | for char in line: 16 | characters[char] = characters.get(char, 0) + 1 17 | f.close() 18 | 19 | return characters 20 | 21 | 22 | if __name__ == "__main__": 23 | 24 | print(character_frequency('test_file.txt')) 25 | -------------------------------------------------------------------------------- /Testing/errors/emails.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import csv 4 | import sys 5 | 6 | 7 | def populate_dictionary(filename): 8 | """Populate a dictionary with name/email pairs for easy lookup.""" 9 | email_dict = {} 10 | with open(filename) as csvfile: 11 | lines = csv.reader(csvfile, delimiter=',') 12 | for row in lines: 13 | name = str(row[0].lower()) 14 | email_dict[name] = row[1] 15 | return email_dict 16 | 17 | 18 | def find_email(argv): 19 | """ Return an email address based on the username given.""" 20 | # Create the username based on the command line input. 21 | try: 22 | fullname = str(argv[1] + " " + argv[2]) 23 | # Preprocess the data 24 | email_dict = populate_dictionary( 25 | '/home/{{ username }}/data/user_emails.csv') 26 | # If email exists, print it 27 | if email_dict.get(fullname.lower()): 28 | return email_dict.get(fullname.lower()) 29 | else: 30 | return "No email address found" 31 | except IndexError: 32 | return "Missing parameters" 33 | 34 | 35 | def main(): 36 | print(find_email(sys.argv)) 37 | 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /Testing/errors/emails_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import unittest 4 | from emails import find_email 5 | 6 | 7 | class EmailsTest(unittest.TestCase): 8 | def test_basic(self): 9 | testcase = [None, "Bree", "Campbell"] 10 | expected = "breee@abc.edu" 11 | self.assertEqual(find_email(testcase), expected) 12 | 13 | def test_one_name(self): 14 | testcase = [None, "John"] 15 | expected = "Missing parameters" 16 | self.assertEqual(find_email(testcase), expected) 17 | 18 | def test_two_name(self): 19 | testcase = [None, "Roy", "Cooper"] 20 | expected = "No email address found" 21 | self.assertEqual(find_email(testcase), expected) 22 | 23 | 24 | if __name__ == '__main__': 25 | unittest.main() 26 | -------------------------------------------------------------------------------- /Testing/errors/practice_errors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import random 3 | 4 | # * Below we have a function that removes an item from an input list. Run it to see what it does. 5 | 6 | my_list = [27, 5, 9, 6, 8] 7 | 8 | 9 | def RemoveValue(myVal): 10 | my_list.remove(myVal) 11 | return my_list 12 | 13 | 14 | print(RemoveValue(27)) 15 | 16 | # * We used the RemoveValue() function to remove the number, 27 from the given list. Great! The function seems to be working fine. However, there is a problem when we try to call the function on the number 27 again. Run the following cell to see what happens. 17 | 18 | print(RemoveValue(27)) 19 | 20 | 21 | # *From the above output we see that our function now raises a ValueError. This is because we are trying to remove a number from a list that is not in the list. When we removed 27 from the list the first time, it was no longer available in the list to be removed a second time. Python is letting us know that the number 27 no longer makes sense for our RemoveValue() function. 22 | 23 | # *We'd like to take control of the error messaging here and pre-empt this error. Fill in the blanks below to raise a ValueError in the RemoveValue() function if a value is not in the list. You can have the error message say something obvious like "Value must be in the given list". 24 | 25 | def RemoveValue(myVal): 26 | if myVal not in my_list: 27 | # code here 28 | else: 29 | my_list.remove(myVal) 30 | return my_list 31 | 32 | 33 | print(RemoveValue(27)) 34 | 35 | 36 | # *Did your error message print correctly? Was the output something like: ValueError: Value must be in the given list? If not, go back to the previous cell and make sure you filled in the blanks correctly. If your error message did print correctly, great! You are on your way to mastering the basics of handling errors and exceptions. 37 | 38 | # *Now, let's look at a different function. Below we have a function that sorts an input list alphabetically. Run it to see what it does. 39 | 40 | my_word_list = ['east', 'after', 'up', 'over', 'inside'] 41 | 42 | 43 | def OrganizeList(myList): 44 | myList.sort() 45 | return myList 46 | 47 | 48 | print(OrganizeList(my_word_list)) 49 | 50 | # *We used the OrganizeList() function to sort a given list alphabetically. The function seems to be working fine. However, there is a problem when we try to call the function on a list containing number values. Run the following cell to see what happens. 51 | 52 | my_new_list = [6, 3, 8, "12", 42] 53 | print(OrganizeList(my_new_list)) 54 | 55 | # * From the above output we see that our function now raises a TypeError. This is because the OrganizeList() function makes sense for lists that are filled with only strings. Take control of the error messaging here and pre-empt this error by filling in the blanks below to add an assert type argument that verifies whether the input list is filled with only strings. You can have the error message say something like "Word list must be a list of strings". 56 | 57 | 58 | def OrganizeList(myList): 59 | for item in myList: 60 | # code here 61 | myList.sort() 62 | return myList 63 | 64 | 65 | print(OrganizeList(my_new_list)) 66 | 67 | # * Did your error message print correctly? Was the output something like: AssertionError: Word list must be a list of strings? If not, go back to the previous cell and make sure you filled in the blanks correctly. If your error message did print correctly, excellent! You are another step closer to mastering the basics of handling errors and exceptions. 68 | 69 | # * Let's look at one last code block. The Guess() function below takes a list of participants, assigns each a random number from 1 to 9, and stores this information in a dictionary with the participant name as the key. It then returns True if Larry was assigned the number 9 and False if this was not the case. Run it to see what it does. 70 | 71 | 72 | participants = ['Jack', 'Jill', 'Larry', 'Tom'] 73 | 74 | 75 | def Guess(participants): 76 | my_participant_dict = {} 77 | for participant in participants: 78 | my_participant_dict[participant] = random.randint(1, 9) 79 | if my_participant_dict['Larry'] == 9: 80 | return True 81 | else: 82 | return False 83 | 84 | 85 | print(Guess(participants)) 86 | 87 | # * The code seems to be working fine. However, there are some things that could go wrong, so find the part that might throw an exception and wrap it in a try-except block to ensure that you get sensible behavior. Do this in the cell below. Code your function to return None if an exception occurs. 88 | 89 | # Revised Guess() function 90 | 91 | 92 | def Guess(participants): 93 | my_participant_dict = {} 94 | for participant in participants: 95 | my_participant_dict[participant] = random.randint(1, 9) 96 | try: 97 | if my_participant_dict['Larry'] == 9: 98 | return True 99 | except KeyError: 100 | return None 101 | else: 102 | return False 103 | 104 | # * Call your revised Guess() function with the following participant list. 105 | 106 | 107 | participants = ['Cathy', 'Fred', 'Jack', 'Tom'] 108 | print(Guess(participants)) 109 | 110 | # * Was the above output None? If not, go back to the code block containing your revised Guess() function and make edits so that the output is None for the previous code block. If the above output was indeed None, congratulations! You've mastered the basics of handling errors and exceptions in Python and you are all done with this notebook 111 | -------------------------------------------------------------------------------- /Testing/errors/test_file.txt: -------------------------------------------------------------------------------- 1 | Counts the frecuency of each character in the given file -------------------------------------------------------------------------------- /Testing/errors/validate_user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def validate_user(username, minlen): 4 | assert type(username) == str, 'username must be a string' 5 | if minlen < 1: 6 | raise ValueError('minlen must be at least 1') 7 | if len(username) < minlen: 8 | return False 9 | if not username.isalnum(): 10 | return False 11 | return False 12 | -------------------------------------------------------------------------------- /Testing/errors/validate_user_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import unittest 4 | from validate_user import validate_user 5 | 6 | 7 | class TestValidateUser(unittest.TestCase): 8 | def test_valid(self): 9 | self.assertEqual(validate_user('validuser', 3), True) 10 | 11 | def test_too_short(self): 12 | self.assertEqual(validate_user('inv', 5), False) 13 | 14 | def test_invalid_characters(self): 15 | self.assertEqual(validate_user('invalid_user', 1), False) 16 | 17 | def test_invalid_minlen(self): 18 | self.assertRaises(ValueError, validate_user, 'user', -1) 19 | 20 | 21 | # Run test 22 | unittest.main() 23 | -------------------------------------------------------------------------------- /Testing/re_arrange/__pycache__/re_arrange.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbeTavarez/Python_DevOps_Scripts/d5da15fd39ed186b464a2296f90ceb267ae9dcdb/Testing/re_arrange/__pycache__/re_arrange.cpython-38.pyc -------------------------------------------------------------------------------- /Testing/re_arrange/re_arrange.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | # * Define functions 6 | 7 | 8 | def rearrange_name_regex(name): 9 | result = re.search(r'^([\w .]*), ([\w .]*)', name) 10 | # edge case (empty string) 11 | if result is None: 12 | return name 13 | return '{} {}'.format(result[2], result[1]) 14 | 15 | 16 | def rearrange_name(name): 17 | result = name.split(',') 18 | return f'{result[1]} {result[0]}' 19 | -------------------------------------------------------------------------------- /Testing/re_arrange/re_arrange_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from re_arrange import rearrange_name_regex 4 | import unittest 5 | 6 | # * Basic way of testing is trying with different inputs 7 | print('Basic Test output -->', rearrange_name_regex('Lovelace, Ada')) 8 | print('Basic Test output -->', rearrange_name_regex('Yaeger, Ereh')) 9 | 10 | # * Now we will test using the UNITTEST MODULE 11 | 12 | 13 | class TestRearrange(unittest.TestCase): 14 | def test_basic(self): 15 | testcase = 'Lovelace, Ada' 16 | expected = 'Ada Lovelace' 17 | self.assertAlmostEqual(rearrange_name_regex(testcase), expected) 18 | 19 | def test_empty(self): 20 | testcase = '' 21 | expected = '' 22 | self.assertEqual(rearrange_name_regex(testcase), expected) 23 | 24 | def test_double_name(self): 25 | testcase = 'Hopper, Grace M.' 26 | expected = 'Grace M. Hopper' 27 | self.assertEqual(rearrange_name_regex(testcase), expected) 28 | 29 | def test_one_name(self): 30 | testcase = 'Mikasa' 31 | expected = 'Mikasa' 32 | self.assertEqual(rearrange_name_regex(testcase), expected) 33 | 34 | 35 | unittest.main() 36 | -------------------------------------------------------------------------------- /intro/create_a_command_line_parse/click_group.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import click 3 | 4 | # * Create a top level group 5 | 6 | 7 | @click.group() 8 | def cli(): 9 | # * func acts as top level group 10 | pass 11 | 12 | 13 | @click.group(help='Worker related commands') 14 | def workers(): 15 | # * Create a group to to hold the workers commands 16 | pass 17 | 18 | 19 | # * Adds the workers group as a command to top level group 20 | cli.add_command(workers) 21 | 22 | 23 | @workers.group(help='Spawn new worker') 24 | def worker(): 25 | worker_name = 'Main worker' 26 | print(f"{worker_name} is now spawing...") 27 | 28 | 29 | @workers.command(help='List all of the workers') 30 | def list_workers(): 31 | workers_list = ['alpha', 'bravo', 'charlie'] 32 | print(f"Workers: {','.join(workers_list)}") 33 | 34 | 35 | @cli.command(help='Talk to worker') 36 | @click.option('--greeting', default='Whats up bro?', help='Greating from admin') 37 | @click.argument('name') 38 | def admins(greeting, name): 39 | message = f'{greeting} {name}' 40 | print(message) 41 | 42 | 43 | if __name__ == '__main__': 44 | cli() 45 | -------------------------------------------------------------------------------- /intro/create_a_command_line_parse/parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # * Getting arguments from the terminal in a vanilla way(no modules). 4 | 5 | 6 | # We need the sys module 7 | import sys 8 | 9 | 10 | def user_greeting(greeting, name): 11 | message = f'{greeting} {name}' 12 | print(message) 13 | 14 | 15 | # The expression (if __name__ == '__main__':) will test if we are running the script from the terminal. 16 | 17 | 18 | if __name__ == '__main__': 19 | greeting = 'Hello' 20 | name = 'User' 21 | 22 | if '--help' in sys.argv: 23 | help_message = f'Usage: {sys.argv[0]} --name --greeting ' 24 | print(help_message) 25 | sys.exit() 26 | 27 | if '--name' in sys.argv: 28 | # get position after name flag 29 | name_index = sys.argv.index('--name') + 1 30 | if name_index < len(sys.argv): 31 | name = sys.argv[name_index] 32 | 33 | if '--greeting' in sys.argv: 34 | # get position after greeting flag 35 | greeting_index = sys.argv.index('--greeting') + 1 36 | if greeting_index < len(sys.argv): 37 | greeting = sys.argv[greeting_index] 38 | 39 | user_greeting(greeting, name) 40 | 41 | # * First make the script executable 42 | # * Now you can run the script: 43 | # ./parse.py --greeting 'Welcome to the Matrix' --name "Neo" 44 | -------------------------------------------------------------------------------- /intro/create_a_command_line_parse/using_argparse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # * Using Argparse module to handle command line arguments 4 | 5 | import argparse 6 | 7 | if __name__ == '__main__': 8 | # Create parser object with it's documentation 9 | parser = argparse.ArgumentParser(description='Echo input') 10 | # adds position based command with it's help message 11 | parser.add_argument('message', help='Message to echo') 12 | # adds optional argument, storing it as a boolean 13 | parser.add_argument('--twice', '-t', help='Do it twice', 14 | action='store_true') 15 | # Use the parser to parse the arguments 16 | args = parser.parse_args() 17 | # Now we have access the arguments value by their names 18 | print(args.message) 19 | # the (--) is removed from (--twice) 20 | if args.twice: 21 | print(args.message) 22 | 23 | 24 | # * Now you can execute this script with: 25 | # ./using_argparse.py hello there! 26 | # ./using_argparse.py hello there! --twice 27 | -------------------------------------------------------------------------------- /intro/create_a_command_line_parse/using_click.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import click 4 | 5 | 6 | @click.command() 7 | @click.option('--greeting', default='Hello', help='Who do you want to greet?') 8 | @click.option('--name', default='Tammy', help='Who do you want to greet?') 9 | def greet(greeting, name): 10 | print(f"{greeting} {name}") 11 | 12 | 13 | if __name__ == '__main__': 14 | greet() 15 | -------------------------------------------------------------------------------- /intro/create_a_command_line_parse/using_fire.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import fire 4 | 5 | 6 | def greet(greeting='hey', name='abe'): 7 | print(f"{greeting} {name}") 8 | 9 | 10 | if __name__ == '__main__': 11 | fire.Fire() 12 | -------------------------------------------------------------------------------- /intro/creating_a_module/__pycache__/first_module.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbeTavarez/Python_DevOps_Scripts/d5da15fd39ed186b464a2296f90ceb267ae9dcdb/intro/creating_a_module/__pycache__/first_module.cpython-38.pyc -------------------------------------------------------------------------------- /intro/creating_a_module/first_module.py: -------------------------------------------------------------------------------- 1 | 2 | import math 3 | 4 | # * Let's encapsulate some code in this file 5 | # * Here we declared some functions to be use outside this file 6 | # * Use these functions on the script.py file 7 | 8 | # *** Calculate areas *** # 9 | 10 | # * Triangle area 11 | 12 | 13 | def triangle(base, height): 14 | return base * height / 2 15 | 16 | # * Rectangle area 17 | 18 | 19 | def rectangle(base, height): 20 | return base*height 21 | 22 | 23 | # * Circle area 24 | 25 | def circle(radius): 26 | return math.pi*(radius**2) 27 | -------------------------------------------------------------------------------- /intro/creating_a_module/script.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # * This will import the file or module 'first_module' 4 | # * and give it the alias 'fm' 5 | import first_module as fm 6 | 7 | # * Let's use oue 'first_module now' 8 | 9 | # * call the triangle function from the 'fm' module 10 | triangle = fm.triangle(5, 3) 11 | print(triangle) 12 | 13 | # * call the rectangle function from the 'fm' module 14 | rectangle = fm.rectangle(8, 4) 15 | print(rectangle) 16 | 17 | 18 | # * Finally let's call the circle function from the 'fm' module 19 | circle = fm.circle(6) 20 | print(circle) 21 | -------------------------------------------------------------------------------- /intro/make_script_executable/script_0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # *************** Making s script executable ******************* 4 | 5 | # * Notice how we set the interpreter at the top of the file to python3 6 | #! using -> #!/usr/bin/env python3 <- on all files 7 | 8 | 9 | # * Then write your code after: 10 | 11 | print("Running script...") 12 | -------------------------------------------------------------------------------- /intro/use_command_line_args/sys_args.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # *********** First command line tool ************ 4 | 5 | # import the system module 6 | import sys 7 | 8 | # we can pass a List of arguments to our script when we're executing it from the command line or terminal 9 | 10 | # This Argument List is called 'argv' or 'arguments vertor' 11 | 12 | # Let's se this in action: 13 | 14 | if __name__ == "__main__": 15 | print(f'The first argument -> : {sys.argv[0]}') 16 | print(f'The second argument -> : {sys.argv[1]}') 17 | print(f'The third argument -> : {sys.argv[2]}') 18 | print(f'The fourth argument -> : {sys.argv[3]}') 19 | 20 | 21 | # * Now run the script from the command line with the fillowing arguments: 22 | # * Rememmber you need to be in the same directory the script is located 23 | # ./sys_args.py 'arg1' 'arg2' 'arg3' 24 | --------------------------------------------------------------------------------