Skip to content

Instantly share code, notes, and snippets.

@techthoughts2
Last active March 6, 2024 06:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save techthoughts2/e6c13162b254c14622c19116eab08be9 to your computer and use it in GitHub Desktop.
Save techthoughts2/e6c13162b254c14622c19116eab08be9 to your computer and use it in GitHub Desktop.
python_learning
"""
Ctrl+K Ctrl+0 Fold (collapse) all regions editor.foldAll
Ctrl+K Ctrl+J Unfold (uncollapse) all regions
Ctrl+Shift+[ Fold (collapse) region editor.fold
Ctrl+Shift+] Unfold (uncollapse) region editor.unfold
Ctrl+K Ctrl+[ Fold (collapse) all subregions editor.foldRecursively
Ctrl+K Ctrl+] Unfold (uncollapse) all subregions editor.unfoldRecursively
"""
# region links
"""
- Online Resources -
Python documentation - https://docs.python.org/3/
Python.org - https://www.python.org/
Tutorial - Learn Python in 10 minutes - https://www.stavros.io/tutorials/python/
HackerRank - Practice Python - https://www.hackerrank.com/domains/python
Microsoft - Introduction to Python - https://docs.microsoft.com/en-us/learn/modules/intro-to-python/
- Book Resources -
Learning Python - https://www.amazon.com/Learning-Python-5th-Mark-Lutz/dp/1449355730
PowerShell Guide to Python - https://leanpub.com/PowerShell-to-Python
Automate the Boring Stuff with Python - http://automatetheboringstuff.com/
- VSCode Setup -
Getting Started with Python in VS Code - https://code.visualstudio.com/docs/python/python-tutorial
Python - Introduction to Visual Studio Code - https://realpython.com/lessons/introduction-visual-studio-code/
Python in Visual Studio Code - https://code.visualstudio.com/docs/languages/python
Visual Studio Code (Windows) - Setting up a Python Development Environment and Complete Overview - https://youtu.be/-nh9rCzPJ20
Setting Up VSCode for Python Programming - https://youtu.be/W--_EOzdTHk
Python extension no longer natively supports snippets: https://devblogs.microsoft.com/python/python-in-visual-studio-code-january-2021-release/
Old Snippets: https://github.com/microsoft/vscode-python/blob/2020.12.424452561/snippets/python.json
Create snippets: https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets
- Videos -
Python Tutorial: VENV (Windows) - How to Use Virtual Environments with the Built-In venv Module - https://youtu.be/APOPm01BVrk
- Misc -
Argparse - https://docs.python.org/3/howto/argparse.html
Python Package Index (PyPI) - https://pypi.org/
- Python Package -
Making a Python Package - https://python-packaging-tutorial.readthedocs.io/en/latest/setup_py.html
Packaging Python Projects - https://packaging.python.org/tutorials/packaging-projects/
Create, build and ship a Python3 pip module in 5 minutes - https://itnext.io/create-build-and-ship-a-python3-pip-module-in-5-minutes-31dd6d9d5c8f
CookieCutter - https://github.com/cookiecutter/cookiecutter
Cookiecutter PyPackage - https://github.com/audreyfeldroy/cookiecutter-pypackage
How Do I Make My Own Command-Line Commands Using Python? - https://dbader.org/blog/how-to-make-command-line-commands-with-python
Develop python CLI with subcommands using Click - https://dev.to/drcloudycoder/develop-python-cli-with-subcommands-using-click-4892
- Decorators -
Python’s Functions Are First-Class - https://dbader.org/blog/python-first-class-functions
Python Decorators: A Step-By-Step Introduction - https://dbader.org/blog/python-decorators
"""
# endregion
# region install (windows)
# winget search --id Python.Python
# winget install python
#
# endregion
# region vscode setup
"""
https://code.visualstudio.com/api/language-extensions/language-configuration-guide
https://github.com/microsoft/vscode-python/issues/33
C:\Program Files\Microsoft VS Code\resources\app\extensions\python\language-configuration.json(in windows) or
/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/extensions/python/language-configuration.json(in mac)
"folding": {
"offSide": true,
"markers": {
"start": "^\\s*#\\s*region\\b",
"end": "^\\s*#\\s*endregion\\b"
}
}
"""
# endregion
# region version
# checking the version
import sys
a = sys.version_info
print(sys.version_info)
print(sys.platform)
# python --version
# py --version
# py --list-paths
# endregion
# region evaluating objects
# https://stackoverflow.com/questions/1006169/how-do-i-look-inside-a-python-object/38629300
full = sys
dir(full) # list details and variables
type(full) # determine what type a variable is
# exploring dict
full.__dict__
# or
vars(full)
import pprint
pprint.pprint(vars(full))
# or
from pprint import pprint
pprint(vars(full))
# inspecting an object
import inspect, os
inspect.ismodule(os)
inspect.ismodule("this is a string")
# find the members of the object categorized as built-in methods
# define a float variable
pi = 3.14159
inspect.getmembers(pi, predicate=inspect.isbuiltin)
# once you know the mattributes/methods of the object, you can use them
pi.is_integer()
pi.as_integer_ratio()
for member in inspect.getmembers(pi, predicate=inspect.isbuiltin):
print(member)
# endregion
# region pip
# install pip if for some reason it is missing
# python -m ensurepip
# You should consider upgrading via the 'c:\python39\python.exe -m pip install --upgrade pip' command.
# list pip installed modules
# pip list
# generate list of module for requirements.txt file
# pip freeze
# install a list of requirements from a requirements.txt file
# pip install -r requirements.txt
# update an existing package
# pip install boto3 --upgrade
# find information about a specific package
# pip show black
# find install locations for packages
# pip list -v
# update pip
# pip install --upgrade pip
# c:\python39\python.exe -m pip install --upgrade pip
# Update all Python Packages on Windows using PowerShell
# pip freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}
# endregion
# region pipx
# py -m pip install --user pipx
# .\pipx.exe ensurepath
# endregion
# region virtual environments
# both of the commands work on windows:
# py -3 -m venv .venv
# python -m venv .venv
# .venv\scripts\activate
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
# python -m venv myProject/myVenv
# close the virtual environment
# deactivate
# delete the virtual environment
# rmdir /s .venv
# search for new versions of requirements
# https://pypi.org/project
# endregion
# region documentation
# an inline comment
"""
multi
line
comments
"""
dir(print) # list of attributes and methods avail in objects
import sys
len(dir(sys)) # number of attributes and methods in sys
len([x for x in dir(sys) if not x.startswith("__")]) # non __x count only
[x for x in dir(sys) if not x.startswith("__")] # non __x only
len([x for x in dir(sys) if not x.startswith("_")]) # non _x count only
[x for x in dir(sys) if not x.startswith("_")] # non _x only
# dir can also be used to evaluate basic empty objects
dir([]) # eval attributes of empty list
dir("") # eval attributes of empty string
dir(str) # this is also an empty string eval
__doc__ # in file documentation attached to an object
import sys
print(sys.__doc__) # print the docstring of the module
print(sys.displayhook.__doc__) # print the docstring of a function in the module
# region help
import sys
help(sys.displayhook)
# you can get help on a module that is not imported by putting it in a string
help("os.pardir")
help(help) # help on help
help("builtin") # list builtin methods
help("modules") # list builtin modules
help(print)
help(input)
help(open)
help(dict) # help on class dict
s = "astring"
help(s.replace)
# PyDoc help function
# python -m pydoc -b
# endregion
# endregion
# region general notes
# variables are dynamically typed
"""
len - Return the number of items in a container.
max - With two or more arguments, return the largest argument.
ord - Return the Unicode code point for a one-character string.
pop - Remove and return item at index (default last).
eval - treats a string as a piece of exec program code - strings containing Python expression
pass - allows code to pass and run, can be used as a placeholder for future code.
"""
# theory info
# immutable: numbers, strings, tuples
# mutable: lists, dictionaries, sets
"""
variable syntax
must start with underscore or letter
can be followed by letters, underscores, digits
variables are case specifc. AVOCADO is not avocado
_avocado
avocado
Avocado_2
"""
"""
reserved words
and
as
assert
break
class
continue
def
del
elif
else
except
False
finally is
for
from
global
if
import
in
lambda
None
nonlocal
not
or
pass
raise
return
True
try
while
with
yield
"""
"""
conventions
_avocado - single underscore. not imported by a from module import * statement
__avocado__ - dunder - two leading/trailing underscores - system defined names
__avocado - localized to enclosing classes
_ - retains result of the last expression
"""
# shebang
# windows
#! python3
# linux
#! /usr/bin/python3
#! /usr/bin/env python3
# osx
#! /usr/bin/env python3
# data type declation reference
s = "" # string
fruits = [] # list
p = () # tuple
d = {} # dictionary
# scalar types
num = 0 # int
var = True # bool
float = 3.125 # float
a = None # no value
# a better way (prettier) to see globs of text
import pprint
yo = "AString"
pprint.pprint(dir(yo))
# REPL - Read Evaluate Print Loop
# _ can be used to refer to most recently printed value
3 * 5
# _ <- would be 15
# exit() # or Ctrl + z to exit REPL
# view the Zen of python
import this
# variable scopes - LEGB rule
# Local - inside the current function
# Enclosing - inside enclosing function
# Global - at the top level of the module
# Built-in - in the special builtins module
count = 0
def set_count(c):
global count # set the global level count
count = c
# endregion
# region output/input
# region print
print("hello", "world")
print("hello" + " world")
print("Hello World!") # normal output
print("Hello World!", end="") # keeps things on same line
print("My name is Jake")
# sep is a special variable that introduces the space
print(1, 2, 3, 4)
print(1, 2, 3, 4, sep="**")
# endregion
# region working with files
# out file
filename = open("c:/rs-pkgs/test.txt", "w")
print("Pretty cool!", file=filename)
filename.close()
# use stream redirection instead
# python script1.py > saveFile.txt
# read file
filenameread = open("c:/rs-pkgs/test.txt", "r")
content = filenameread.read()
filenameread.close()
# using file iterations
filePath = r"C:\Test\script2.py"
lines = [line.rstrip() for line in open(filePath, "r")]
# capitalize all lines of a file
capLines = [line.upper() for line in open(filePath, "r")]
# replace text in a file
replaceLines = [line.replace("hello", "goodbye") for line in open(filePath, "r")]
# endregion
# reading from console
name = input("Enter your name:")
print("Hello", name)
# read securely
import getpass
password = getpass.getpass("Enter your password: ")
# region working with json
import json
# load vs loads | dump vs dumps = the s is for STRING. use loads/dumps when working with string directly
name = dict(first="Jake", last="M")
record = dict(name=name, job=["sysdev", "engineer"], age=37)
jsonString = json.dumps(record)
# convert back
loadFromJson = json.loads(jsonString)
record == loadFromJson # check if they match!
# endregion
# endregion
# region general tasks
# show current working directory
import os
os.getcwd() # current working directory
# list contents of current directory
os.listdir()
# change working directory
os.chdir("..")
# import is an expensive operation and therefore is only done once
# it can be forced again with a reload
# NOTE: this must already have been imported at least once
from imp import reload
reload(os)
# generate random number
import random
random.random()
random.choice([1, 2, 3, 4])
# generate random from a list of choices
random.choice(["Picard", "Sisko", "Janeway"])
# check if number is even
numCheck = 4
if numCheck % 2 == 0: # condition to check even number
print(numCheck, "is an even number")
# region xml
# using ElementTree
import xml.etree.ElementTree as ET
# parse to xml document
tree = ET.parse("c://test//test.xml")
root = tree.getroot() # get xml root
# returns XML Document root
root.tag
# returns XML parent node
root.getchildren()[0].tag
# returns XML child node
root.getchildren()[0].getchildren()[1].tag
# accessing a data value
root.getchildren()[0].getchildren()[1].text
# endregion
# region json
import json
json_string = '{"first": "Jake", "last":"Morrison"}'
# loads and parses the JSON
parsed_json = json.loads(json_string)
# accessing the parsed JSON like a hash table
print(parsed_json["first"])
# serialize data to json
import json
data = {
"first": "Jake",
"last": "Morrison",
"skills": ["PowerShell", "Python", "AWS"],
}
print(json.dumps(data, indent=4))
# writing the objects to a file serialized in JSON format
with open("C://Temp//test.json", "w") as filehandler:
json.dump(data, filehandler, indent=4)
# reading in json from a file
with open("C://Temp//test.json", "r") as filehandler:
zeData = json.load(filehandler) # loads as dictionary
# endregion
# region csv
import csv
# open the file in read-only mode
with open("c://Temp//aCSV.csv", "r") as f:
# read the content of the csv file
reader = csv.reader(f, delimiter=",") # this will be a _csv.reader object
for row in reader:
# return each row as a list
print(row)
# csv info can also be loaded directly in a dictionary
import csv
# open the file in read-only mode
with open("c://Temp//aCSV.csv", "r") as f:
# read the content of the csv file
reader = csv.DictReader(f, delimiter=",")
for row in reader:
print("FirstName:{0} LastName: {1}".format(row["FirstName"], row["LastName"]))
# write CSV information to a file
import csv
header = ["Name", "Company"]
rows = [["Jake", "AWS"], ["Joe", "MedCenter"], ["John", "Microsoft"]]
with open("c://Temp//Data.csv", "w", newline="") as f:
writer = csv.writer(f, delimiter=",")
writer.writerow(header)
writer.writerows(rows)
# endregion
# endregion
# region importing
import os # importing module
import time, sys # importing multiple modules
time.sleep(2) # sleeps for 2 seconds
print("Platform:", sys.platform) # platform identifier, like Win32
# importing multiple sub-modules
from statistics import mean, variance, median, stdev
# import module alias
import math as m
# endregion
# region parameters
# short example that shows that copies of things are not made
e = [1, 2, 3]
def replaceE(list):
return list
f = replaceE(e)
e is f
# default arguments in a function. border is set to -
def banner(message, border="-"):
line = border * len(message)
print(line)
print(message)
print(line)
# you do not have to specify border here because it has a value
banner("Hi Jake")
# here you can provide a default argument
banner("Hi Jake", "*") # what does this do? not clear. use a keyword
# positional argument vs keyword argument
banner("Hi Jake", border="*") # this will resolve to keyword
# function to get current time that does not work.
# the default variable is only loaded once when loaded to memory
def show_default(arg=time.ctime()):
print(arg)
# always a good idea to use immutable default values
def add_spam(menu=None):
if menu is None:
menu = []
menu.append("spam")
return menu
add_spam()
# command line arguments - EXAMPLE 1
"""
sys.argv is a list of arguments passed to the script
sys.argv[0] is by default the path of the script
user defined starts at [1]
"""
import sys
if len(sys.argv) > 1:
print("Arguments: ", sys.argv)
print(
"Max number is: ",
max(
sys.argv[1],
sys.argv[2],
sys.argv[3],
),
)
print("argv[0]: ", sys.argv[0])
# command line arguments - EXAMPLE 2
import sys
# https://docs.python.org/3/howto/argparse.html
# !!!! sys.argv[0] is always the name of the Python file to which command line arguments are passed.
# sys.argv is a list of arguments passed to the script
# sys.argv[0] is by default the path of the script
# and user-defined arguments start with index 1
if len(sys.argv) > 1:
print("Arguments: ", sys.argv)
length = len(sys.argv)
for i in range(length):
# print(str(i))
print("argv[{0}]:".format(i), sys.argv[i])
# argparse module in python - EXAMPLE1
import argparse
help(argparse)
parser = argparse.ArgumentParser()
parser.add_argument("FName", help="first name", type=str)
parser.add_argument("LName", help="last name", type=str)
# optional parameter - designated with the '--'
parser.add_argument("--MName", help="middle name", type=str)
# parameter with alias + switch paramater
parser.add_argument("-s", "--sum", help="adds integers", action="store_true")
# setting a default value
parser.add_argument("--number", help="int number value", type=int, nargs="?", default=3)
# parsing the arguments
args = parser.parse_args()
print(args)
# argparse - EXAMPLE2
import argparse
# create the argument parser
parser = argparse.ArgumentParser()
# add the arguments
# a = name of the parameter
# type = int
# help text for user help
# these are mandatory arguments
parser.add_argument("a", help="help text", type=int)
parser.add_argument("b", help="Provide a integer value", type=int)
# optional arguments
# -s argument alias for sum
# --sum the double -- makes this argument optional
# action="store_true" makes this act like a switch variable
# this will be true if user provides. this will be false if the user does not provide
parser.add_argument("-s", "--sum", help="Add the integers", action="store_true")
# setting a default value to an argument
# Default argument will be passed to '--n' parameter
# nargs --> number of command-line arguments that should be consumed
# example: enter the starting and ending character (i, e)
# https://docs.python.org/3/library/argparse.html#nargs
# '?' = 0 or 1
# N = an integer
# '*' = arguments presented are gathered into a list
# '+' = just like '*' into a list but error generated if not at least 1 argument present
parser.add_argument(
"--n", help="Provide a integer value", type=int, nargs="?", default=3
)
# parsing the cmdline-arguments
args = parser.parse_args()
print(args)
# endregion
# region strings
s = "spam" # load a string variable
len(s) # string length
s[0] # first character of a string
s[-1] # last character in string
s[1:3] # piece of a string
len(s) # length of a string
s.find("pa") # find piece of a string
s.replace("pa", "xyz") # replace a portion of a string with something else
s.upper() # make a string all uppercase
s.lower() # make a string all lowercase
s.isalpha() # check if string is only alpha characters
s.isalnum() # both alpha and numeric
line = "aaa,bbb,ccc,dd"
line.split(",") # split a line at a certain character
line.rstrip() # Return a copy of the string S with trailing whitespace removed
repr(line) # Return a string containing a printable representation of an object.
print("-" * 80) # repetitive print with multiplication
ord("s") # converts charcater to ASCII byte value
chr(115) # converts ASCII byte value to string
line = "aaa,bbb,ccc,dd\n"
line.rstrip().split(
","
) # two commands in one, run left to right. strips the whitespace, then splits
"{0}, eggs, and {1}".format("spam", "SPAM!") # format output
s = "A\nB\tC" # \n is end-of-line, \t is tab
s = r"C:\text\new" # use of a raw string that turns off backslash escape mechanism
raw_s = r"Hi\nHello"
print(raw_s)
# even with r - the string can not end in a backlash - it must be escaped and added on
endInBackSlash = r"C:\text\new" + "\\"
# pattern matching - requires re - Support for regular expressions (RE).
import re
match = re.match("Hello[ \t]*(.*)world", "Hello Python world")
match.group(1)
# strings can be concatenated together
S1 = "Jake"
S2 = "M"
name = S1 + S2
# explode a string into a list
S = "Jake"
L = list(S) # now you can make quick, performant changes
# implode a list back into a string
N = "".join(L)
# testing a character in a string
"a" in "jake"
"z" not in "jake"
"ake" in "jake"
# convert int to string
x = 5
print("The number is: " + str(x))
# join is much more efficient than +=
colors = ";".join(["red", "blue", "gray"])
colors.split(";")
"".join(["humble", "bundle"])
# region string substitutions
# using format method
length = 2
for i in range(length):
# print(str(i))
print("number[{0}]:".format(i))
# using a F-String (aka formatted string literals)
name = "Jake"
f"Hello {name}!"
name = "Jake"
lName = "Morrison"
print("Yo %s %s what's up?" % (name, lName)) # 1 - old style, don't use
print("Yo {0} {1} what's up?".format(name, lName)) # 2 - new style, use format method
print(f"Yo {name} {lName} what's up?") # 3 - even newer, ok to use
# multi-line string substitution
name = "Jake"
born = "UK"
string = f"""my name is {name}
and I was born in {born}
"""
print(string)
# using dictionaries for formatting
coordinates = {"latitude": "31.24E", "longitude": "-125.81N", "local": "TX"}
"Coordinates: {latitude}, {longitude}, {local}".format(**coordinates)
# endregion
# region string methods
S = "jake"
S.capitalize() # Return a capitalized version of S, i.e. make the first character have upper case and the rest lower case
S.casefold() # removes all case distinctions present in a string. It is used for caseless matching, i.e. ignores cases when comparing.
# S.center() # Return S centered in a Unicode string of length width.
S.count(
"a"
) # Return the number of non-overlapping occurrences of substring (how many occurrences of a)
S.encode() # Encode the string using the codec registered for encoding.
S.endswith("e") # Return True if S ends with the specified suffix, False otherwise.
# S.expandtabs() # Return a copy of S where all tab characters are expanded using spaces. If tabsize is not given, a tab size of 8 characters is assumed.
S.find(
"k"
) # Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. returns -1 if not found.
S.format() # {0}, {1}
S.index(
"ak"
) # Return the lowest index in S where substring sub is found - index throws exception if not found
S.isalnum() # Return True if all characters in S are alphanumeric
S.isdecimal()
# S.ljust() #Return S left-justified in a Unicode string of length width.
S.lower() # Return a copy of the string S converted to lowercase.
S.lstrip() # Return a copy of the string S with leading whitespace removed.
# S.maketrans()
"""
Partition the string into three parts using the given separator.
This will search for the separator in the string. If the separator is found,
returns a 3-tuple containing the part before the separator, the separator
itself, and the part after it.
If the separator is not found, returns a 3-tuple containing the original string
and two empty strings.
"""
S.partition("|")
# the use of underscore here loads the split into a dummy value that won't be used
origin, _, destination = "Seattle-Boston".partition("-")
S.replace(
"j", "r"
) # Return a copy with all occurrences of substring old replaced by new.
S.rfind()
S.rindex()
# S.rjust()
# S.rpartition()
# S.rsplit()
# S.rstrip()
S.split(
"a"
) # Return a list of the words in the string, using sep as the delimiter string
S.isdigit() # Return True if all characters in S are digits and there is at least one character in S, False otherwise.
# S.isidentifier()
S.islower() # Return True if all cased characters in S are lowercase
S.isnumeric()
S.isprintable()
S.isspace() # Return True if all characters in S are whitespace
S.istitle() # Return True if S is a titlecased string
S.isupper() # Return True if all cased characters
S.join(("is", "awesome")) # Concatenate any number of strings.
S.splitlines() # Return a list of the lines in the string, breaking at line boundaries.
S.startswith("j") # Return True if S starts with the specified prefix, False otherwise.
S.strip() # Return a copy of the string S with leading and trailing whitespace removed.
S.swapcase() # Return a copy of S with uppercase characters converted to lowercase and vice versa.
S.title() # Return a titlecased version of S, i.e. words start with title case characters, all remaining cased characters have lower case.
# S.translate()
S.upper() # uppercase
S.zfill(
50
) # Pad a numeric string S with zeros on the left, to fill a field of the specified width
# endregion
# region escape characters
r"""
\newline
\\ Backslash
\' Single quote
\" Double quote
\a Bell
\b Backspace
\f Formfeed
\n Newline
\r Carriage return
\t Horizontal tab
\v Vertical tab
\xhh Character with hex value hh
\ooo Character with octal value
\O Null: binary 0 character
\N{ id }Unicode database ID
"""
# endregion
# endregion
# region numbers
numbers = [1, 2, 3, 4]
for number in numbers:
print()
float(7)
float("nan") # not a number
float("inf") # infinity
float("-inf") # negative infinity
# endregion
# region lists
# most general sequence
# positionally ordered collections of arbitrarily typed objects
# no fixed size
# mutable
L = [] # an empty list
l = [123, "nemo", 1.23] # list of different objects
type(l) # type of list
len(l) # 3 objects found
l[0] # index position
l[-1] # find the last value in the list
l[:-1] # this returns all items in list except the last one
l[1:3] # return a slice of a list
l[1:] # slice everything past 1
l[:2] # slice everything up to 2
"nemo" in l # check if nemo is in the list
78 not in l # check that 78 is not in the list
t = l[:] # copy the list into t. t is now a unique variable without a reference
u = l.copy() # another way to copy a list
n = [4, 5, 6]
z = l + n # lists can be added together - concatenation
3 in [1, 2, 3] # find if something is in a list
[avocado, pancakes] = ["Good", "YUM!"] # this creates 2 separate lists
# sorting list in descending order
nums = [4, 1, 12, 5, 2, 11, 121, 23, 14, 45, 150, 67]
sorted(nums, reverse=True)
# sorting list in ascending order
sorted(nums)
# region list methods
l = [123, "nemo", 1.23] # list of different objects
# growing
l.append("new") # lists can be added to at the end - appends object - even another list
l.extend([5, 6, 7]) # mutates the original list
l.insert(2, "X")
# searching
l.index("X") # find the index of X
l.count("X") # how may times is X in the list?
# sorting and reversing
l.sort()
l.reverse()
# copying and clearing
l.copy() # Return a shallow copy of the list.
l.clear() # Remove all items from list.
# shrinking
l.pop(
2
) # remove item and specified index - note: this causes the index to shrink. DEFAULT is -1
l.remove("X")
p = ["b", "a", "c"]
p.sort() # sort a list - must all be the same type
p.reverse() # sort list in reverse
del l[2]
del l[1:2]
l[1:2] = []
# assignment
l[1] = 3
# list comprehension and maps
l = [x**2 for x in range(5)]
# endregion
# lists can also contain other lists and dictionaries
# endregion
# region tuples
# tuple objects - list that cannot be changed
# sequences - like lists - but are immutable
# used to represent fixes collections of items
p = () # an empty tuple
p = ("I",) # a one item tuple
p = (1, 2, 3, 4) # 4 item tuple
p = ("Jake", ("dev", "engineer")) # nested tuple
p[1][1] # access nested tuple info
len(p) # length
p + (5, 6)
p + ("whoa",) # a trailing comma is required when adding just a single item
p + ("whoa2", "whoa3")
tmpList = list(p) # make a list from a tuple
p.index(4) # index of 4
p.count(4) # the number of times the number 4 is found in the tuple
# tuple unpacking
def minmax(items):
return min(items), max(items)
# example of tuple unpacking
lower, upper = minmax([8, 99, 177, 53, 2, 88, 67, 99, 120, 5])
# endregion
# region dictionaries
# known as mappings - collections of other objects
# store by key instead of relative position - keys to associated values
# mutable
d = {"food": "hotdog", "quantity": 2, "color": "red"}
d["food"] # get the value of the index food
d["quantity"] += 1 # we can manipulate the quantity by referencing the index
# more common way to write a dictionary
d = {} # declare an empty dictionary
d["food"] = "hotdog"
d["quantity"] = 2
d["color"] = "red"
# nested dictionary
rec = {
"name": {"first": "Joe", "last": "Joey"},
"jobs": ["dev", "mgr"],
"age": 40,
}
rec["name"] # index by key
rec["name"]["last"]
rec["jobs"]
rec["jobs"][-1]
# alternative, more "PowerShelly" way of doing dictionary:
d = dict(name="Jake", job="Engineer")
# trap an index error
aMatrix = {}
aMatrix[(2, 3, 4)] = 88
try:
print(aMatrix[(2, 3, 6)]) # there is no 6 key loaded
except KeyError:
print(0)
# interacting with / finding dict values/keys
users = [
{
"name": {"first": "Jake", "last": "Morrison"},
"jobs": ["Dad", "Systems Developer"],
"born": "UK",
},
{
"name": {"first": "Joey", "last": "Joey"},
"jobs": ["Secret Agent"],
"born": "UK",
},
]
users[0].keys() # list all the keys of the first dict entry
users[0].values() # list all the values of the first dict entry
listCount = len(users) # get the number of dicts in the list
# get all the values from all the dicts in the list
for i in range(listCount):
users[i].values()
# check if an entry is found
users[0]["name"]["first"].__contains__("Jake")
# iterating through key-value pairs
peeps = {}
peeps["Jake"] = "Human"
peeps["Ruffles"] = "Dog"
for key, value in peeps.items():
"key: {0}, value: {1}".format(key, value)
# another way to iterate though key-value pairs
colors = dict(aquamarine="#7FFFD4", honeydew="#F0FFF0", sienna="#A05222D")
for key in colors:
print(f"{key} => {colors[key]}")
# iterating just through values
for value in colors.values():
print(value)
# iterating just through keys
for key in colors.keys():
print(key)
# sorting a dictionary
aDict = {15: "fifteen", 13: "thirteen", 0: "zero", 2: "two", 6: "six"}
# ascending order
dict(sorted(aDict.items()))
# descending order
dict(sorted(aDict.items(), reverse=True))
# region dictionary methods
"name" in d # membership test
d.keys() # all keys
d.values() # all values
d.items() # all key + value tuples
d.copy() # Return a shallow copy of the dictionary (top level)
d.clear() # remove all items
# This recursively updates the structure of the original dictionary-like object with the new entries in the second and third objects. This allows users to update with large, nested structures.
d.update() # Update current dict with dict1 and then dict2.
d.get("name") # fetch by key, if absent default (or none)
d.pop("name") # remove by key, if absent default (or error)
d.setdefault() # fetch by key, if absent set default (or none)
d.popitem() # remove/return any (key, value) pair
len(d) # number of stored entries
# endregion
# endregion
# region sets
"""
set vs dictionary
A set in python is a collection of items just like Lists and Tuples.
A dictionary in python is a collections of key-value pairs of item. For each entry, there are two items: a key and a value.
Dictionaries are unordered sets.
The main difference is that items in dictionaries are accessed via keys and not via their position.
The values of a dictionary can be any Python data type.
A set is a collection which is unordered and un-indexed.
It does not hold duplicate values and is unordered. However, it is not immutable, unlike a tuple.
"""
aSet = set() # create an empty set
aSet.add(1.5)
# one good use case is sets can be used to filter duplicates out of other collections
aList = [1, 2, 1, 3, 2, 4, 5, 1, 1]
# converting to set removes the duplicates as sets do not support duplicates. this does un-order the contents though.
set(aList)
L = list(set(aList)) # back to a list
# sets can be used to isolate differences in lists, strings, and other objects
list1 = [1, 3, 5, 7]
list2 = [1, 2, 3, 4, 5, 6]
set(list1) - set(list2)
string1 = "acString"
string2 = "abString"
set(string1) - set(string2)
# endregion
# region ranges
# sequence representing an arithmetic progression of integers
range(5) # stop
range(5, 10) # start stop
list(range(5, 10)) # starts at 5 because 2 arguments provided
list(range(0, 10, 2)) # start stop step
# can be used in loop counters - note it starts at zero because only 1 value supplied
for i in range(5):
print(i)
# endregion
# region loops
"""
break - jumps out of the loop
continue - jumps to the next iteration of the loop
pass - does nothing
Loop else block - executed when the loop is finished
"""
# region for loop
d = {"a": 1, "b": 2, "c": 3}
ks = list(d.keys())
# ks.sort()
for key in sorted(ks):
print(key, "=>", d[key])
for n in ["abc", "def"]:
print("String:", n)
# iterating over a string
for c in "spam":
print(c.upper())
# looping through a range
for i in range(1, 11):
print("*" * i)
# break out of a loop
for i in range(0, 10):
if i == 8:
print("In IF: ", i)
break
print(i)
# looping through an unknown range
list = [1, 3, 5, 7, 9]
# loop through a dictionary
D = {"a": 1, "b": 2, "c": 3}
for key in D:
print(key, "=>", D[key])
# getting length of list
length = len(list)
# Iterating the index
# same as 'for i in range(len(list))'
for i in range(length):
print(list[i])
# using an enumerate to loop through an array and find positions
t = [6, 372, 8862, 148800, 2096886]
for p in enumerate(t):
print(p)
# with tuple unpack
for i, v in enumerate(t):
print(f" i= {i}, v = {v}")
# read a file line by line and capitalize each line
filePath = r"C:\Test\script2.py"
for line in open(filePath, "r"):
print(line.upper(), end="")
# endregion
# region while loop
x = 4
while x > 0:
print("whoa!" * x)
x -= 1
while True:
userInput = input("Enter text:")
if userInput == "stop":
break
print(userInput.upper())
# slice off the first character in the loop
x = "jake"
while x:
print(x, end=" ")
x = x[1:]
# one way to do code counter loop
a = 0
b = 10
while a < b:
print(a, end=" ")
a += 1
# no native do while loop in python
def exitTest():
pass
while True:
# do something
if exitTest():
break
# using continue in while to find even numbers
x = 10
while x:
x -= 1
if x % 2 != 0:
continue
print(x, end=" ")
# ^^ this uses continue, which is not always a best practice
# try this instead:
x = 10
while x:
x -= 1
if x % 2 == 0:
print(x, end=" ")
# endregion
# region iterations
"""
iteration protocol - any object with a __next__ method to advance to a next result
next - built in function to advance to the next result using __next__
next(x) is the same as x.__next__()
"""
# in the below file read f will have a method __next__
# this is used to iterate over the file and readline() will take in the next line
filePath = r"C:\Test\script2.py"
f = open(filePath, "r")
f.readline()
f.readline()
f.readline()
f.readline()
f.close()
# we can prove this by running the __next__ method
f = open(filePath, "r")
f.__next__()
f.close()
# this could also be written this way:
f = open(filePath, "r")
next(f)
f.close()
# iter example
L = [1, 2, 3, 4, 5]
anIter = iter(L)
next(anIter) # could also be written as anIter.__next__()
# list comprehension
# this is the old school way of doing a list comprehension:
L = [1, 2, 3, 4, 5]
for i in range(len(L)):
L[i] += 10
L
# new way of doing this:
L = [1, 2, 3, 4, 5]
L = [i + 10 for i in L]
L
# list comprehensions can be applied to working with files
filePath = r"C:\Test\script2.py"
lines = [line.rstrip() for line in open(filePath, "r")]
# this can also be used to perform actions during iteration
capLines = [line.upper() for line in open(filePath, "r")]
# filter clauses can be added to list comprehensions
filePath = r"C:\Test\script2.py"
lines = [line.rstrip() for line in open(filePath, "r") if line[0] == "s"]
# pull out all lines from a file that start with i
zeResults = []
filePath = r"C:\Test\script2.py"
for line in open(filePath, "r"):
if line[0] == "i":
zeResults.append(line.rstrip())
zeResults
# list comprehension can be used to do this
filePath = r"C:\Test\script2.py"
lines = [line.rstrip() for line in open(filePath, "r") if line[0] == "i"]
# endregion
# endregion
# region virtual environments
# purpose of a virtual env where we can install packages for a specific project
# https://code.visualstudio.com/docs/python/environments#_global-virtual-and-conda-environments
# https://code.visualstudio.com/docs/python/python-tutorial#_install-and-use-packages
"""
Note: While it's possible to open a virtual environment folder as a workspace,
doing so is not recommended and might cause issues with using the Python extension.
"""
# region VENV
# pip install virtualenv
# common to create a venv folder inside the working project - common practice
# create a project environment
r"""
python -m venv project_env
project_env\Scripts\activate.bat
"""
# it is common to often use .venv with VSCode
r"""
python -m venv .venv
.venv\scripts\activate
"""
# If the activate command generates the message "Activate.ps1 is not digitally signed.
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
# deactivate an environment
# deactivate
# delete the virtual env
# just delete the dir
# endregion
# endregion
# region files
fileWork = open("test.txt", "w") # open new file in write output mode
fileWork.write("Hello\n")
fileWork.write("World!\n")
l = [123, "nemo", 1.23] # a list
fileWork.writelines(l) # write all line strings in a list into file
fileWork.close() # close to flush to disk
fileData = open("test.txt") # open file in read mode
text = fileData.read() # read entire file into single string
aList = fileData.readlines() # read entire file into list one ling strings (with \n)
print(text)
text.split()
"""
r - reading only - default mode
r+ - reading and writing - opens the file (if it exists) and places the pointer at the beginning of the file to read.
w - writing only
w+ - writing and reading - DELETES all the content of the file and keeps the point at the beginning of the file.
a - appending. creates file if it does not exist.
a+ - appending and reading.
"""
fileData.flush() # flush output buffer to disk without closing
# use r for opening file paths easily
path = r"C:\test\test.txt"
# scan a text file line by line using file iterator
for line in open(path):
print(line, end="")
# iterate over each character in a file using a while loop
file = open(path)
while True:
char = file.read(1)
if not char:
break
print(char)
# iterate over each character in a file using a for loop
for char in open(path).read():
print(char)
# change to a different directory
import os
os.chdir(r"C:\aws-pkgs\test")
os.getcwd() # current working directory
text = open("unicodedata.txt", encoding="utf-8").read()
# region FULL MANUAL - file conversion and conversion back from file
# an example that writes some info to disk and then reads it in with conversion steps
A, B, C = 1, 2, 3 # numbers
aString = "Yo" # string
aDict = {"a": 1, "b": 2} # dictionary
aList = [1, 2, 3] # list
aFile = open(path, "w") # open the file
aFile.write(aString + "\n") # string can be written without issue
aFile.write("%s,%s,%s\n" % (A, B, C)) # convert numbers to strings
aFile.write(
str(aList) + "$" + str(aDict) + "\n"
) # convert list and dict - separate with $
aFile.close()
# now read in file
chars = open(path).read() # raw string
chars
print(chars) # user-friendly
# convert back
fileInfo = open(path) # open file
line1 = fileInfo.readline() # reads first line
line1
line1.rstrip() # remove end of line
# line 1 is now our original string
line2 = fileInfo.readline() # read second line
line2
parts = line2.split(",") # split by comma
numbers = [int(P) for P in parts] # convert all in list at once
line3 = fileInfo.readline() # read 3rd line
line3
parts = line3.split("$")
objects = [eval(P) for P in parts]
# endregion
# region PICKLE - file conversion and conversion back
aDict = {"a": 1, "b": 2} # dictionary
aFile = open(path, "wb") # open the file - binary mode is required for pickle
import pickle
pickle.dump(aDict, aFile)
aFile.close()
# import and convert back
aFile = open(path, "rb") # open the file
theData = pickle.load(aFile) # already converted natively to dict
# endregion
# endregion
# region classes
class Worker:
def __init__(self, name, pay): # self is the new object.
# it has been initialized with name and pay
self.name = name
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay *= 1.0 + percent
w = Worker("Jake LastName", 100000)
w.giveRaise(0.10)
w.pay
class Human:
# this is a property/attribute
name = "homo sapiens"
height = 5
# 'def' is used to define a method/function of a class
def eat(self):
print(self.name, "is eating now")
jake = Human()
jake.name = "Jake"
jake.eat()
# explore the class and determine what properties and methods it has:
dir(jake) # list attributes of jake
vars(jake) # list attribute values of jake
type(jake) # get the type of jake
type(jake.eat) # get type of a method
print(type(Human.__dict__["eat"]))
print(type(Human.__dict__["height"]))
import inspect
inspect.getmembers(jake, predicate=inspect.ismethod) # get all methods from class
inspect.isfunction(type(jake.eat))
inspect.ismethod(type(jake.eat))
inspect.isclass(type(jake.eat))
for member in inspect.getmembers(jake, predicate=inspect.ismethod):
print(member)
for member in inspect.getmembers(jake, predicate=not inspect.ismethod):
print(member)
# endregion
# region decorators
# EXAMPLE1 - decorator stacking
def uppercase(func):
def wrapper():
original_result = func()
modified_result = original_result.upper()
return modified_result
return wrapper
def strong(func):
def wrapper():
return "<strong>" + func() + "</strong>"
return wrapper
def emphasis(func):
def wrapper():
return "<em>" + func() + "</em>"
return wrapper
# the function greet can now be decorated with these functions
@uppercase
@strong
@emphasis
def greet():
return "Hello!"
# EXAMPLE2 - trace function decorator with arguments
def trace(func):
def wrapper(*args, **kwargs):
print(f"TRACE: calling {func.__name__}() " f"with {args}, {kwargs}")
original_result = func(*args, **kwargs)
print(f"TRACE: {func.__name__}() " f"returned {original_result!r}")
return original_result
return wrapper
@trace
def say(name, line, line2):
return f"{name}: {line} and {line2}"
# endregion
# region math
4 == 4
4 > 3
4 + 4
4 - 4
4 * 4
4 / 4
5 // 3
import math
math.pi, math.e
math.sqrt(160) # square root
math.sin(90)
math.cos(90)
math.tan(30)
pow(2, 4) # exponent
2**4 # another way to do exponent
sum((1, 2, 3, 4))
min(3, 4, 5, 6), max(7, 8, 9, 10)
round(1.345)
round(1.345, 2)
math.floor(3.99)
math.ceil(3.14)
# logarithm of X with base 2
math.log(10000, 2)
# finding max/min
array = 1, 2, 3, 4, 5
max(array)
min(array)
import random
random.random()
random.randint(1, 10) # generate a random number
# endregion
# region time
import time
# returns float number, UNIX representation of time
time.time() # time() -> floating point number
# returns a time tuple
time.localtime() # local time
time.gmtime(time.time()) # time in UTC
# converting time tuple to string
time.asctime(time.localtime()) # asctime([tuple]) -> string
time.asctime(time.gmtime(time.time())) # time in UTC as string
time.time() # Returns current time in seconds since the Epoch as a floating point numbers
time.clock() # Returns CPU time since process start as a float
time.sleep() # Delay for a number of seconds passed to the function
time.gmtime() # Convert seconds since Epoch to UTC time tuple
time.localtime() # Converts seconds since Epoch to local time tuple
time.asctime() # Converts time tuple to a string
time.ctime() # Converts time in seconds to string
time.mktime() # Converts local time tuple to seconds since Epoch
time.strftime() # Converts time tuple to string according to a specific format
time.strptime() # Parses string to time tuple according to format specification
time.tzset() # To change the local timezone
from datetime import datetime
str(datetime.now())
str(datetime.today())
str(datetime.utcnow())
import datetime
# creating date objects
d = datetime.date(1991, 11, 21)
d.year
d.day
d.month
# creating datetime objects
dt = datetime.datetime(1991, 11, 21, 9, 5, 59)
dt.month
dt.second
dt.hour
dt.minute
from datetime import datetime
# parsing string and converting it to datetime object
datetime.strptime("05/01/91 11:29", "%d/%m/%y %H:%M")
# accessing properties of datetime object
d = datetime.strptime("05/01/91 11:29", "%d/%m/%y %H:%M")
d.year
d.hour
d.minute
# date time formatting
"{:%d-%b-%Y %I:%M:%S %p}".format(datetime.now())
"{:%d/%m/%Y %H:%M:%S}".format(datetime.now())
from datetime import datetime, timedelta
# timedelta and future/past dates
futuredate = datetime.now() + timedelta(days=365, hours=4, minutes=2)
pastdate = datetime.now() + timedelta(days=-365, hours=4, minutes=2)
"future date: {:%d-%b-%Y %I:%M:%S %p}".format(futuredate)
"past date: {:%d-%b-%Y %I:%M:%S %p}".format(pastdate)
# endregion
# region exceptions
while True:
userInput = input("Enter text:")
if userInput == "stop":
break
try:
aNum = int(userInput)
except:
print("NoGo!" * 8)
else:
print(aNum**2)
print("So Long!")
# raise an exception
# raise Exception("An error message")
# handle file not found exception
try:
f = open("nope.txt", "r")
print(f.read())
f.close()
except:
print("Error encountered opening file!")
# identifying the specific exception
# https://stackoverflow.com/questions/9823936/python-how-do-i-know-what-type-of-exception-occurred
try:
f = open("nope.txt", "r")
print(f.read())
f.close()
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print(message)
# endregion
# region logic
# relational operators
g = 20
g == 20 # true
g == 13 # false
g != 20 # false
g != 13 # true
g < 30 # true
g <= 20 # true
g > 30 # false
# general if statement
test1 = True
whoa = "HAM"
if test1:
whoa = "HAM-True"
elif test1 is False:
whoa = "HAM-False"
else:
whoa = "Turkey"
# if-else ternary expression
X = True
Y = "Y"
Z = "Z"
# standard if-else
if X:
A = Y
else:
A = Z
print(f"A is {A}!")
# ternary operator
A = Y if X else Z
print(f"A is {A}!")
# boolean operator evaluation
X = A or B or C or None
# endregion
# region functions
# alternative to pass. declare empty function with elipsis
def func1(): ...
def nameOfFunction(param):
# your code
return
def addition(num1, num2):
return num1 + num2
# you can provide a 'documentation string' or docstring as a first optional statement
def subtraction(num1, num2):
"""This function will subtract the second
number from the first and return the result"""
return num1 - num2
help(subtraction) # see the docstring
subtraction.__doc__ # see the docstring
def square(x):
"""[summary]
This function will square a number
Args:
x ([type]): [description]
Returns:
[type]: [description]
"""
return x * x
square(5)
# region lambda function
# anonymous function as they are not declared with def
doTheMulti = lambda num1, num2: num1 * num2
doTheMulti(2, 4)
# endregion
# endregion
# region packages
# install cookiecutter
# pipx install cookiecutter
# using pipx with cookiecutter
# pipx run cookiecutter cookiecutter-pypackage
# bootstrap the project initially
# pip install -r requirements_dev.txt
# basic package structure
"""
packaging_tutorial
├── LICENSE
├── README.md
├── example_pkg
│ └── __init__.py
├── setup.py
└── tests
"""
# more developed package structure
"""
package_name/
bin/
CHANGES.txt
docs/
LICENSE.txt
MANIFEST.in
README.txt
setup.py
package_name/
\__init__.py
\module1.py
\module2.py
\test/
__init__.py
test_module1.py
test_module2.py
CHANGES.txt: log of changes with each release
LICENSE.txt: text of the license you choose (do choose one!)
MANIFEST.in: description of what non-code files to include
README.txt: description of the package – should be written in ReST or Markdown (for PyPi):
setup.py: the script for building/installing package.
bin/: This is where you put top-level scripts
docs/: the documentation
package_name/: The main package – this is where the code goes.
test/: your unit tests.
"""
# basic setup file:
"""
import setuptools
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setuptools.setup(
name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
name is the distribution name of your package. This can be any name as long
as only contains letters, numbers, _ , and -. It also must not already be
taken on pypi.org. Be sure to update this with your username, as this ensures
you won’t try to upload a package with the same name as one which already exists
when you upload the package.
version is the package version see PEP 440 for more details on versions.
author and author_email are used to identify the author of the package.
description is a short, one-sentence summary of the package.
long_description is a detailed description of the package. This is shown on the
package detail page on the Python Package Index. In this case, the long
description is loaded from README.md which is a common pattern.
long_description_content_type tells the index what type of markup is used
for the long description. In this case, it’s Markdown.
url is the URL for the homepage of the project. For many projects, this will
just be a link to GitHub, GitLab, Bitbucket, or similar code hosting service.
packages is a list of all Python import packages that should be included in
the Distribution Package. Instead of listing each package manually, we can
use find_packages() to automatically discover all packages and subpackages.
In this case, the list of packages will be example_pkg as that’s the only
package present.
classifiers gives the index and pip some additional metadata about your package.
In this case, the package is only compatible with Python 3, is licensed under
the MIT license, and is OS-independent. You should always include at least which
version(s) of Python your package works on, which license your package is
available under, and which operating systems your package will work on.
For a complete list of classifiers, see https://pypi.org/classifiers/.
"""
# using cooking cutter to get a python package scaffold
"""
pip install -U cookiecutter
cookiecutter https://github.com/audreyfeldroy/cookiecutter-pypackage.git <-- base standard (unittest)
cookiecutter https://github.com/Nekroze/cookiecutter-pypackage.git <-- pytest support, strict flake8
"""
"""
https://packaging.python.org/guides/distributing-packages-using-setuptools
docs
authors.rst
conf.py
contributing.rst
history.rst
index.rst
installation.rst
make.bat
MakeFile
usage.rst
.gitignore
.travis.yml - travis-ci build file
AUTHORS.rst - Author info
CONTRIBUTING.rst - contributing guidelines
HISTORY.rst - CHANGELOG
LICENSE - project license
Makefile - the project BUILD file (like InvokeBuild) - https://pypi.org/project/py-make/
https://stackoverflow.com/questions/2532234/how-to-run-a-makefile-in-windows
MANIFEST.in - optional, can control what files are included/excluded in distribution
README.rst - reStructuredText (like Markdown) for displaying nicely on PyPI
requirements.txt - pip freeze
setup.cfg - setup.cfg is an ini file that contains option defaults for setup.py commands.
setup.py - setup.py is the build script for setuptools. It tells setuptools about
your package (such as the name and version) as well as which code files to include.
tox.ini - Tox is a tool that creates virtual environments, and installs the
configured dependencies for those environments, for the purpose of testing
a Python package. https://www.integralist.co.uk/posts/toxini/
tox aims to automate and standardize testing in Python. It is part of a
larger vision of easing the packaging, testing and release process of Python software.
https://tox.readthedocs.io/en/latest/
"""
# cookicutter package structure
"""
packaging_tutorial
├── packaging_tutorial.egg-info
│ ├── dependency_links.txt
│ ├── not-zip-safe
│ ├── PKG-INFO
│ ├── SOURCES.txt
│ └── top_level.txt
├── docs
│ ├── authors.rst
│ ├── conf.py
│ ├── contributing.rst
│ ├── history.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── make.bat
│ └── MakeFile
│ └── readme.rst
│ └── usage.rst
├── tests
│ └── __init__.py
│ └── test_example.py
├── __init__.py
├── .editorconfig
├── .gitignore
├── .travis.yml
├── AUTHORS.rst
├── packaging_tutorial.py
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MakeFile
├── MANIFEST.in
├── README.rst
├── requirements.txt
├── setup.cfg
├── setup.py
└── tox.ini
Makefile - the project BUILD file (like InvokeBuild) - https://pypi.org/project/py-make/
MANIFEST.in guides the packaging process by specifying which files are
essential for distribution, ensuring a well-defined and complete package for users.
requirements.txt - pip freeze
setup.cfg - setup.cfg is an ini file that contains option defaults for setup.py commands.
setup.py - setup.py is the build script for setuptools. It tells setuptools about
your package (such as the name and version) as well as which code files to include.
It instructs setuptools on how to package, distribute, and install your project as a distributable Python package.
tox.ini - Tox is a tool that creates virtual environments, and installs the
configured dependencies for those environments, for the purpose of testing
a Python package. https://www.integralist.co.uk/posts/toxini/
tox aims to automate and standardize testing in Python. It is part of a
larger vision of easing the packaging, testing and release process of Python software.
https://tox.readthedocs.io/en/latest/
"""
# endregion
# region pytest
"""
pytest file naming conventions:
test_<name>.py
<name>_test.py
pytest methods and functions naming conventions:
test_<name>
pytest class naming conventions:
Test<Name>
"""
"""
pytest result codes:
. - pass
F - Failures
E - Errors
s - Skipped
x - Expected failures
X - Unexpected successes
"""
# pytest --help
# searches for all tests in the package and runs them
# pytest
# search for tests in the package and run them with full diffs
# pytest -v
# run just one specific test in a test file:
# pytest -v tasks/test_four.py::test_asdict
# marking tests with @pytest.mark.unit
# pytest -m "unit"
# endregion
# region misc
# region processing shell command outputs
import os
dirOutput = os.popen("dir").read() # reads it all as a string
dirOutput = os.popen("dir")
dirOutput.read() # reads it all as a string
dirOutput.readline() # reads just the first line
dirOutput.readlines() # reads all lines with escape characters
os.popen("dir").readlines()[0] # read just the first line
os.popen("dir").read()[:50] # read the first 50 characters
# file line iterator loop
for line in os.popen("dir"):
print(line.rstrip())
# endregion
# endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment