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 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 help | |
help(help) # help on help | |
help("builtin") # list builtin methods | |
help("modules") # list builtin modules | |
help(print) | |
help(input) | |
help(open) | |
s = "astring" | |
help(s.replace) | |
# 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 | |
# 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 | |
# endregion | |
# region virtual environments | |
# py -3 -m venv .venv | |
# .venv\scripts\activate | |
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process | |
# python -m venv myProject/myVenv | |
# endregion | |
# region comments | |
# an inline comment | |
""" | |
multi | |
line | |
comments | |
""" | |
# 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. AVACADO is not avacado | |
_avacado | |
avacado | |
Avacado_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 | |
_avacado - single underscore. not imported by a from module import * statement | |
__avacado__ - two leading/trailing underscores - system defined names | |
__avacado - localized to enclosing classes | |
_ - retains result of the last expression | |
""" | |
# data type declation reference | |
s = "" # string | |
num = 0 # int | |
var = True # bool | |
fruits = [] # list | |
p = () # tuple | |
d = {} # dictionary | |
# a better way (prettier) to see globs of text | |
import pprint | |
yo = "AString" | |
pprint.pprint(dir(yo)) | |
# endregion | |
# region output/input | |
print("hello", "world") | |
print("hello" + " world") | |
print("Hello World!", end="") | |
print("My name is Jake") | |
# sep is a special varialble that introduces the space | |
print(1, 2, 3, 4) | |
print(1, 2, 3, 4, sep="**") | |
# out file | |
filename = open("c:/rs-pkgs/test.txt", "w") | |
print("Pretty cool!", file=filename) | |
filename.close() | |
# use stream redirection instead | |
# python script1.py > saveit.txt | |
# read file | |
filenameread = open("c:/rs-pkgs/test.txt", "r") | |
content = filenameread.read() | |
filenameread.close() | |
# 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 | |
# 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 dictonary | |
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/arguments | |
# 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" | |
# region string subsitutions | |
# 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 substituion | |
name = "Jake" | |
born = "UK" | |
string = f"""my name is {name} | |
and I was born in {born} | |
""" | |
print(string) | |
# using dictionaries for formatting | |
coor = {"latitude": "31.24E", "longitude": "-125.81N", "local": "TX"} | |
"Coordinates: {latitude}, {longitude}, {local}".format(**coor) | |
# 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 occurences 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("|") | |
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() | |
# endregion | |
# region lists | |
# most general sequence | |
# positinally ordered collections of arbitraliy 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] # this returns all items in list except the last one | |
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 | |
[avacado, pancakes] = ["Good", "YUM!"] # this creates 2 seperate 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 | |
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 | |
# endregion | |
# region dictionaries | |
# known as mappings - collections of other objects | |
# store by key instead of relative pposition - 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["Woofy"] = "Dog" | |
for key, value in peeps.items(): | |
"key: {0}, value: {1}".format(key, value) | |
# 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 unindexed. | |
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 duplictes. this does unorder 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 = "abcdefg" | |
string2 = "abdghij" | |
set(string1) - set(string2) | |
# endregion | |
# region loops | |
# 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) | |
for c in "spam": | |
print(c.upper()) | |
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] | |
# 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]) | |
# 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()) | |
# 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 | |
# 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 environmnet | |
# 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="") | |
# 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 - seperate 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 Morr", 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 arugments | |
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 | |
# general if statement | |
test1 = True | |
whoa = "HAM" | |
if test1: | |
whoa = "HAM-True" | |
elif test1 is False: | |
whoa = "HAM-False" | |
else: | |
whoa = "Turkey" | |
# endregion | |
# region functions | |
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 subract the second | |
number from the first and return the result""" | |
return num1 - num2 | |
help(subtraction) # see the docstring | |
subtraction.__doc__ # see the docstring | |
# 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 | |
# 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 | |
installtion.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/ | |
""" | |
# endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment