Last active
March 6, 2024 06:05
-
-
Save techthoughts2/e6c13162b254c14622c19116eab08be9 to your computer and use it in GitHub Desktop.
python_learning
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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